tpm_generated.cc revision a2ea1493759120ba0456825efe27806c491971b7
1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17// THIS CODE IS GENERATED - DO NOT MODIFY!
18
19#include "trunks/tpm_generated.h"
20
21#include <memory>
22#include <string>
23
24#include <base/bind.h>
25#include <base/callback.h>
26#include <base/logging.h>
27#include <base/macros.h>
28#include <base/stl_util.h>
29#include <base/strings/string_number_conversions.h>
30#include <base/sys_byteorder.h>
31#include <crypto/secure_hash.h>
32
33#include "trunks/authorization_delegate.h"
34#include "trunks/command_transceiver.h"
35#include "trunks/error_codes.h"
36
37namespace trunks {
38
39size_t GetNumberOfRequestHandles(TPM_CC command_code) {
40  switch (command_code) {
41    case TPM_CC_Startup:
42      return 0;
43    case TPM_CC_Shutdown:
44      return 0;
45    case TPM_CC_SelfTest:
46      return 0;
47    case TPM_CC_IncrementalSelfTest:
48      return 0;
49    case TPM_CC_GetTestResult:
50      return 0;
51    case TPM_CC_StartAuthSession:
52      return 2;
53    case TPM_CC_PolicyRestart:
54      return 1;
55    case TPM_CC_Create:
56      return 1;
57    case TPM_CC_Load:
58      return 1;
59    case TPM_CC_LoadExternal:
60      return 0;
61    case TPM_CC_ReadPublic:
62      return 1;
63    case TPM_CC_ActivateCredential:
64      return 2;
65    case TPM_CC_MakeCredential:
66      return 1;
67    case TPM_CC_Unseal:
68      return 1;
69    case TPM_CC_ObjectChangeAuth:
70      return 2;
71    case TPM_CC_Duplicate:
72      return 2;
73    case TPM_CC_Rewrap:
74      return 2;
75    case TPM_CC_Import:
76      return 1;
77    case TPM_CC_RSA_Encrypt:
78      return 1;
79    case TPM_CC_RSA_Decrypt:
80      return 1;
81    case TPM_CC_ECDH_KeyGen:
82      return 1;
83    case TPM_CC_ECDH_ZGen:
84      return 1;
85    case TPM_CC_ECC_Parameters:
86      return 0;
87    case TPM_CC_ZGen_2Phase:
88      return 1;
89    case TPM_CC_EncryptDecrypt:
90      return 1;
91    case TPM_CC_Hash:
92      return 0;
93    case TPM_CC_HMAC:
94      return 1;
95    case TPM_CC_GetRandom:
96      return 0;
97    case TPM_CC_StirRandom:
98      return 0;
99    case TPM_CC_HMAC_Start:
100      return 1;
101    case TPM_CC_HashSequenceStart:
102      return 0;
103    case TPM_CC_SequenceUpdate:
104      return 1;
105    case TPM_CC_SequenceComplete:
106      return 1;
107    case TPM_CC_EventSequenceComplete:
108      return 2;
109    case TPM_CC_Certify:
110      return 2;
111    case TPM_CC_CertifyCreation:
112      return 2;
113    case TPM_CC_Quote:
114      return 1;
115    case TPM_CC_GetSessionAuditDigest:
116      return 3;
117    case TPM_CC_GetCommandAuditDigest:
118      return 2;
119    case TPM_CC_GetTime:
120      return 2;
121    case TPM_CC_Commit:
122      return 1;
123    case TPM_CC_EC_Ephemeral:
124      return 0;
125    case TPM_CC_VerifySignature:
126      return 1;
127    case TPM_CC_Sign:
128      return 1;
129    case TPM_CC_SetCommandCodeAuditStatus:
130      return 1;
131    case TPM_CC_PCR_Extend:
132      return 1;
133    case TPM_CC_PCR_Event:
134      return 1;
135    case TPM_CC_PCR_Read:
136      return 0;
137    case TPM_CC_PCR_Allocate:
138      return 1;
139    case TPM_CC_PCR_SetAuthPolicy:
140      return 2;
141    case TPM_CC_PCR_SetAuthValue:
142      return 1;
143    case TPM_CC_PCR_Reset:
144      return 1;
145    case TPM_CC_PolicySigned:
146      return 2;
147    case TPM_CC_PolicySecret:
148      return 2;
149    case TPM_CC_PolicyTicket:
150      return 1;
151    case TPM_CC_PolicyOR:
152      return 1;
153    case TPM_CC_PolicyPCR:
154      return 1;
155    case TPM_CC_PolicyLocality:
156      return 1;
157    case TPM_CC_PolicyNV:
158      return 3;
159    case TPM_CC_PolicyCounterTimer:
160      return 1;
161    case TPM_CC_PolicyCommandCode:
162      return 1;
163    case TPM_CC_PolicyPhysicalPresence:
164      return 1;
165    case TPM_CC_PolicyCpHash:
166      return 1;
167    case TPM_CC_PolicyNameHash:
168      return 1;
169    case TPM_CC_PolicyDuplicationSelect:
170      return 1;
171    case TPM_CC_PolicyAuthorize:
172      return 1;
173    case TPM_CC_PolicyAuthValue:
174      return 1;
175    case TPM_CC_PolicyPassword:
176      return 1;
177    case TPM_CC_PolicyGetDigest:
178      return 1;
179    case TPM_CC_PolicyNvWritten:
180      return 1;
181    case TPM_CC_CreatePrimary:
182      return 1;
183    case TPM_CC_HierarchyControl:
184      return 1;
185    case TPM_CC_SetPrimaryPolicy:
186      return 1;
187    case TPM_CC_ChangePPS:
188      return 1;
189    case TPM_CC_ChangeEPS:
190      return 1;
191    case TPM_CC_Clear:
192      return 1;
193    case TPM_CC_ClearControl:
194      return 1;
195    case TPM_CC_HierarchyChangeAuth:
196      return 1;
197    case TPM_CC_DictionaryAttackLockReset:
198      return 1;
199    case TPM_CC_DictionaryAttackParameters:
200      return 1;
201    case TPM_CC_PP_Commands:
202      return 1;
203    case TPM_CC_SetAlgorithmSet:
204      return 1;
205    case TPM_CC_FieldUpgradeStart:
206      return 2;
207    case TPM_CC_FieldUpgradeData:
208      return 0;
209    case TPM_CC_FirmwareRead:
210      return 0;
211    case TPM_CC_ContextSave:
212      return 1;
213    case TPM_CC_ContextLoad:
214      return 0;
215    case TPM_CC_FlushContext:
216      return 0;
217    case TPM_CC_EvictControl:
218      return 2;
219    case TPM_CC_ReadClock:
220      return 0;
221    case TPM_CC_ClockSet:
222      return 1;
223    case TPM_CC_ClockRateAdjust:
224      return 1;
225    case TPM_CC_GetCapability:
226      return 0;
227    case TPM_CC_TestParms:
228      return 0;
229    case TPM_CC_NV_DefineSpace:
230      return 1;
231    case TPM_CC_NV_UndefineSpace:
232      return 2;
233    case TPM_CC_NV_UndefineSpaceSpecial:
234      return 2;
235    case TPM_CC_NV_ReadPublic:
236      return 1;
237    case TPM_CC_NV_Write:
238      return 2;
239    case TPM_CC_NV_Increment:
240      return 2;
241    case TPM_CC_NV_Extend:
242      return 2;
243    case TPM_CC_NV_SetBits:
244      return 2;
245    case TPM_CC_NV_WriteLock:
246      return 2;
247    case TPM_CC_NV_GlobalWriteLock:
248      return 1;
249    case TPM_CC_NV_Read:
250      return 2;
251    case TPM_CC_NV_ReadLock:
252      return 2;
253    case TPM_CC_NV_ChangeAuth:
254      return 1;
255    case TPM_CC_NV_Certify:
256      return 3;
257    default:
258      LOG(WARNING) << "Unknown command code: " << command_code;
259  }
260  return 0;
261}
262
263size_t GetNumberOfResponseHandles(TPM_CC command_code) {
264  switch (command_code) {
265    case TPM_CC_Startup:
266      return 0;
267    case TPM_CC_Shutdown:
268      return 0;
269    case TPM_CC_SelfTest:
270      return 0;
271    case TPM_CC_IncrementalSelfTest:
272      return 0;
273    case TPM_CC_GetTestResult:
274      return 0;
275    case TPM_CC_StartAuthSession:
276      return 1;
277    case TPM_CC_PolicyRestart:
278      return 0;
279    case TPM_CC_Create:
280      return 0;
281    case TPM_CC_Load:
282      return 1;
283    case TPM_CC_LoadExternal:
284      return 1;
285    case TPM_CC_ReadPublic:
286      return 0;
287    case TPM_CC_ActivateCredential:
288      return 0;
289    case TPM_CC_MakeCredential:
290      return 0;
291    case TPM_CC_Unseal:
292      return 0;
293    case TPM_CC_ObjectChangeAuth:
294      return 0;
295    case TPM_CC_Duplicate:
296      return 0;
297    case TPM_CC_Rewrap:
298      return 0;
299    case TPM_CC_Import:
300      return 0;
301    case TPM_CC_RSA_Encrypt:
302      return 0;
303    case TPM_CC_RSA_Decrypt:
304      return 0;
305    case TPM_CC_ECDH_KeyGen:
306      return 0;
307    case TPM_CC_ECDH_ZGen:
308      return 0;
309    case TPM_CC_ECC_Parameters:
310      return 0;
311    case TPM_CC_ZGen_2Phase:
312      return 0;
313    case TPM_CC_EncryptDecrypt:
314      return 0;
315    case TPM_CC_Hash:
316      return 0;
317    case TPM_CC_HMAC:
318      return 0;
319    case TPM_CC_GetRandom:
320      return 0;
321    case TPM_CC_StirRandom:
322      return 0;
323    case TPM_CC_HMAC_Start:
324      return 1;
325    case TPM_CC_HashSequenceStart:
326      return 1;
327    case TPM_CC_SequenceUpdate:
328      return 0;
329    case TPM_CC_SequenceComplete:
330      return 0;
331    case TPM_CC_EventSequenceComplete:
332      return 0;
333    case TPM_CC_Certify:
334      return 0;
335    case TPM_CC_CertifyCreation:
336      return 0;
337    case TPM_CC_Quote:
338      return 0;
339    case TPM_CC_GetSessionAuditDigest:
340      return 0;
341    case TPM_CC_GetCommandAuditDigest:
342      return 0;
343    case TPM_CC_GetTime:
344      return 0;
345    case TPM_CC_Commit:
346      return 0;
347    case TPM_CC_EC_Ephemeral:
348      return 0;
349    case TPM_CC_VerifySignature:
350      return 0;
351    case TPM_CC_Sign:
352      return 0;
353    case TPM_CC_SetCommandCodeAuditStatus:
354      return 0;
355    case TPM_CC_PCR_Extend:
356      return 0;
357    case TPM_CC_PCR_Event:
358      return 0;
359    case TPM_CC_PCR_Read:
360      return 0;
361    case TPM_CC_PCR_Allocate:
362      return 0;
363    case TPM_CC_PCR_SetAuthPolicy:
364      return 0;
365    case TPM_CC_PCR_SetAuthValue:
366      return 0;
367    case TPM_CC_PCR_Reset:
368      return 0;
369    case TPM_CC_PolicySigned:
370      return 0;
371    case TPM_CC_PolicySecret:
372      return 0;
373    case TPM_CC_PolicyTicket:
374      return 0;
375    case TPM_CC_PolicyOR:
376      return 0;
377    case TPM_CC_PolicyPCR:
378      return 0;
379    case TPM_CC_PolicyLocality:
380      return 0;
381    case TPM_CC_PolicyNV:
382      return 0;
383    case TPM_CC_PolicyCounterTimer:
384      return 0;
385    case TPM_CC_PolicyCommandCode:
386      return 0;
387    case TPM_CC_PolicyPhysicalPresence:
388      return 0;
389    case TPM_CC_PolicyCpHash:
390      return 0;
391    case TPM_CC_PolicyNameHash:
392      return 0;
393    case TPM_CC_PolicyDuplicationSelect:
394      return 0;
395    case TPM_CC_PolicyAuthorize:
396      return 0;
397    case TPM_CC_PolicyAuthValue:
398      return 0;
399    case TPM_CC_PolicyPassword:
400      return 0;
401    case TPM_CC_PolicyGetDigest:
402      return 0;
403    case TPM_CC_PolicyNvWritten:
404      return 0;
405    case TPM_CC_CreatePrimary:
406      return 1;
407    case TPM_CC_HierarchyControl:
408      return 0;
409    case TPM_CC_SetPrimaryPolicy:
410      return 0;
411    case TPM_CC_ChangePPS:
412      return 0;
413    case TPM_CC_ChangeEPS:
414      return 0;
415    case TPM_CC_Clear:
416      return 0;
417    case TPM_CC_ClearControl:
418      return 0;
419    case TPM_CC_HierarchyChangeAuth:
420      return 0;
421    case TPM_CC_DictionaryAttackLockReset:
422      return 0;
423    case TPM_CC_DictionaryAttackParameters:
424      return 0;
425    case TPM_CC_PP_Commands:
426      return 0;
427    case TPM_CC_SetAlgorithmSet:
428      return 0;
429    case TPM_CC_FieldUpgradeStart:
430      return 0;
431    case TPM_CC_FieldUpgradeData:
432      return 0;
433    case TPM_CC_FirmwareRead:
434      return 0;
435    case TPM_CC_ContextSave:
436      return 0;
437    case TPM_CC_ContextLoad:
438      return 1;
439    case TPM_CC_FlushContext:
440      return 0;
441    case TPM_CC_EvictControl:
442      return 0;
443    case TPM_CC_ReadClock:
444      return 0;
445    case TPM_CC_ClockSet:
446      return 0;
447    case TPM_CC_ClockRateAdjust:
448      return 0;
449    case TPM_CC_GetCapability:
450      return 0;
451    case TPM_CC_TestParms:
452      return 0;
453    case TPM_CC_NV_DefineSpace:
454      return 0;
455    case TPM_CC_NV_UndefineSpace:
456      return 0;
457    case TPM_CC_NV_UndefineSpaceSpecial:
458      return 0;
459    case TPM_CC_NV_ReadPublic:
460      return 0;
461    case TPM_CC_NV_Write:
462      return 0;
463    case TPM_CC_NV_Increment:
464      return 0;
465    case TPM_CC_NV_Extend:
466      return 0;
467    case TPM_CC_NV_SetBits:
468      return 0;
469    case TPM_CC_NV_WriteLock:
470      return 0;
471    case TPM_CC_NV_GlobalWriteLock:
472      return 0;
473    case TPM_CC_NV_Read:
474      return 0;
475    case TPM_CC_NV_ReadLock:
476      return 0;
477    case TPM_CC_NV_ChangeAuth:
478      return 0;
479    case TPM_CC_NV_Certify:
480      return 0;
481    default:
482      LOG(WARNING) << "Unknown command code: " << command_code;
483  }
484  return 0;
485}
486
487TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) {
488  VLOG(3) << __func__;
489  uint8_t value_net = value;
490  switch (sizeof(uint8_t)) {
491    case 2:
492      value_net = base::HostToNet16(value);
493      break;
494    case 4:
495      value_net = base::HostToNet32(value);
496      break;
497    case 8:
498      value_net = base::HostToNet64(value);
499      break;
500    default:
501      break;
502  }
503  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
504  buffer->append(value_bytes, sizeof(uint8_t));
505  return TPM_RC_SUCCESS;
506}
507
508TPM_RC Parse_uint8_t(std::string* buffer,
509                     uint8_t* value,
510                     std::string* value_bytes) {
511  VLOG(3) << __func__;
512  if (buffer->size() < sizeof(uint8_t))
513    return TPM_RC_INSUFFICIENT;
514  uint8_t value_net = 0;
515  memcpy(&value_net, buffer->data(), sizeof(uint8_t));
516  switch (sizeof(uint8_t)) {
517    case 2:
518      *value = base::NetToHost16(value_net);
519      break;
520    case 4:
521      *value = base::NetToHost32(value_net);
522      break;
523    case 8:
524      *value = base::NetToHost64(value_net);
525      break;
526    default:
527      *value = value_net;
528  }
529  if (value_bytes) {
530    value_bytes->append(buffer->substr(0, sizeof(uint8_t)));
531  }
532  buffer->erase(0, sizeof(uint8_t));
533  return TPM_RC_SUCCESS;
534}
535
536TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) {
537  VLOG(3) << __func__;
538  int8_t value_net = value;
539  switch (sizeof(int8_t)) {
540    case 2:
541      value_net = base::HostToNet16(value);
542      break;
543    case 4:
544      value_net = base::HostToNet32(value);
545      break;
546    case 8:
547      value_net = base::HostToNet64(value);
548      break;
549    default:
550      break;
551  }
552  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
553  buffer->append(value_bytes, sizeof(int8_t));
554  return TPM_RC_SUCCESS;
555}
556
557TPM_RC Parse_int8_t(std::string* buffer,
558                    int8_t* value,
559                    std::string* value_bytes) {
560  VLOG(3) << __func__;
561  if (buffer->size() < sizeof(int8_t))
562    return TPM_RC_INSUFFICIENT;
563  int8_t value_net = 0;
564  memcpy(&value_net, buffer->data(), sizeof(int8_t));
565  switch (sizeof(int8_t)) {
566    case 2:
567      *value = base::NetToHost16(value_net);
568      break;
569    case 4:
570      *value = base::NetToHost32(value_net);
571      break;
572    case 8:
573      *value = base::NetToHost64(value_net);
574      break;
575    default:
576      *value = value_net;
577  }
578  if (value_bytes) {
579    value_bytes->append(buffer->substr(0, sizeof(int8_t)));
580  }
581  buffer->erase(0, sizeof(int8_t));
582  return TPM_RC_SUCCESS;
583}
584
585TPM_RC Serialize_int(const int& value, std::string* buffer) {
586  VLOG(3) << __func__;
587  int value_net = value;
588  switch (sizeof(int)) {
589    case 2:
590      value_net = base::HostToNet16(value);
591      break;
592    case 4:
593      value_net = base::HostToNet32(value);
594      break;
595    case 8:
596      value_net = base::HostToNet64(value);
597      break;
598    default:
599      break;
600  }
601  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
602  buffer->append(value_bytes, sizeof(int));
603  return TPM_RC_SUCCESS;
604}
605
606TPM_RC Parse_int(std::string* buffer, int* value, std::string* value_bytes) {
607  VLOG(3) << __func__;
608  if (buffer->size() < sizeof(int))
609    return TPM_RC_INSUFFICIENT;
610  int value_net = 0;
611  memcpy(&value_net, buffer->data(), sizeof(int));
612  switch (sizeof(int)) {
613    case 2:
614      *value = base::NetToHost16(value_net);
615      break;
616    case 4:
617      *value = base::NetToHost32(value_net);
618      break;
619    case 8:
620      *value = base::NetToHost64(value_net);
621      break;
622    default:
623      *value = value_net;
624  }
625  if (value_bytes) {
626    value_bytes->append(buffer->substr(0, sizeof(int)));
627  }
628  buffer->erase(0, sizeof(int));
629  return TPM_RC_SUCCESS;
630}
631
632TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) {
633  VLOG(3) << __func__;
634  uint16_t value_net = value;
635  switch (sizeof(uint16_t)) {
636    case 2:
637      value_net = base::HostToNet16(value);
638      break;
639    case 4:
640      value_net = base::HostToNet32(value);
641      break;
642    case 8:
643      value_net = base::HostToNet64(value);
644      break;
645    default:
646      break;
647  }
648  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
649  buffer->append(value_bytes, sizeof(uint16_t));
650  return TPM_RC_SUCCESS;
651}
652
653TPM_RC Parse_uint16_t(std::string* buffer,
654                      uint16_t* value,
655                      std::string* value_bytes) {
656  VLOG(3) << __func__;
657  if (buffer->size() < sizeof(uint16_t))
658    return TPM_RC_INSUFFICIENT;
659  uint16_t value_net = 0;
660  memcpy(&value_net, buffer->data(), sizeof(uint16_t));
661  switch (sizeof(uint16_t)) {
662    case 2:
663      *value = base::NetToHost16(value_net);
664      break;
665    case 4:
666      *value = base::NetToHost32(value_net);
667      break;
668    case 8:
669      *value = base::NetToHost64(value_net);
670      break;
671    default:
672      *value = value_net;
673  }
674  if (value_bytes) {
675    value_bytes->append(buffer->substr(0, sizeof(uint16_t)));
676  }
677  buffer->erase(0, sizeof(uint16_t));
678  return TPM_RC_SUCCESS;
679}
680
681TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) {
682  VLOG(3) << __func__;
683  int16_t value_net = value;
684  switch (sizeof(int16_t)) {
685    case 2:
686      value_net = base::HostToNet16(value);
687      break;
688    case 4:
689      value_net = base::HostToNet32(value);
690      break;
691    case 8:
692      value_net = base::HostToNet64(value);
693      break;
694    default:
695      break;
696  }
697  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
698  buffer->append(value_bytes, sizeof(int16_t));
699  return TPM_RC_SUCCESS;
700}
701
702TPM_RC Parse_int16_t(std::string* buffer,
703                     int16_t* value,
704                     std::string* value_bytes) {
705  VLOG(3) << __func__;
706  if (buffer->size() < sizeof(int16_t))
707    return TPM_RC_INSUFFICIENT;
708  int16_t value_net = 0;
709  memcpy(&value_net, buffer->data(), sizeof(int16_t));
710  switch (sizeof(int16_t)) {
711    case 2:
712      *value = base::NetToHost16(value_net);
713      break;
714    case 4:
715      *value = base::NetToHost32(value_net);
716      break;
717    case 8:
718      *value = base::NetToHost64(value_net);
719      break;
720    default:
721      *value = value_net;
722  }
723  if (value_bytes) {
724    value_bytes->append(buffer->substr(0, sizeof(int16_t)));
725  }
726  buffer->erase(0, sizeof(int16_t));
727  return TPM_RC_SUCCESS;
728}
729
730TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) {
731  VLOG(3) << __func__;
732  uint32_t value_net = value;
733  switch (sizeof(uint32_t)) {
734    case 2:
735      value_net = base::HostToNet16(value);
736      break;
737    case 4:
738      value_net = base::HostToNet32(value);
739      break;
740    case 8:
741      value_net = base::HostToNet64(value);
742      break;
743    default:
744      break;
745  }
746  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
747  buffer->append(value_bytes, sizeof(uint32_t));
748  return TPM_RC_SUCCESS;
749}
750
751TPM_RC Parse_uint32_t(std::string* buffer,
752                      uint32_t* value,
753                      std::string* value_bytes) {
754  VLOG(3) << __func__;
755  if (buffer->size() < sizeof(uint32_t))
756    return TPM_RC_INSUFFICIENT;
757  uint32_t value_net = 0;
758  memcpy(&value_net, buffer->data(), sizeof(uint32_t));
759  switch (sizeof(uint32_t)) {
760    case 2:
761      *value = base::NetToHost16(value_net);
762      break;
763    case 4:
764      *value = base::NetToHost32(value_net);
765      break;
766    case 8:
767      *value = base::NetToHost64(value_net);
768      break;
769    default:
770      *value = value_net;
771  }
772  if (value_bytes) {
773    value_bytes->append(buffer->substr(0, sizeof(uint32_t)));
774  }
775  buffer->erase(0, sizeof(uint32_t));
776  return TPM_RC_SUCCESS;
777}
778
779TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) {
780  VLOG(3) << __func__;
781  int32_t value_net = value;
782  switch (sizeof(int32_t)) {
783    case 2:
784      value_net = base::HostToNet16(value);
785      break;
786    case 4:
787      value_net = base::HostToNet32(value);
788      break;
789    case 8:
790      value_net = base::HostToNet64(value);
791      break;
792    default:
793      break;
794  }
795  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
796  buffer->append(value_bytes, sizeof(int32_t));
797  return TPM_RC_SUCCESS;
798}
799
800TPM_RC Parse_int32_t(std::string* buffer,
801                     int32_t* value,
802                     std::string* value_bytes) {
803  VLOG(3) << __func__;
804  if (buffer->size() < sizeof(int32_t))
805    return TPM_RC_INSUFFICIENT;
806  int32_t value_net = 0;
807  memcpy(&value_net, buffer->data(), sizeof(int32_t));
808  switch (sizeof(int32_t)) {
809    case 2:
810      *value = base::NetToHost16(value_net);
811      break;
812    case 4:
813      *value = base::NetToHost32(value_net);
814      break;
815    case 8:
816      *value = base::NetToHost64(value_net);
817      break;
818    default:
819      *value = value_net;
820  }
821  if (value_bytes) {
822    value_bytes->append(buffer->substr(0, sizeof(int32_t)));
823  }
824  buffer->erase(0, sizeof(int32_t));
825  return TPM_RC_SUCCESS;
826}
827
828TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) {
829  VLOG(3) << __func__;
830  uint64_t value_net = value;
831  switch (sizeof(uint64_t)) {
832    case 2:
833      value_net = base::HostToNet16(value);
834      break;
835    case 4:
836      value_net = base::HostToNet32(value);
837      break;
838    case 8:
839      value_net = base::HostToNet64(value);
840      break;
841    default:
842      break;
843  }
844  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
845  buffer->append(value_bytes, sizeof(uint64_t));
846  return TPM_RC_SUCCESS;
847}
848
849TPM_RC Parse_uint64_t(std::string* buffer,
850                      uint64_t* value,
851                      std::string* value_bytes) {
852  VLOG(3) << __func__;
853  if (buffer->size() < sizeof(uint64_t))
854    return TPM_RC_INSUFFICIENT;
855  uint64_t value_net = 0;
856  memcpy(&value_net, buffer->data(), sizeof(uint64_t));
857  switch (sizeof(uint64_t)) {
858    case 2:
859      *value = base::NetToHost16(value_net);
860      break;
861    case 4:
862      *value = base::NetToHost32(value_net);
863      break;
864    case 8:
865      *value = base::NetToHost64(value_net);
866      break;
867    default:
868      *value = value_net;
869  }
870  if (value_bytes) {
871    value_bytes->append(buffer->substr(0, sizeof(uint64_t)));
872  }
873  buffer->erase(0, sizeof(uint64_t));
874  return TPM_RC_SUCCESS;
875}
876
877TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) {
878  VLOG(3) << __func__;
879  int64_t value_net = value;
880  switch (sizeof(int64_t)) {
881    case 2:
882      value_net = base::HostToNet16(value);
883      break;
884    case 4:
885      value_net = base::HostToNet32(value);
886      break;
887    case 8:
888      value_net = base::HostToNet64(value);
889      break;
890    default:
891      break;
892  }
893  const char* value_bytes = reinterpret_cast<const char*>(&value_net);
894  buffer->append(value_bytes, sizeof(int64_t));
895  return TPM_RC_SUCCESS;
896}
897
898TPM_RC Parse_int64_t(std::string* buffer,
899                     int64_t* value,
900                     std::string* value_bytes) {
901  VLOG(3) << __func__;
902  if (buffer->size() < sizeof(int64_t))
903    return TPM_RC_INSUFFICIENT;
904  int64_t value_net = 0;
905  memcpy(&value_net, buffer->data(), sizeof(int64_t));
906  switch (sizeof(int64_t)) {
907    case 2:
908      *value = base::NetToHost16(value_net);
909      break;
910    case 4:
911      *value = base::NetToHost32(value_net);
912      break;
913    case 8:
914      *value = base::NetToHost64(value_net);
915      break;
916    default:
917      *value = value_net;
918  }
919  if (value_bytes) {
920    value_bytes->append(buffer->substr(0, sizeof(int64_t)));
921  }
922  buffer->erase(0, sizeof(int64_t));
923  return TPM_RC_SUCCESS;
924}
925
926TPM_RC Serialize_UINT8(const UINT8& value, std::string* buffer) {
927  VLOG(3) << __func__;
928  return Serialize_uint8_t(value, buffer);
929}
930
931TPM_RC Parse_UINT8(std::string* buffer,
932                   UINT8* value,
933                   std::string* value_bytes) {
934  VLOG(3) << __func__;
935  return Parse_uint8_t(buffer, value, value_bytes);
936}
937
938TPM_RC Serialize_BYTE(const BYTE& value, std::string* buffer) {
939  VLOG(3) << __func__;
940  return Serialize_uint8_t(value, buffer);
941}
942
943TPM_RC Parse_BYTE(std::string* buffer, BYTE* value, std::string* value_bytes) {
944  VLOG(3) << __func__;
945  return Parse_uint8_t(buffer, value, value_bytes);
946}
947
948TPM_RC Serialize_INT8(const INT8& value, std::string* buffer) {
949  VLOG(3) << __func__;
950  return Serialize_int8_t(value, buffer);
951}
952
953TPM_RC Parse_INT8(std::string* buffer, INT8* value, std::string* value_bytes) {
954  VLOG(3) << __func__;
955  return Parse_int8_t(buffer, value, value_bytes);
956}
957
958TPM_RC Serialize_BOOL(const BOOL& value, std::string* buffer) {
959  VLOG(3) << __func__;
960  return Serialize_int(value, buffer);
961}
962
963TPM_RC Parse_BOOL(std::string* buffer, BOOL* value, std::string* value_bytes) {
964  VLOG(3) << __func__;
965  return Parse_int(buffer, value, value_bytes);
966}
967
968TPM_RC Serialize_UINT16(const UINT16& value, std::string* buffer) {
969  VLOG(3) << __func__;
970  return Serialize_uint16_t(value, buffer);
971}
972
973TPM_RC Parse_UINT16(std::string* buffer,
974                    UINT16* value,
975                    std::string* value_bytes) {
976  VLOG(3) << __func__;
977  return Parse_uint16_t(buffer, value, value_bytes);
978}
979
980TPM_RC Serialize_INT16(const INT16& value, std::string* buffer) {
981  VLOG(3) << __func__;
982  return Serialize_int16_t(value, buffer);
983}
984
985TPM_RC Parse_INT16(std::string* buffer,
986                   INT16* value,
987                   std::string* value_bytes) {
988  VLOG(3) << __func__;
989  return Parse_int16_t(buffer, value, value_bytes);
990}
991
992TPM_RC Serialize_UINT32(const UINT32& value, std::string* buffer) {
993  VLOG(3) << __func__;
994  return Serialize_uint32_t(value, buffer);
995}
996
997TPM_RC Parse_UINT32(std::string* buffer,
998                    UINT32* value,
999                    std::string* value_bytes) {
1000  VLOG(3) << __func__;
1001  return Parse_uint32_t(buffer, value, value_bytes);
1002}
1003
1004TPM_RC Serialize_INT32(const INT32& value, std::string* buffer) {
1005  VLOG(3) << __func__;
1006  return Serialize_int32_t(value, buffer);
1007}
1008
1009TPM_RC Parse_INT32(std::string* buffer,
1010                   INT32* value,
1011                   std::string* value_bytes) {
1012  VLOG(3) << __func__;
1013  return Parse_int32_t(buffer, value, value_bytes);
1014}
1015
1016TPM_RC Serialize_UINT64(const UINT64& value, std::string* buffer) {
1017  VLOG(3) << __func__;
1018  return Serialize_uint64_t(value, buffer);
1019}
1020
1021TPM_RC Parse_UINT64(std::string* buffer,
1022                    UINT64* value,
1023                    std::string* value_bytes) {
1024  VLOG(3) << __func__;
1025  return Parse_uint64_t(buffer, value, value_bytes);
1026}
1027
1028TPM_RC Serialize_INT64(const INT64& value, std::string* buffer) {
1029  VLOG(3) << __func__;
1030  return Serialize_int64_t(value, buffer);
1031}
1032
1033TPM_RC Parse_INT64(std::string* buffer,
1034                   INT64* value,
1035                   std::string* value_bytes) {
1036  VLOG(3) << __func__;
1037  return Parse_int64_t(buffer, value, value_bytes);
1038}
1039
1040TPM_RC Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID& value,
1041                                  std::string* buffer) {
1042  VLOG(3) << __func__;
1043  return Serialize_UINT32(value, buffer);
1044}
1045
1046TPM_RC Parse_TPM_ALGORITHM_ID(std::string* buffer,
1047                              TPM_ALGORITHM_ID* value,
1048                              std::string* value_bytes) {
1049  VLOG(3) << __func__;
1050  return Parse_UINT32(buffer, value, value_bytes);
1051}
1052
1053TPM_RC Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR& value,
1054                                        std::string* buffer) {
1055  VLOG(3) << __func__;
1056  return Serialize_UINT32(value, buffer);
1057}
1058
1059TPM_RC Parse_TPM_MODIFIER_INDICATOR(std::string* buffer,
1060                                    TPM_MODIFIER_INDICATOR* value,
1061                                    std::string* value_bytes) {
1062  VLOG(3) << __func__;
1063  return Parse_UINT32(buffer, value, value_bytes);
1064}
1065
1066TPM_RC Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE& value,
1067                                        std::string* buffer) {
1068  VLOG(3) << __func__;
1069  return Serialize_UINT32(value, buffer);
1070}
1071
1072TPM_RC Parse_TPM_AUTHORIZATION_SIZE(std::string* buffer,
1073                                    TPM_AUTHORIZATION_SIZE* value,
1074                                    std::string* value_bytes) {
1075  VLOG(3) << __func__;
1076  return Parse_UINT32(buffer, value, value_bytes);
1077}
1078
1079TPM_RC Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE& value,
1080                                    std::string* buffer) {
1081  VLOG(3) << __func__;
1082  return Serialize_UINT32(value, buffer);
1083}
1084
1085TPM_RC Parse_TPM_PARAMETER_SIZE(std::string* buffer,
1086                                TPM_PARAMETER_SIZE* value,
1087                                std::string* value_bytes) {
1088  VLOG(3) << __func__;
1089  return Parse_UINT32(buffer, value, value_bytes);
1090}
1091
1092TPM_RC Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE& value, std::string* buffer) {
1093  VLOG(3) << __func__;
1094  return Serialize_UINT16(value, buffer);
1095}
1096
1097TPM_RC Parse_TPM_KEY_SIZE(std::string* buffer,
1098                          TPM_KEY_SIZE* value,
1099                          std::string* value_bytes) {
1100  VLOG(3) << __func__;
1101  return Parse_UINT16(buffer, value, value_bytes);
1102}
1103
1104TPM_RC Serialize_TPM_KEY_BITS(const TPM_KEY_BITS& value, std::string* buffer) {
1105  VLOG(3) << __func__;
1106  return Serialize_UINT16(value, buffer);
1107}
1108
1109TPM_RC Parse_TPM_KEY_BITS(std::string* buffer,
1110                          TPM_KEY_BITS* value,
1111                          std::string* value_bytes) {
1112  VLOG(3) << __func__;
1113  return Parse_UINT16(buffer, value, value_bytes);
1114}
1115
1116TPM_RC Serialize_TPM_HANDLE(const TPM_HANDLE& value, std::string* buffer) {
1117  VLOG(3) << __func__;
1118  return Serialize_UINT32(value, buffer);
1119}
1120
1121TPM_RC Parse_TPM_HANDLE(std::string* buffer,
1122                        TPM_HANDLE* value,
1123                        std::string* value_bytes) {
1124  VLOG(3) << __func__;
1125  return Parse_UINT32(buffer, value, value_bytes);
1126}
1127
1128TPM_RC Serialize_TPM2B_DIGEST(const TPM2B_DIGEST& value, std::string* buffer) {
1129  TPM_RC result = TPM_RC_SUCCESS;
1130  VLOG(3) << __func__;
1131
1132  result = Serialize_UINT16(value.size, buffer);
1133  if (result) {
1134    return result;
1135  }
1136
1137  if (arraysize(value.buffer) < value.size) {
1138    return TPM_RC_INSUFFICIENT;
1139  }
1140  for (uint32_t i = 0; i < value.size; ++i) {
1141    result = Serialize_BYTE(value.buffer[i], buffer);
1142    if (result) {
1143      return result;
1144    }
1145  }
1146  return result;
1147}
1148
1149TPM_RC Parse_TPM2B_DIGEST(std::string* buffer,
1150                          TPM2B_DIGEST* value,
1151                          std::string* value_bytes) {
1152  TPM_RC result = TPM_RC_SUCCESS;
1153  VLOG(3) << __func__;
1154
1155  result = Parse_UINT16(buffer, &value->size, value_bytes);
1156  if (result) {
1157    return result;
1158  }
1159
1160  if (arraysize(value->buffer) < value->size) {
1161    return TPM_RC_INSUFFICIENT;
1162  }
1163  for (uint32_t i = 0; i < value->size; ++i) {
1164    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
1165    if (result) {
1166      return result;
1167    }
1168  }
1169  return result;
1170}
1171
1172TPM2B_DIGEST Make_TPM2B_DIGEST(const std::string& bytes) {
1173  TPM2B_DIGEST tpm2b;
1174  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
1175  memset(&tpm2b, 0, sizeof(TPM2B_DIGEST));
1176  tpm2b.size = bytes.size();
1177  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
1178  return tpm2b;
1179}
1180
1181std::string StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST& tpm2b) {
1182  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
1183  return std::string(char_buffer, tpm2b.size);
1184}
1185
1186TPM_RC Serialize_TPM2B_NONCE(const TPM2B_NONCE& value, std::string* buffer) {
1187  VLOG(3) << __func__;
1188  return Serialize_TPM2B_DIGEST(value, buffer);
1189}
1190
1191TPM_RC Parse_TPM2B_NONCE(std::string* buffer,
1192                         TPM2B_NONCE* value,
1193                         std::string* value_bytes) {
1194  VLOG(3) << __func__;
1195  return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1196}
1197
1198TPM_RC Serialize_TPM2B_AUTH(const TPM2B_AUTH& value, std::string* buffer) {
1199  VLOG(3) << __func__;
1200  return Serialize_TPM2B_DIGEST(value, buffer);
1201}
1202
1203TPM_RC Parse_TPM2B_AUTH(std::string* buffer,
1204                        TPM2B_AUTH* value,
1205                        std::string* value_bytes) {
1206  VLOG(3) << __func__;
1207  return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1208}
1209
1210TPM_RC Serialize_TPM2B_OPERAND(const TPM2B_OPERAND& value,
1211                               std::string* buffer) {
1212  VLOG(3) << __func__;
1213  return Serialize_TPM2B_DIGEST(value, buffer);
1214}
1215
1216TPM_RC Parse_TPM2B_OPERAND(std::string* buffer,
1217                           TPM2B_OPERAND* value,
1218                           std::string* value_bytes) {
1219  VLOG(3) << __func__;
1220  return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1221}
1222
1223TPM_RC Serialize_TPM_ALG_ID(const TPM_ALG_ID& value, std::string* buffer) {
1224  VLOG(3) << __func__;
1225  return Serialize_UINT16(value, buffer);
1226}
1227
1228TPM_RC Parse_TPM_ALG_ID(std::string* buffer,
1229                        TPM_ALG_ID* value,
1230                        std::string* value_bytes) {
1231  VLOG(3) << __func__;
1232  return Parse_UINT16(buffer, value, value_bytes);
1233}
1234
1235TPM_RC Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH& value,
1236                               std::string* buffer) {
1237  VLOG(3) << __func__;
1238  return Serialize_TPM_ALG_ID(value, buffer);
1239}
1240
1241TPM_RC Parse_TPMI_ALG_HASH(std::string* buffer,
1242                           TPMI_ALG_HASH* value,
1243                           std::string* value_bytes) {
1244  VLOG(3) << __func__;
1245  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1246}
1247
1248TPM_RC Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH& value,
1249                                     std::string* buffer) {
1250  TPM_RC result = TPM_RC_SUCCESS;
1251  VLOG(3) << __func__;
1252
1253  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
1254  if (result) {
1255    return result;
1256  }
1257  return result;
1258}
1259
1260TPM_RC Parse_TPMS_SCHEME_SIGHASH(std::string* buffer,
1261                                 TPMS_SCHEME_SIGHASH* value,
1262                                 std::string* value_bytes) {
1263  TPM_RC result = TPM_RC_SUCCESS;
1264  VLOG(3) << __func__;
1265
1266  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
1267  if (result) {
1268    return result;
1269  }
1270  return result;
1271}
1272
1273TPM_RC Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC& value,
1274                                  std::string* buffer) {
1275  VLOG(3) << __func__;
1276  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1277}
1278
1279TPM_RC Parse_TPMS_SCHEME_HMAC(std::string* buffer,
1280                              TPMS_SCHEME_HMAC* value,
1281                              std::string* value_bytes) {
1282  VLOG(3) << __func__;
1283  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1284}
1285
1286TPM_RC Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA& value,
1287                                    std::string* buffer) {
1288  VLOG(3) << __func__;
1289  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1290}
1291
1292TPM_RC Parse_TPMS_SCHEME_RSASSA(std::string* buffer,
1293                                TPMS_SCHEME_RSASSA* value,
1294                                std::string* value_bytes) {
1295  VLOG(3) << __func__;
1296  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1297}
1298
1299TPM_RC Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS& value,
1300                                    std::string* buffer) {
1301  VLOG(3) << __func__;
1302  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1303}
1304
1305TPM_RC Parse_TPMS_SCHEME_RSAPSS(std::string* buffer,
1306                                TPMS_SCHEME_RSAPSS* value,
1307                                std::string* value_bytes) {
1308  VLOG(3) << __func__;
1309  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1310}
1311
1312TPM_RC Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA& value,
1313                                   std::string* buffer) {
1314  VLOG(3) << __func__;
1315  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1316}
1317
1318TPM_RC Parse_TPMS_SCHEME_ECDSA(std::string* buffer,
1319                               TPMS_SCHEME_ECDSA* value,
1320                               std::string* value_bytes) {
1321  VLOG(3) << __func__;
1322  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1323}
1324
1325TPM_RC Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2& value,
1326                                 std::string* buffer) {
1327  VLOG(3) << __func__;
1328  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1329}
1330
1331TPM_RC Parse_TPMS_SCHEME_SM2(std::string* buffer,
1332                             TPMS_SCHEME_SM2* value,
1333                             std::string* value_bytes) {
1334  VLOG(3) << __func__;
1335  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1336}
1337
1338TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR& value,
1339                                       std::string* buffer) {
1340  VLOG(3) << __func__;
1341  return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1342}
1343
1344TPM_RC Parse_TPMS_SCHEME_ECSCHNORR(std::string* buffer,
1345                                   TPMS_SCHEME_ECSCHNORR* value,
1346                                   std::string* value_bytes) {
1347  VLOG(3) << __func__;
1348  return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1349}
1350
1351TPM_RC Serialize_TPMI_YES_NO(const TPMI_YES_NO& value, std::string* buffer) {
1352  VLOG(3) << __func__;
1353  return Serialize_BYTE(value, buffer);
1354}
1355
1356TPM_RC Parse_TPMI_YES_NO(std::string* buffer,
1357                         TPMI_YES_NO* value,
1358                         std::string* value_bytes) {
1359  VLOG(3) << __func__;
1360  return Parse_BYTE(buffer, value, value_bytes);
1361}
1362
1363TPM_RC Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT& value,
1364                                std::string* buffer) {
1365  VLOG(3) << __func__;
1366  return Serialize_TPM_HANDLE(value, buffer);
1367}
1368
1369TPM_RC Parse_TPMI_DH_OBJECT(std::string* buffer,
1370                            TPMI_DH_OBJECT* value,
1371                            std::string* value_bytes) {
1372  VLOG(3) << __func__;
1373  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1374}
1375
1376TPM_RC Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT& value,
1377                                    std::string* buffer) {
1378  VLOG(3) << __func__;
1379  return Serialize_TPM_HANDLE(value, buffer);
1380}
1381
1382TPM_RC Parse_TPMI_DH_PERSISTENT(std::string* buffer,
1383                                TPMI_DH_PERSISTENT* value,
1384                                std::string* value_bytes) {
1385  VLOG(3) << __func__;
1386  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1387}
1388
1389TPM_RC Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY& value,
1390                                std::string* buffer) {
1391  VLOG(3) << __func__;
1392  return Serialize_TPM_HANDLE(value, buffer);
1393}
1394
1395TPM_RC Parse_TPMI_DH_ENTITY(std::string* buffer,
1396                            TPMI_DH_ENTITY* value,
1397                            std::string* value_bytes) {
1398  VLOG(3) << __func__;
1399  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1400}
1401
1402TPM_RC Serialize_TPMI_DH_PCR(const TPMI_DH_PCR& value, std::string* buffer) {
1403  VLOG(3) << __func__;
1404  return Serialize_TPM_HANDLE(value, buffer);
1405}
1406
1407TPM_RC Parse_TPMI_DH_PCR(std::string* buffer,
1408                         TPMI_DH_PCR* value,
1409                         std::string* value_bytes) {
1410  VLOG(3) << __func__;
1411  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1412}
1413
1414TPM_RC Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION& value,
1415                                      std::string* buffer) {
1416  VLOG(3) << __func__;
1417  return Serialize_TPM_HANDLE(value, buffer);
1418}
1419
1420TPM_RC Parse_TPMI_SH_AUTH_SESSION(std::string* buffer,
1421                                  TPMI_SH_AUTH_SESSION* value,
1422                                  std::string* value_bytes) {
1423  VLOG(3) << __func__;
1424  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1425}
1426
1427TPM_RC Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC& value, std::string* buffer) {
1428  VLOG(3) << __func__;
1429  return Serialize_TPM_HANDLE(value, buffer);
1430}
1431
1432TPM_RC Parse_TPMI_SH_HMAC(std::string* buffer,
1433                          TPMI_SH_HMAC* value,
1434                          std::string* value_bytes) {
1435  VLOG(3) << __func__;
1436  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1437}
1438
1439TPM_RC Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY& value,
1440                                std::string* buffer) {
1441  VLOG(3) << __func__;
1442  return Serialize_TPM_HANDLE(value, buffer);
1443}
1444
1445TPM_RC Parse_TPMI_SH_POLICY(std::string* buffer,
1446                            TPMI_SH_POLICY* value,
1447                            std::string* value_bytes) {
1448  VLOG(3) << __func__;
1449  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1450}
1451
1452TPM_RC Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT& value,
1453                                 std::string* buffer) {
1454  VLOG(3) << __func__;
1455  return Serialize_TPM_HANDLE(value, buffer);
1456}
1457
1458TPM_RC Parse_TPMI_DH_CONTEXT(std::string* buffer,
1459                             TPMI_DH_CONTEXT* value,
1460                             std::string* value_bytes) {
1461  VLOG(3) << __func__;
1462  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1463}
1464
1465TPM_RC Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY& value,
1466                                   std::string* buffer) {
1467  VLOG(3) << __func__;
1468  return Serialize_TPM_HANDLE(value, buffer);
1469}
1470
1471TPM_RC Parse_TPMI_RH_HIERARCHY(std::string* buffer,
1472                               TPMI_RH_HIERARCHY* value,
1473                               std::string* value_bytes) {
1474  VLOG(3) << __func__;
1475  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1476}
1477
1478TPM_RC Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES& value,
1479                                 std::string* buffer) {
1480  VLOG(3) << __func__;
1481  return Serialize_TPM_HANDLE(value, buffer);
1482}
1483
1484TPM_RC Parse_TPMI_RH_ENABLES(std::string* buffer,
1485                             TPMI_RH_ENABLES* value,
1486                             std::string* value_bytes) {
1487  VLOG(3) << __func__;
1488  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1489}
1490
1491TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH& value,
1492                                        std::string* buffer) {
1493  VLOG(3) << __func__;
1494  return Serialize_TPM_HANDLE(value, buffer);
1495}
1496
1497TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH(std::string* buffer,
1498                                    TPMI_RH_HIERARCHY_AUTH* value,
1499                                    std::string* value_bytes) {
1500  VLOG(3) << __func__;
1501  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1502}
1503
1504TPM_RC Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM& value,
1505                                  std::string* buffer) {
1506  VLOG(3) << __func__;
1507  return Serialize_TPM_HANDLE(value, buffer);
1508}
1509
1510TPM_RC Parse_TPMI_RH_PLATFORM(std::string* buffer,
1511                              TPMI_RH_PLATFORM* value,
1512                              std::string* value_bytes) {
1513  VLOG(3) << __func__;
1514  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1515}
1516
1517TPM_RC Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER& value,
1518                               std::string* buffer) {
1519  VLOG(3) << __func__;
1520  return Serialize_TPM_HANDLE(value, buffer);
1521}
1522
1523TPM_RC Parse_TPMI_RH_OWNER(std::string* buffer,
1524                           TPMI_RH_OWNER* value,
1525                           std::string* value_bytes) {
1526  VLOG(3) << __func__;
1527  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1528}
1529
1530TPM_RC Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT& value,
1531                                     std::string* buffer) {
1532  VLOG(3) << __func__;
1533  return Serialize_TPM_HANDLE(value, buffer);
1534}
1535
1536TPM_RC Parse_TPMI_RH_ENDORSEMENT(std::string* buffer,
1537                                 TPMI_RH_ENDORSEMENT* value,
1538                                 std::string* value_bytes) {
1539  VLOG(3) << __func__;
1540  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1541}
1542
1543TPM_RC Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION& value,
1544                                   std::string* buffer) {
1545  VLOG(3) << __func__;
1546  return Serialize_TPM_HANDLE(value, buffer);
1547}
1548
1549TPM_RC Parse_TPMI_RH_PROVISION(std::string* buffer,
1550                               TPMI_RH_PROVISION* value,
1551                               std::string* value_bytes) {
1552  VLOG(3) << __func__;
1553  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1554}
1555
1556TPM_RC Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR& value,
1557                               std::string* buffer) {
1558  VLOG(3) << __func__;
1559  return Serialize_TPM_HANDLE(value, buffer);
1560}
1561
1562TPM_RC Parse_TPMI_RH_CLEAR(std::string* buffer,
1563                           TPMI_RH_CLEAR* value,
1564                           std::string* value_bytes) {
1565  VLOG(3) << __func__;
1566  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1567}
1568
1569TPM_RC Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH& value,
1570                                 std::string* buffer) {
1571  VLOG(3) << __func__;
1572  return Serialize_TPM_HANDLE(value, buffer);
1573}
1574
1575TPM_RC Parse_TPMI_RH_NV_AUTH(std::string* buffer,
1576                             TPMI_RH_NV_AUTH* value,
1577                             std::string* value_bytes) {
1578  VLOG(3) << __func__;
1579  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1580}
1581
1582TPM_RC Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT& value,
1583                                 std::string* buffer) {
1584  VLOG(3) << __func__;
1585  return Serialize_TPM_HANDLE(value, buffer);
1586}
1587
1588TPM_RC Parse_TPMI_RH_LOCKOUT(std::string* buffer,
1589                             TPMI_RH_LOCKOUT* value,
1590                             std::string* value_bytes) {
1591  VLOG(3) << __func__;
1592  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1593}
1594
1595TPM_RC Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX& value,
1596                                  std::string* buffer) {
1597  VLOG(3) << __func__;
1598  return Serialize_TPM_HANDLE(value, buffer);
1599}
1600
1601TPM_RC Parse_TPMI_RH_NV_INDEX(std::string* buffer,
1602                              TPMI_RH_NV_INDEX* value,
1603                              std::string* value_bytes) {
1604  VLOG(3) << __func__;
1605  return Parse_TPM_HANDLE(buffer, value, value_bytes);
1606}
1607
1608TPM_RC Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM& value,
1609                               std::string* buffer) {
1610  VLOG(3) << __func__;
1611  return Serialize_TPM_ALG_ID(value, buffer);
1612}
1613
1614TPM_RC Parse_TPMI_ALG_ASYM(std::string* buffer,
1615                           TPMI_ALG_ASYM* value,
1616                           std::string* value_bytes) {
1617  VLOG(3) << __func__;
1618  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1619}
1620
1621TPM_RC Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM& value, std::string* buffer) {
1622  VLOG(3) << __func__;
1623  return Serialize_TPM_ALG_ID(value, buffer);
1624}
1625
1626TPM_RC Parse_TPMI_ALG_SYM(std::string* buffer,
1627                          TPMI_ALG_SYM* value,
1628                          std::string* value_bytes) {
1629  VLOG(3) << __func__;
1630  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1631}
1632
1633TPM_RC Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT& value,
1634                                     std::string* buffer) {
1635  VLOG(3) << __func__;
1636  return Serialize_TPM_ALG_ID(value, buffer);
1637}
1638
1639TPM_RC Parse_TPMI_ALG_SYM_OBJECT(std::string* buffer,
1640                                 TPMI_ALG_SYM_OBJECT* value,
1641                                 std::string* value_bytes) {
1642  VLOG(3) << __func__;
1643  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1644}
1645
1646TPM_RC Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE& value,
1647                                   std::string* buffer) {
1648  VLOG(3) << __func__;
1649  return Serialize_TPM_ALG_ID(value, buffer);
1650}
1651
1652TPM_RC Parse_TPMI_ALG_SYM_MODE(std::string* buffer,
1653                               TPMI_ALG_SYM_MODE* value,
1654                               std::string* value_bytes) {
1655  VLOG(3) << __func__;
1656  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1657}
1658
1659TPM_RC Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF& value, std::string* buffer) {
1660  VLOG(3) << __func__;
1661  return Serialize_TPM_ALG_ID(value, buffer);
1662}
1663
1664TPM_RC Parse_TPMI_ALG_KDF(std::string* buffer,
1665                          TPMI_ALG_KDF* value,
1666                          std::string* value_bytes) {
1667  VLOG(3) << __func__;
1668  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1669}
1670
1671TPM_RC Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME& value,
1672                                     std::string* buffer) {
1673  VLOG(3) << __func__;
1674  return Serialize_TPM_ALG_ID(value, buffer);
1675}
1676
1677TPM_RC Parse_TPMI_ALG_SIG_SCHEME(std::string* buffer,
1678                                 TPMI_ALG_SIG_SCHEME* value,
1679                                 std::string* value_bytes) {
1680  VLOG(3) << __func__;
1681  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1682}
1683
1684TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE& value,
1685                                       std::string* buffer) {
1686  VLOG(3) << __func__;
1687  return Serialize_TPM_ALG_ID(value, buffer);
1688}
1689
1690TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE(std::string* buffer,
1691                                   TPMI_ECC_KEY_EXCHANGE* value,
1692                                   std::string* value_bytes) {
1693  VLOG(3) << __func__;
1694  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1695}
1696
1697TPM_RC Serialize_TPM_ST(const TPM_ST& value, std::string* buffer) {
1698  VLOG(3) << __func__;
1699  return Serialize_UINT16(value, buffer);
1700}
1701
1702TPM_RC Parse_TPM_ST(std::string* buffer,
1703                    TPM_ST* value,
1704                    std::string* value_bytes) {
1705  VLOG(3) << __func__;
1706  return Parse_UINT16(buffer, value, value_bytes);
1707}
1708
1709TPM_RC Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG& value,
1710                                     std::string* buffer) {
1711  VLOG(3) << __func__;
1712  return Serialize_TPM_ST(value, buffer);
1713}
1714
1715TPM_RC Parse_TPMI_ST_COMMAND_TAG(std::string* buffer,
1716                                 TPMI_ST_COMMAND_TAG* value,
1717                                 std::string* value_bytes) {
1718  VLOG(3) << __func__;
1719  return Parse_TPM_ST(buffer, value, value_bytes);
1720}
1721
1722TPM_RC Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST& value,
1723                                std::string* buffer) {
1724  VLOG(3) << __func__;
1725  return Serialize_TPM_ST(value, buffer);
1726}
1727
1728TPM_RC Parse_TPMI_ST_ATTEST(std::string* buffer,
1729                            TPMI_ST_ATTEST* value,
1730                            std::string* value_bytes) {
1731  VLOG(3) << __func__;
1732  return Parse_TPM_ST(buffer, value, value_bytes);
1733}
1734
1735TPM_RC Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS& value,
1736                                   std::string* buffer) {
1737  VLOG(3) << __func__;
1738  return Serialize_TPM_KEY_BITS(value, buffer);
1739}
1740
1741TPM_RC Parse_TPMI_AES_KEY_BITS(std::string* buffer,
1742                               TPMI_AES_KEY_BITS* value,
1743                               std::string* value_bytes) {
1744  VLOG(3) << __func__;
1745  return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1746}
1747
1748TPM_RC Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS& value,
1749                                   std::string* buffer) {
1750  VLOG(3) << __func__;
1751  return Serialize_TPM_KEY_BITS(value, buffer);
1752}
1753
1754TPM_RC Parse_TPMI_SM4_KEY_BITS(std::string* buffer,
1755                               TPMI_SM4_KEY_BITS* value,
1756                               std::string* value_bytes) {
1757  VLOG(3) << __func__;
1758  return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1759}
1760
1761TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME(
1762    const TPMI_ALG_KEYEDHASH_SCHEME& value,
1763    std::string* buffer) {
1764  VLOG(3) << __func__;
1765  return Serialize_TPM_ALG_ID(value, buffer);
1766}
1767
1768TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string* buffer,
1769                                       TPMI_ALG_KEYEDHASH_SCHEME* value,
1770                                       std::string* value_bytes) {
1771  VLOG(3) << __func__;
1772  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1773}
1774
1775TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME& value,
1776                                      std::string* buffer) {
1777  VLOG(3) << __func__;
1778  return Serialize_TPM_ALG_ID(value, buffer);
1779}
1780
1781TPM_RC Parse_TPMI_ALG_ASYM_SCHEME(std::string* buffer,
1782                                  TPMI_ALG_ASYM_SCHEME* value,
1783                                  std::string* value_bytes) {
1784  VLOG(3) << __func__;
1785  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1786}
1787
1788TPM_RC Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME& value,
1789                                     std::string* buffer) {
1790  VLOG(3) << __func__;
1791  return Serialize_TPM_ALG_ID(value, buffer);
1792}
1793
1794TPM_RC Parse_TPMI_ALG_RSA_SCHEME(std::string* buffer,
1795                                 TPMI_ALG_RSA_SCHEME* value,
1796                                 std::string* value_bytes) {
1797  VLOG(3) << __func__;
1798  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1799}
1800
1801TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT& value,
1802                                      std::string* buffer) {
1803  VLOG(3) << __func__;
1804  return Serialize_TPM_ALG_ID(value, buffer);
1805}
1806
1807TPM_RC Parse_TPMI_ALG_RSA_DECRYPT(std::string* buffer,
1808                                  TPMI_ALG_RSA_DECRYPT* value,
1809                                  std::string* value_bytes) {
1810  VLOG(3) << __func__;
1811  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1812}
1813
1814TPM_RC Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS& value,
1815                                   std::string* buffer) {
1816  VLOG(3) << __func__;
1817  return Serialize_TPM_KEY_BITS(value, buffer);
1818}
1819
1820TPM_RC Parse_TPMI_RSA_KEY_BITS(std::string* buffer,
1821                               TPMI_RSA_KEY_BITS* value,
1822                               std::string* value_bytes) {
1823  VLOG(3) << __func__;
1824  return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1825}
1826
1827TPM_RC Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME& value,
1828                                     std::string* buffer) {
1829  VLOG(3) << __func__;
1830  return Serialize_TPM_ALG_ID(value, buffer);
1831}
1832
1833TPM_RC Parse_TPMI_ALG_ECC_SCHEME(std::string* buffer,
1834                                 TPMI_ALG_ECC_SCHEME* value,
1835                                 std::string* value_bytes) {
1836  VLOG(3) << __func__;
1837  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1838}
1839
1840TPM_RC Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE& value,
1841                               std::string* buffer) {
1842  VLOG(3) << __func__;
1843  return Serialize_UINT16(value, buffer);
1844}
1845
1846TPM_RC Parse_TPM_ECC_CURVE(std::string* buffer,
1847                           TPM_ECC_CURVE* value,
1848                           std::string* value_bytes) {
1849  VLOG(3) << __func__;
1850  return Parse_UINT16(buffer, value, value_bytes);
1851}
1852
1853TPM_RC Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE& value,
1854                                std::string* buffer) {
1855  VLOG(3) << __func__;
1856  return Serialize_TPM_ECC_CURVE(value, buffer);
1857}
1858
1859TPM_RC Parse_TPMI_ECC_CURVE(std::string* buffer,
1860                            TPMI_ECC_CURVE* value,
1861                            std::string* value_bytes) {
1862  VLOG(3) << __func__;
1863  return Parse_TPM_ECC_CURVE(buffer, value, value_bytes);
1864}
1865
1866TPM_RC Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC& value,
1867                                 std::string* buffer) {
1868  VLOG(3) << __func__;
1869  return Serialize_TPM_ALG_ID(value, buffer);
1870}
1871
1872TPM_RC Parse_TPMI_ALG_PUBLIC(std::string* buffer,
1873                             TPMI_ALG_PUBLIC* value,
1874                             std::string* value_bytes) {
1875  VLOG(3) << __func__;
1876  return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1877}
1878
1879TPM_RC Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM& value,
1880                                std::string* buffer) {
1881  VLOG(3) << __func__;
1882  return Serialize_UINT32(value, buffer);
1883}
1884
1885TPM_RC Parse_TPMA_ALGORITHM(std::string* buffer,
1886                            TPMA_ALGORITHM* value,
1887                            std::string* value_bytes) {
1888  VLOG(3) << __func__;
1889  return Parse_UINT32(buffer, value, value_bytes);
1890}
1891
1892TPM_RC Serialize_TPMA_OBJECT(const TPMA_OBJECT& value, std::string* buffer) {
1893  VLOG(3) << __func__;
1894  return Serialize_UINT32(value, buffer);
1895}
1896
1897TPM_RC Parse_TPMA_OBJECT(std::string* buffer,
1898                         TPMA_OBJECT* value,
1899                         std::string* value_bytes) {
1900  VLOG(3) << __func__;
1901  return Parse_UINT32(buffer, value, value_bytes);
1902}
1903
1904TPM_RC Serialize_TPMA_SESSION(const TPMA_SESSION& value, std::string* buffer) {
1905  VLOG(3) << __func__;
1906  return Serialize_UINT8(value, buffer);
1907}
1908
1909TPM_RC Parse_TPMA_SESSION(std::string* buffer,
1910                          TPMA_SESSION* value,
1911                          std::string* value_bytes) {
1912  VLOG(3) << __func__;
1913  return Parse_UINT8(buffer, value, value_bytes);
1914}
1915
1916TPM_RC Serialize_TPMA_LOCALITY(const TPMA_LOCALITY& value,
1917                               std::string* buffer) {
1918  VLOG(3) << __func__;
1919  return Serialize_UINT8(value, buffer);
1920}
1921
1922TPM_RC Parse_TPMA_LOCALITY(std::string* buffer,
1923                           TPMA_LOCALITY* value,
1924                           std::string* value_bytes) {
1925  VLOG(3) << __func__;
1926  return Parse_UINT8(buffer, value, value_bytes);
1927}
1928
1929TPM_RC Serialize_TPMA_PERMANENT(const TPMA_PERMANENT& value,
1930                                std::string* buffer) {
1931  VLOG(3) << __func__;
1932  return Serialize_UINT32(value, buffer);
1933}
1934
1935TPM_RC Parse_TPMA_PERMANENT(std::string* buffer,
1936                            TPMA_PERMANENT* value,
1937                            std::string* value_bytes) {
1938  VLOG(3) << __func__;
1939  return Parse_UINT32(buffer, value, value_bytes);
1940}
1941
1942TPM_RC Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR& value,
1943                                    std::string* buffer) {
1944  VLOG(3) << __func__;
1945  return Serialize_UINT32(value, buffer);
1946}
1947
1948TPM_RC Parse_TPMA_STARTUP_CLEAR(std::string* buffer,
1949                                TPMA_STARTUP_CLEAR* value,
1950                                std::string* value_bytes) {
1951  VLOG(3) << __func__;
1952  return Parse_UINT32(buffer, value, value_bytes);
1953}
1954
1955TPM_RC Serialize_TPMA_MEMORY(const TPMA_MEMORY& value, std::string* buffer) {
1956  VLOG(3) << __func__;
1957  return Serialize_UINT32(value, buffer);
1958}
1959
1960TPM_RC Parse_TPMA_MEMORY(std::string* buffer,
1961                         TPMA_MEMORY* value,
1962                         std::string* value_bytes) {
1963  VLOG(3) << __func__;
1964  return Parse_UINT32(buffer, value, value_bytes);
1965}
1966
1967TPM_RC Serialize_TPM_CC(const TPM_CC& value, std::string* buffer) {
1968  VLOG(3) << __func__;
1969  return Serialize_UINT32(value, buffer);
1970}
1971
1972TPM_RC Parse_TPM_CC(std::string* buffer,
1973                    TPM_CC* value,
1974                    std::string* value_bytes) {
1975  VLOG(3) << __func__;
1976  return Parse_UINT32(buffer, value, value_bytes);
1977}
1978
1979TPM_RC Serialize_TPMA_CC(const TPMA_CC& value, std::string* buffer) {
1980  VLOG(3) << __func__;
1981  return Serialize_TPM_CC(value, buffer);
1982}
1983
1984TPM_RC Parse_TPMA_CC(std::string* buffer,
1985                     TPMA_CC* value,
1986                     std::string* value_bytes) {
1987  VLOG(3) << __func__;
1988  return Parse_TPM_CC(buffer, value, value_bytes);
1989}
1990
1991TPM_RC Serialize_TPM_NV_INDEX(const TPM_NV_INDEX& value, std::string* buffer) {
1992  VLOG(3) << __func__;
1993  return Serialize_UINT32(value, buffer);
1994}
1995
1996TPM_RC Parse_TPM_NV_INDEX(std::string* buffer,
1997                          TPM_NV_INDEX* value,
1998                          std::string* value_bytes) {
1999  VLOG(3) << __func__;
2000  return Parse_UINT32(buffer, value, value_bytes);
2001}
2002
2003TPM_RC Serialize_TPMA_NV(const TPMA_NV& value, std::string* buffer) {
2004  VLOG(3) << __func__;
2005  return Serialize_UINT32(value, buffer);
2006}
2007
2008TPM_RC Parse_TPMA_NV(std::string* buffer,
2009                     TPMA_NV* value,
2010                     std::string* value_bytes) {
2011  VLOG(3) << __func__;
2012  return Parse_UINT32(buffer, value, value_bytes);
2013}
2014
2015TPM_RC Serialize_TPM_SPEC(const TPM_SPEC& value, std::string* buffer) {
2016  VLOG(3) << __func__;
2017  return Serialize_UINT32(value, buffer);
2018}
2019
2020TPM_RC Parse_TPM_SPEC(std::string* buffer,
2021                      TPM_SPEC* value,
2022                      std::string* value_bytes) {
2023  VLOG(3) << __func__;
2024  return Parse_UINT32(buffer, value, value_bytes);
2025}
2026
2027TPM_RC Serialize_TPM_GENERATED(const TPM_GENERATED& value,
2028                               std::string* buffer) {
2029  VLOG(3) << __func__;
2030  return Serialize_UINT32(value, buffer);
2031}
2032
2033TPM_RC Parse_TPM_GENERATED(std::string* buffer,
2034                           TPM_GENERATED* value,
2035                           std::string* value_bytes) {
2036  VLOG(3) << __func__;
2037  return Parse_UINT32(buffer, value, value_bytes);
2038}
2039
2040TPM_RC Serialize_TPM_RC(const TPM_RC& value, std::string* buffer) {
2041  VLOG(3) << __func__;
2042  return Serialize_UINT32(value, buffer);
2043}
2044
2045TPM_RC Parse_TPM_RC(std::string* buffer,
2046                    TPM_RC* value,
2047                    std::string* value_bytes) {
2048  VLOG(3) << __func__;
2049  return Parse_UINT32(buffer, value, value_bytes);
2050}
2051
2052TPM_RC Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST& value,
2053                                  std::string* buffer) {
2054  VLOG(3) << __func__;
2055  return Serialize_INT8(value, buffer);
2056}
2057
2058TPM_RC Parse_TPM_CLOCK_ADJUST(std::string* buffer,
2059                              TPM_CLOCK_ADJUST* value,
2060                              std::string* value_bytes) {
2061  VLOG(3) << __func__;
2062  return Parse_INT8(buffer, value, value_bytes);
2063}
2064
2065TPM_RC Serialize_TPM_EO(const TPM_EO& value, std::string* buffer) {
2066  VLOG(3) << __func__;
2067  return Serialize_UINT16(value, buffer);
2068}
2069
2070TPM_RC Parse_TPM_EO(std::string* buffer,
2071                    TPM_EO* value,
2072                    std::string* value_bytes) {
2073  VLOG(3) << __func__;
2074  return Parse_UINT16(buffer, value, value_bytes);
2075}
2076
2077TPM_RC Serialize_TPM_SU(const TPM_SU& value, std::string* buffer) {
2078  VLOG(3) << __func__;
2079  return Serialize_UINT16(value, buffer);
2080}
2081
2082TPM_RC Parse_TPM_SU(std::string* buffer,
2083                    TPM_SU* value,
2084                    std::string* value_bytes) {
2085  VLOG(3) << __func__;
2086  return Parse_UINT16(buffer, value, value_bytes);
2087}
2088
2089TPM_RC Serialize_TPM_SE(const TPM_SE& value, std::string* buffer) {
2090  VLOG(3) << __func__;
2091  return Serialize_UINT8(value, buffer);
2092}
2093
2094TPM_RC Parse_TPM_SE(std::string* buffer,
2095                    TPM_SE* value,
2096                    std::string* value_bytes) {
2097  VLOG(3) << __func__;
2098  return Parse_UINT8(buffer, value, value_bytes);
2099}
2100
2101TPM_RC Serialize_TPM_CAP(const TPM_CAP& value, std::string* buffer) {
2102  VLOG(3) << __func__;
2103  return Serialize_UINT32(value, buffer);
2104}
2105
2106TPM_RC Parse_TPM_CAP(std::string* buffer,
2107                     TPM_CAP* value,
2108                     std::string* value_bytes) {
2109  VLOG(3) << __func__;
2110  return Parse_UINT32(buffer, value, value_bytes);
2111}
2112
2113TPM_RC Serialize_TPM_PT(const TPM_PT& value, std::string* buffer) {
2114  VLOG(3) << __func__;
2115  return Serialize_UINT32(value, buffer);
2116}
2117
2118TPM_RC Parse_TPM_PT(std::string* buffer,
2119                    TPM_PT* value,
2120                    std::string* value_bytes) {
2121  VLOG(3) << __func__;
2122  return Parse_UINT32(buffer, value, value_bytes);
2123}
2124
2125TPM_RC Serialize_TPM_PT_PCR(const TPM_PT_PCR& value, std::string* buffer) {
2126  VLOG(3) << __func__;
2127  return Serialize_UINT32(value, buffer);
2128}
2129
2130TPM_RC Parse_TPM_PT_PCR(std::string* buffer,
2131                        TPM_PT_PCR* value,
2132                        std::string* value_bytes) {
2133  VLOG(3) << __func__;
2134  return Parse_UINT32(buffer, value, value_bytes);
2135}
2136
2137TPM_RC Serialize_TPM_PS(const TPM_PS& value, std::string* buffer) {
2138  VLOG(3) << __func__;
2139  return Serialize_UINT32(value, buffer);
2140}
2141
2142TPM_RC Parse_TPM_PS(std::string* buffer,
2143                    TPM_PS* value,
2144                    std::string* value_bytes) {
2145  VLOG(3) << __func__;
2146  return Parse_UINT32(buffer, value, value_bytes);
2147}
2148
2149TPM_RC Serialize_TPM_HT(const TPM_HT& value, std::string* buffer) {
2150  VLOG(3) << __func__;
2151  return Serialize_UINT8(value, buffer);
2152}
2153
2154TPM_RC Parse_TPM_HT(std::string* buffer,
2155                    TPM_HT* value,
2156                    std::string* value_bytes) {
2157  VLOG(3) << __func__;
2158  return Parse_UINT8(buffer, value, value_bytes);
2159}
2160
2161TPM_RC Serialize_TPM_RH(const TPM_RH& value, std::string* buffer) {
2162  VLOG(3) << __func__;
2163  return Serialize_UINT32(value, buffer);
2164}
2165
2166TPM_RC Parse_TPM_RH(std::string* buffer,
2167                    TPM_RH* value,
2168                    std::string* value_bytes) {
2169  VLOG(3) << __func__;
2170  return Parse_UINT32(buffer, value, value_bytes);
2171}
2172
2173TPM_RC Serialize_TPM_HC(const TPM_HC& value, std::string* buffer) {
2174  VLOG(3) << __func__;
2175  return Serialize_TPM_HANDLE(value, buffer);
2176}
2177
2178TPM_RC Parse_TPM_HC(std::string* buffer,
2179                    TPM_HC* value,
2180                    std::string* value_bytes) {
2181  VLOG(3) << __func__;
2182  return Parse_TPM_HANDLE(buffer, value, value_bytes);
2183}
2184
2185TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION(
2186    const TPMS_ALGORITHM_DESCRIPTION& value,
2187    std::string* buffer) {
2188  TPM_RC result = TPM_RC_SUCCESS;
2189  VLOG(3) << __func__;
2190
2191  result = Serialize_TPM_ALG_ID(value.alg, buffer);
2192  if (result) {
2193    return result;
2194  }
2195
2196  result = Serialize_TPMA_ALGORITHM(value.attributes, buffer);
2197  if (result) {
2198    return result;
2199  }
2200  return result;
2201}
2202
2203TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION(std::string* buffer,
2204                                        TPMS_ALGORITHM_DESCRIPTION* value,
2205                                        std::string* value_bytes) {
2206  TPM_RC result = TPM_RC_SUCCESS;
2207  VLOG(3) << __func__;
2208
2209  result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
2210  if (result) {
2211    return result;
2212  }
2213
2214  result = Parse_TPMA_ALGORITHM(buffer, &value->attributes, value_bytes);
2215  if (result) {
2216    return result;
2217  }
2218  return result;
2219}
2220
2221TPM_RC Serialize_TPMU_HA(const TPMU_HA& value,
2222                         TPMI_ALG_HASH selector,
2223                         std::string* buffer) {
2224  TPM_RC result = TPM_RC_SUCCESS;
2225  VLOG(3) << __func__;
2226
2227  if (selector == TPM_ALG_SHA384) {
2228    if (arraysize(value.sha384) < SHA384_DIGEST_SIZE) {
2229      return TPM_RC_INSUFFICIENT;
2230    }
2231    for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2232      result = Serialize_BYTE(value.sha384[i], buffer);
2233      if (result) {
2234        return result;
2235      }
2236    }
2237  }
2238
2239  if (selector == TPM_ALG_SHA1) {
2240    if (arraysize(value.sha1) < SHA1_DIGEST_SIZE) {
2241      return TPM_RC_INSUFFICIENT;
2242    }
2243    for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2244      result = Serialize_BYTE(value.sha1[i], buffer);
2245      if (result) {
2246        return result;
2247      }
2248    }
2249  }
2250
2251  if (selector == TPM_ALG_SM3_256) {
2252    if (arraysize(value.sm3_256) < SM3_256_DIGEST_SIZE) {
2253      return TPM_RC_INSUFFICIENT;
2254    }
2255    for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2256      result = Serialize_BYTE(value.sm3_256[i], buffer);
2257      if (result) {
2258        return result;
2259      }
2260    }
2261  }
2262
2263  if (selector == TPM_ALG_NULL) {
2264    // Do nothing.
2265  }
2266
2267  if (selector == TPM_ALG_SHA256) {
2268    if (arraysize(value.sha256) < SHA256_DIGEST_SIZE) {
2269      return TPM_RC_INSUFFICIENT;
2270    }
2271    for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2272      result = Serialize_BYTE(value.sha256[i], buffer);
2273      if (result) {
2274        return result;
2275      }
2276    }
2277  }
2278
2279  if (selector == TPM_ALG_SHA512) {
2280    if (arraysize(value.sha512) < SHA512_DIGEST_SIZE) {
2281      return TPM_RC_INSUFFICIENT;
2282    }
2283    for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2284      result = Serialize_BYTE(value.sha512[i], buffer);
2285      if (result) {
2286        return result;
2287      }
2288    }
2289  }
2290  return result;
2291}
2292
2293TPM_RC Parse_TPMU_HA(std::string* buffer,
2294                     TPMI_ALG_HASH selector,
2295                     TPMU_HA* value,
2296                     std::string* value_bytes) {
2297  TPM_RC result = TPM_RC_SUCCESS;
2298  VLOG(3) << __func__;
2299
2300  if (selector == TPM_ALG_SHA384) {
2301    if (arraysize(value->sha384) < SHA384_DIGEST_SIZE) {
2302      return TPM_RC_INSUFFICIENT;
2303    }
2304    for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2305      result = Parse_BYTE(buffer, &value->sha384[i], value_bytes);
2306      if (result) {
2307        return result;
2308      }
2309    }
2310  }
2311
2312  if (selector == TPM_ALG_SHA1) {
2313    if (arraysize(value->sha1) < SHA1_DIGEST_SIZE) {
2314      return TPM_RC_INSUFFICIENT;
2315    }
2316    for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2317      result = Parse_BYTE(buffer, &value->sha1[i], value_bytes);
2318      if (result) {
2319        return result;
2320      }
2321    }
2322  }
2323
2324  if (selector == TPM_ALG_SM3_256) {
2325    if (arraysize(value->sm3_256) < SM3_256_DIGEST_SIZE) {
2326      return TPM_RC_INSUFFICIENT;
2327    }
2328    for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2329      result = Parse_BYTE(buffer, &value->sm3_256[i], value_bytes);
2330      if (result) {
2331        return result;
2332      }
2333    }
2334  }
2335
2336  if (selector == TPM_ALG_NULL) {
2337    // Do nothing.
2338  }
2339
2340  if (selector == TPM_ALG_SHA256) {
2341    if (arraysize(value->sha256) < SHA256_DIGEST_SIZE) {
2342      return TPM_RC_INSUFFICIENT;
2343    }
2344    for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2345      result = Parse_BYTE(buffer, &value->sha256[i], value_bytes);
2346      if (result) {
2347        return result;
2348      }
2349    }
2350  }
2351
2352  if (selector == TPM_ALG_SHA512) {
2353    if (arraysize(value->sha512) < SHA512_DIGEST_SIZE) {
2354      return TPM_RC_INSUFFICIENT;
2355    }
2356    for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2357      result = Parse_BYTE(buffer, &value->sha512[i], value_bytes);
2358      if (result) {
2359        return result;
2360      }
2361    }
2362  }
2363  return result;
2364}
2365
2366TPM_RC Serialize_TPMT_HA(const TPMT_HA& value, std::string* buffer) {
2367  TPM_RC result = TPM_RC_SUCCESS;
2368  VLOG(3) << __func__;
2369
2370  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
2371  if (result) {
2372    return result;
2373  }
2374
2375  result = Serialize_TPMU_HA(value.digest, value.hash_alg, buffer);
2376  if (result) {
2377    return result;
2378  }
2379  return result;
2380}
2381
2382TPM_RC Parse_TPMT_HA(std::string* buffer,
2383                     TPMT_HA* value,
2384                     std::string* value_bytes) {
2385  TPM_RC result = TPM_RC_SUCCESS;
2386  VLOG(3) << __func__;
2387
2388  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
2389  if (result) {
2390    return result;
2391  }
2392
2393  result = Parse_TPMU_HA(buffer, value->hash_alg, &value->digest, value_bytes);
2394  if (result) {
2395    return result;
2396  }
2397  return result;
2398}
2399
2400TPM_RC Serialize_TPM2B_DATA(const TPM2B_DATA& value, std::string* buffer) {
2401  TPM_RC result = TPM_RC_SUCCESS;
2402  VLOG(3) << __func__;
2403
2404  result = Serialize_UINT16(value.size, buffer);
2405  if (result) {
2406    return result;
2407  }
2408
2409  if (arraysize(value.buffer) < value.size) {
2410    return TPM_RC_INSUFFICIENT;
2411  }
2412  for (uint32_t i = 0; i < value.size; ++i) {
2413    result = Serialize_BYTE(value.buffer[i], buffer);
2414    if (result) {
2415      return result;
2416    }
2417  }
2418  return result;
2419}
2420
2421TPM_RC Parse_TPM2B_DATA(std::string* buffer,
2422                        TPM2B_DATA* value,
2423                        std::string* value_bytes) {
2424  TPM_RC result = TPM_RC_SUCCESS;
2425  VLOG(3) << __func__;
2426
2427  result = Parse_UINT16(buffer, &value->size, value_bytes);
2428  if (result) {
2429    return result;
2430  }
2431
2432  if (arraysize(value->buffer) < value->size) {
2433    return TPM_RC_INSUFFICIENT;
2434  }
2435  for (uint32_t i = 0; i < value->size; ++i) {
2436    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2437    if (result) {
2438      return result;
2439    }
2440  }
2441  return result;
2442}
2443
2444TPM2B_DATA Make_TPM2B_DATA(const std::string& bytes) {
2445  TPM2B_DATA tpm2b;
2446  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2447  memset(&tpm2b, 0, sizeof(TPM2B_DATA));
2448  tpm2b.size = bytes.size();
2449  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2450  return tpm2b;
2451}
2452
2453std::string StringFrom_TPM2B_DATA(const TPM2B_DATA& tpm2b) {
2454  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2455  return std::string(char_buffer, tpm2b.size);
2456}
2457
2458TPM_RC Serialize_TPM2B_EVENT(const TPM2B_EVENT& value, std::string* buffer) {
2459  TPM_RC result = TPM_RC_SUCCESS;
2460  VLOG(3) << __func__;
2461
2462  result = Serialize_UINT16(value.size, buffer);
2463  if (result) {
2464    return result;
2465  }
2466
2467  if (arraysize(value.buffer) < value.size) {
2468    return TPM_RC_INSUFFICIENT;
2469  }
2470  for (uint32_t i = 0; i < value.size; ++i) {
2471    result = Serialize_BYTE(value.buffer[i], buffer);
2472    if (result) {
2473      return result;
2474    }
2475  }
2476  return result;
2477}
2478
2479TPM_RC Parse_TPM2B_EVENT(std::string* buffer,
2480                         TPM2B_EVENT* value,
2481                         std::string* value_bytes) {
2482  TPM_RC result = TPM_RC_SUCCESS;
2483  VLOG(3) << __func__;
2484
2485  result = Parse_UINT16(buffer, &value->size, value_bytes);
2486  if (result) {
2487    return result;
2488  }
2489
2490  if (arraysize(value->buffer) < value->size) {
2491    return TPM_RC_INSUFFICIENT;
2492  }
2493  for (uint32_t i = 0; i < value->size; ++i) {
2494    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2495    if (result) {
2496      return result;
2497    }
2498  }
2499  return result;
2500}
2501
2502TPM2B_EVENT Make_TPM2B_EVENT(const std::string& bytes) {
2503  TPM2B_EVENT tpm2b;
2504  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2505  memset(&tpm2b, 0, sizeof(TPM2B_EVENT));
2506  tpm2b.size = bytes.size();
2507  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2508  return tpm2b;
2509}
2510
2511std::string StringFrom_TPM2B_EVENT(const TPM2B_EVENT& tpm2b) {
2512  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2513  return std::string(char_buffer, tpm2b.size);
2514}
2515
2516TPM_RC Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& value,
2517                                  std::string* buffer) {
2518  TPM_RC result = TPM_RC_SUCCESS;
2519  VLOG(3) << __func__;
2520
2521  result = Serialize_UINT16(value.size, buffer);
2522  if (result) {
2523    return result;
2524  }
2525
2526  if (arraysize(value.buffer) < value.size) {
2527    return TPM_RC_INSUFFICIENT;
2528  }
2529  for (uint32_t i = 0; i < value.size; ++i) {
2530    result = Serialize_BYTE(value.buffer[i], buffer);
2531    if (result) {
2532      return result;
2533    }
2534  }
2535  return result;
2536}
2537
2538TPM_RC Parse_TPM2B_MAX_BUFFER(std::string* buffer,
2539                              TPM2B_MAX_BUFFER* value,
2540                              std::string* value_bytes) {
2541  TPM_RC result = TPM_RC_SUCCESS;
2542  VLOG(3) << __func__;
2543
2544  result = Parse_UINT16(buffer, &value->size, value_bytes);
2545  if (result) {
2546    return result;
2547  }
2548
2549  if (arraysize(value->buffer) < value->size) {
2550    return TPM_RC_INSUFFICIENT;
2551  }
2552  for (uint32_t i = 0; i < value->size; ++i) {
2553    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2554    if (result) {
2555      return result;
2556    }
2557  }
2558  return result;
2559}
2560
2561TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER(const std::string& bytes) {
2562  TPM2B_MAX_BUFFER tpm2b;
2563  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2564  memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER));
2565  tpm2b.size = bytes.size();
2566  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2567  return tpm2b;
2568}
2569
2570std::string StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& tpm2b) {
2571  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2572  return std::string(char_buffer, tpm2b.size);
2573}
2574
2575TPM_RC Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& value,
2576                                     std::string* buffer) {
2577  TPM_RC result = TPM_RC_SUCCESS;
2578  VLOG(3) << __func__;
2579
2580  result = Serialize_UINT16(value.size, buffer);
2581  if (result) {
2582    return result;
2583  }
2584
2585  if (arraysize(value.buffer) < value.size) {
2586    return TPM_RC_INSUFFICIENT;
2587  }
2588  for (uint32_t i = 0; i < value.size; ++i) {
2589    result = Serialize_BYTE(value.buffer[i], buffer);
2590    if (result) {
2591      return result;
2592    }
2593  }
2594  return result;
2595}
2596
2597TPM_RC Parse_TPM2B_MAX_NV_BUFFER(std::string* buffer,
2598                                 TPM2B_MAX_NV_BUFFER* value,
2599                                 std::string* value_bytes) {
2600  TPM_RC result = TPM_RC_SUCCESS;
2601  VLOG(3) << __func__;
2602
2603  result = Parse_UINT16(buffer, &value->size, value_bytes);
2604  if (result) {
2605    return result;
2606  }
2607
2608  if (arraysize(value->buffer) < value->size) {
2609    return TPM_RC_INSUFFICIENT;
2610  }
2611  for (uint32_t i = 0; i < value->size; ++i) {
2612    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2613    if (result) {
2614      return result;
2615    }
2616  }
2617  return result;
2618}
2619
2620TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER(const std::string& bytes) {
2621  TPM2B_MAX_NV_BUFFER tpm2b;
2622  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2623  memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER));
2624  tpm2b.size = bytes.size();
2625  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2626  return tpm2b;
2627}
2628
2629std::string StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& tpm2b) {
2630  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2631  return std::string(char_buffer, tpm2b.size);
2632}
2633
2634TPM_RC Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& value,
2635                               std::string* buffer) {
2636  TPM_RC result = TPM_RC_SUCCESS;
2637  VLOG(3) << __func__;
2638
2639  result = Serialize_UINT16(value.size, buffer);
2640  if (result) {
2641    return result;
2642  }
2643
2644  if (arraysize(value.buffer) < value.size) {
2645    return TPM_RC_INSUFFICIENT;
2646  }
2647  for (uint32_t i = 0; i < value.size; ++i) {
2648    result = Serialize_BYTE(value.buffer[i], buffer);
2649    if (result) {
2650      return result;
2651    }
2652  }
2653  return result;
2654}
2655
2656TPM_RC Parse_TPM2B_TIMEOUT(std::string* buffer,
2657                           TPM2B_TIMEOUT* value,
2658                           std::string* value_bytes) {
2659  TPM_RC result = TPM_RC_SUCCESS;
2660  VLOG(3) << __func__;
2661
2662  result = Parse_UINT16(buffer, &value->size, value_bytes);
2663  if (result) {
2664    return result;
2665  }
2666
2667  if (arraysize(value->buffer) < value->size) {
2668    return TPM_RC_INSUFFICIENT;
2669  }
2670  for (uint32_t i = 0; i < value->size; ++i) {
2671    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2672    if (result) {
2673      return result;
2674    }
2675  }
2676  return result;
2677}
2678
2679TPM2B_TIMEOUT Make_TPM2B_TIMEOUT(const std::string& bytes) {
2680  TPM2B_TIMEOUT tpm2b;
2681  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2682  memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT));
2683  tpm2b.size = bytes.size();
2684  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2685  return tpm2b;
2686}
2687
2688std::string StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& tpm2b) {
2689  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2690  return std::string(char_buffer, tpm2b.size);
2691}
2692
2693TPM_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 (arraysize(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
2714TPM_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 (arraysize(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
2737TPM2B_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
2746std::string StringFrom_TPM2B_IV(const TPM2B_IV& tpm2b) {
2747  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2748  return std::string(char_buffer, tpm2b.size);
2749}
2750
2751TPM_RC Serialize_TPM2B_NAME(const TPM2B_NAME& value, std::string* buffer) {
2752  TPM_RC result = TPM_RC_SUCCESS;
2753  VLOG(3) << __func__;
2754
2755  result = Serialize_UINT16(value.size, buffer);
2756  if (result) {
2757    return result;
2758  }
2759
2760  if (arraysize(value.name) < value.size) {
2761    return TPM_RC_INSUFFICIENT;
2762  }
2763  for (uint32_t i = 0; i < value.size; ++i) {
2764    result = Serialize_BYTE(value.name[i], buffer);
2765    if (result) {
2766      return result;
2767    }
2768  }
2769  return result;
2770}
2771
2772TPM_RC Parse_TPM2B_NAME(std::string* buffer,
2773                        TPM2B_NAME* value,
2774                        std::string* value_bytes) {
2775  TPM_RC result = TPM_RC_SUCCESS;
2776  VLOG(3) << __func__;
2777
2778  result = Parse_UINT16(buffer, &value->size, value_bytes);
2779  if (result) {
2780    return result;
2781  }
2782
2783  if (arraysize(value->name) < value->size) {
2784    return TPM_RC_INSUFFICIENT;
2785  }
2786  for (uint32_t i = 0; i < value->size; ++i) {
2787    result = Parse_BYTE(buffer, &value->name[i], value_bytes);
2788    if (result) {
2789      return result;
2790    }
2791  }
2792  return result;
2793}
2794
2795TPM2B_NAME Make_TPM2B_NAME(const std::string& bytes) {
2796  TPM2B_NAME tpm2b;
2797  CHECK(bytes.size() <= sizeof(tpm2b.name));
2798  memset(&tpm2b, 0, sizeof(TPM2B_NAME));
2799  tpm2b.size = bytes.size();
2800  memcpy(tpm2b.name, bytes.data(), bytes.size());
2801  return tpm2b;
2802}
2803
2804std::string StringFrom_TPM2B_NAME(const TPM2B_NAME& tpm2b) {
2805  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.name);
2806  return std::string(char_buffer, tpm2b.size);
2807}
2808
2809TPM_RC Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT& value,
2810                                 std::string* buffer) {
2811  TPM_RC result = TPM_RC_SUCCESS;
2812  VLOG(3) << __func__;
2813
2814  result = Serialize_UINT8(value.sizeof_select, buffer);
2815  if (result) {
2816    return result;
2817  }
2818
2819  if (arraysize(value.pcr_select) < value.sizeof_select) {
2820    return TPM_RC_INSUFFICIENT;
2821  }
2822  for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2823    result = Serialize_BYTE(value.pcr_select[i], buffer);
2824    if (result) {
2825      return result;
2826    }
2827  }
2828  return result;
2829}
2830
2831TPM_RC Parse_TPMS_PCR_SELECT(std::string* buffer,
2832                             TPMS_PCR_SELECT* value,
2833                             std::string* value_bytes) {
2834  TPM_RC result = TPM_RC_SUCCESS;
2835  VLOG(3) << __func__;
2836
2837  result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2838  if (result) {
2839    return result;
2840  }
2841
2842  if (arraysize(value->pcr_select) < value->sizeof_select) {
2843    return TPM_RC_INSUFFICIENT;
2844  }
2845  for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2846    result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2847    if (result) {
2848      return result;
2849    }
2850  }
2851  return result;
2852}
2853
2854TPM_RC Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION& value,
2855                                    std::string* buffer) {
2856  TPM_RC result = TPM_RC_SUCCESS;
2857  VLOG(3) << __func__;
2858
2859  result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
2860  if (result) {
2861    return result;
2862  }
2863
2864  result = Serialize_UINT8(value.sizeof_select, buffer);
2865  if (result) {
2866    return result;
2867  }
2868
2869  if (arraysize(value.pcr_select) < value.sizeof_select) {
2870    return TPM_RC_INSUFFICIENT;
2871  }
2872  for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2873    result = Serialize_BYTE(value.pcr_select[i], buffer);
2874    if (result) {
2875      return result;
2876    }
2877  }
2878  return result;
2879}
2880
2881TPM_RC Parse_TPMS_PCR_SELECTION(std::string* buffer,
2882                                TPMS_PCR_SELECTION* value,
2883                                std::string* value_bytes) {
2884  TPM_RC result = TPM_RC_SUCCESS;
2885  VLOG(3) << __func__;
2886
2887  result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
2888  if (result) {
2889    return result;
2890  }
2891
2892  result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2893  if (result) {
2894    return result;
2895  }
2896
2897  if (arraysize(value->pcr_select) < value->sizeof_select) {
2898    return TPM_RC_INSUFFICIENT;
2899  }
2900  for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2901    result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2902    if (result) {
2903      return result;
2904    }
2905  }
2906  return result;
2907}
2908
2909TPM_RC Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION& value,
2910                                  std::string* buffer) {
2911  TPM_RC result = TPM_RC_SUCCESS;
2912  VLOG(3) << __func__;
2913
2914  result = Serialize_TPM_ST(value.tag, buffer);
2915  if (result) {
2916    return result;
2917  }
2918
2919  result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2920  if (result) {
2921    return result;
2922  }
2923
2924  result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2925  if (result) {
2926    return result;
2927  }
2928  return result;
2929}
2930
2931TPM_RC Parse_TPMT_TK_CREATION(std::string* buffer,
2932                              TPMT_TK_CREATION* value,
2933                              std::string* value_bytes) {
2934  TPM_RC result = TPM_RC_SUCCESS;
2935  VLOG(3) << __func__;
2936
2937  result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2938  if (result) {
2939    return result;
2940  }
2941
2942  result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2943  if (result) {
2944    return result;
2945  }
2946
2947  result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2948  if (result) {
2949    return result;
2950  }
2951  return result;
2952}
2953
2954TPM_RC Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED& value,
2955                                  std::string* buffer) {
2956  TPM_RC result = TPM_RC_SUCCESS;
2957  VLOG(3) << __func__;
2958
2959  result = Serialize_TPM_ST(value.tag, buffer);
2960  if (result) {
2961    return result;
2962  }
2963
2964  result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2965  if (result) {
2966    return result;
2967  }
2968
2969  result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2970  if (result) {
2971    return result;
2972  }
2973  return result;
2974}
2975
2976TPM_RC Parse_TPMT_TK_VERIFIED(std::string* buffer,
2977                              TPMT_TK_VERIFIED* value,
2978                              std::string* value_bytes) {
2979  TPM_RC result = TPM_RC_SUCCESS;
2980  VLOG(3) << __func__;
2981
2982  result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2983  if (result) {
2984    return result;
2985  }
2986
2987  result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2988  if (result) {
2989    return result;
2990  }
2991
2992  result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2993  if (result) {
2994    return result;
2995  }
2996  return result;
2997}
2998
2999TPM_RC Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH& value, std::string* buffer) {
3000  TPM_RC result = TPM_RC_SUCCESS;
3001  VLOG(3) << __func__;
3002
3003  result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3004  if (result) {
3005    return result;
3006  }
3007
3008  result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3009  if (result) {
3010    return result;
3011  }
3012  return result;
3013}
3014
3015TPM_RC Parse_TPMT_TK_AUTH(std::string* buffer,
3016                          TPMT_TK_AUTH* value,
3017                          std::string* value_bytes) {
3018  TPM_RC result = TPM_RC_SUCCESS;
3019  VLOG(3) << __func__;
3020
3021  result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3022  if (result) {
3023    return result;
3024  }
3025
3026  result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3027  if (result) {
3028    return result;
3029  }
3030  return result;
3031}
3032
3033TPM_RC Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK& value,
3034                                   std::string* buffer) {
3035  TPM_RC result = TPM_RC_SUCCESS;
3036  VLOG(3) << __func__;
3037
3038  result = Serialize_TPM_ST(value.tag, buffer);
3039  if (result) {
3040    return result;
3041  }
3042
3043  result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3044  if (result) {
3045    return result;
3046  }
3047
3048  result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3049  if (result) {
3050    return result;
3051  }
3052  return result;
3053}
3054
3055TPM_RC Parse_TPMT_TK_HASHCHECK(std::string* buffer,
3056                               TPMT_TK_HASHCHECK* value,
3057                               std::string* value_bytes) {
3058  TPM_RC result = TPM_RC_SUCCESS;
3059  VLOG(3) << __func__;
3060
3061  result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3062  if (result) {
3063    return result;
3064  }
3065
3066  result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3067  if (result) {
3068    return result;
3069  }
3070
3071  result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3072  if (result) {
3073    return result;
3074  }
3075  return result;
3076}
3077
3078TPM_RC Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY& value,
3079                                   std::string* buffer) {
3080  TPM_RC result = TPM_RC_SUCCESS;
3081  VLOG(3) << __func__;
3082
3083  result = Serialize_TPM_ALG_ID(value.alg, buffer);
3084  if (result) {
3085    return result;
3086  }
3087
3088  result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer);
3089  if (result) {
3090    return result;
3091  }
3092  return result;
3093}
3094
3095TPM_RC Parse_TPMS_ALG_PROPERTY(std::string* buffer,
3096                               TPMS_ALG_PROPERTY* value,
3097                               std::string* value_bytes) {
3098  TPM_RC result = TPM_RC_SUCCESS;
3099  VLOG(3) << __func__;
3100
3101  result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
3102  if (result) {
3103    return result;
3104  }
3105
3106  result = Parse_TPMA_ALGORITHM(buffer, &value->alg_properties, value_bytes);
3107  if (result) {
3108    return result;
3109  }
3110  return result;
3111}
3112
3113TPM_RC Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY& value,
3114                                      std::string* buffer) {
3115  TPM_RC result = TPM_RC_SUCCESS;
3116  VLOG(3) << __func__;
3117
3118  result = Serialize_TPM_PT(value.property, buffer);
3119  if (result) {
3120    return result;
3121  }
3122
3123  result = Serialize_UINT32(value.value, buffer);
3124  if (result) {
3125    return result;
3126  }
3127  return result;
3128}
3129
3130TPM_RC Parse_TPMS_TAGGED_PROPERTY(std::string* buffer,
3131                                  TPMS_TAGGED_PROPERTY* value,
3132                                  std::string* value_bytes) {
3133  TPM_RC result = TPM_RC_SUCCESS;
3134  VLOG(3) << __func__;
3135
3136  result = Parse_TPM_PT(buffer, &value->property, value_bytes);
3137  if (result) {
3138    return result;
3139  }
3140
3141  result = Parse_UINT32(buffer, &value->value, value_bytes);
3142  if (result) {
3143    return result;
3144  }
3145  return result;
3146}
3147
3148TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT& value,
3149                                        std::string* buffer) {
3150  TPM_RC result = TPM_RC_SUCCESS;
3151  VLOG(3) << __func__;
3152
3153  result = Serialize_TPM_PT(value.tag, buffer);
3154  if (result) {
3155    return result;
3156  }
3157
3158  result = Serialize_UINT8(value.sizeof_select, buffer);
3159  if (result) {
3160    return result;
3161  }
3162
3163  if (arraysize(value.pcr_select) < value.sizeof_select) {
3164    return TPM_RC_INSUFFICIENT;
3165  }
3166  for (uint32_t i = 0; i < value.sizeof_select; ++i) {
3167    result = Serialize_BYTE(value.pcr_select[i], buffer);
3168    if (result) {
3169      return result;
3170    }
3171  }
3172  return result;
3173}
3174
3175TPM_RC Parse_TPMS_TAGGED_PCR_SELECT(std::string* buffer,
3176                                    TPMS_TAGGED_PCR_SELECT* value,
3177                                    std::string* value_bytes) {
3178  TPM_RC result = TPM_RC_SUCCESS;
3179  VLOG(3) << __func__;
3180
3181  result = Parse_TPM_PT(buffer, &value->tag, value_bytes);
3182  if (result) {
3183    return result;
3184  }
3185
3186  result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
3187  if (result) {
3188    return result;
3189  }
3190
3191  if (arraysize(value->pcr_select) < value->sizeof_select) {
3192    return TPM_RC_INSUFFICIENT;
3193  }
3194  for (uint32_t i = 0; i < value->sizeof_select; ++i) {
3195    result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
3196    if (result) {
3197      return result;
3198    }
3199  }
3200  return result;
3201}
3202
3203TPM_RC Serialize_TPML_CC(const TPML_CC& value, std::string* buffer) {
3204  TPM_RC result = TPM_RC_SUCCESS;
3205  VLOG(3) << __func__;
3206
3207  result = Serialize_UINT32(value.count, buffer);
3208  if (result) {
3209    return result;
3210  }
3211
3212  if (arraysize(value.command_codes) < value.count) {
3213    return TPM_RC_INSUFFICIENT;
3214  }
3215  for (uint32_t i = 0; i < value.count; ++i) {
3216    result = Serialize_TPM_CC(value.command_codes[i], buffer);
3217    if (result) {
3218      return result;
3219    }
3220  }
3221  return result;
3222}
3223
3224TPM_RC Parse_TPML_CC(std::string* buffer,
3225                     TPML_CC* value,
3226                     std::string* value_bytes) {
3227  TPM_RC result = TPM_RC_SUCCESS;
3228  VLOG(3) << __func__;
3229
3230  result = Parse_UINT32(buffer, &value->count, value_bytes);
3231  if (result) {
3232    return result;
3233  }
3234
3235  if (arraysize(value->command_codes) < value->count) {
3236    return TPM_RC_INSUFFICIENT;
3237  }
3238  for (uint32_t i = 0; i < value->count; ++i) {
3239    result = Parse_TPM_CC(buffer, &value->command_codes[i], value_bytes);
3240    if (result) {
3241      return result;
3242    }
3243  }
3244  return result;
3245}
3246
3247TPM_RC Serialize_TPML_CCA(const TPML_CCA& value, std::string* buffer) {
3248  TPM_RC result = TPM_RC_SUCCESS;
3249  VLOG(3) << __func__;
3250
3251  result = Serialize_UINT32(value.count, buffer);
3252  if (result) {
3253    return result;
3254  }
3255
3256  if (arraysize(value.command_attributes) < value.count) {
3257    return TPM_RC_INSUFFICIENT;
3258  }
3259  for (uint32_t i = 0; i < value.count; ++i) {
3260    result = Serialize_TPMA_CC(value.command_attributes[i], buffer);
3261    if (result) {
3262      return result;
3263    }
3264  }
3265  return result;
3266}
3267
3268TPM_RC Parse_TPML_CCA(std::string* buffer,
3269                      TPML_CCA* value,
3270                      std::string* value_bytes) {
3271  TPM_RC result = TPM_RC_SUCCESS;
3272  VLOG(3) << __func__;
3273
3274  result = Parse_UINT32(buffer, &value->count, value_bytes);
3275  if (result) {
3276    return result;
3277  }
3278
3279  if (arraysize(value->command_attributes) < value->count) {
3280    return TPM_RC_INSUFFICIENT;
3281  }
3282  for (uint32_t i = 0; i < value->count; ++i) {
3283    result = Parse_TPMA_CC(buffer, &value->command_attributes[i], value_bytes);
3284    if (result) {
3285      return result;
3286    }
3287  }
3288  return result;
3289}
3290
3291TPM_RC Serialize_TPML_ALG(const TPML_ALG& value, std::string* buffer) {
3292  TPM_RC result = TPM_RC_SUCCESS;
3293  VLOG(3) << __func__;
3294
3295  result = Serialize_UINT32(value.count, buffer);
3296  if (result) {
3297    return result;
3298  }
3299
3300  if (arraysize(value.algorithms) < value.count) {
3301    return TPM_RC_INSUFFICIENT;
3302  }
3303  for (uint32_t i = 0; i < value.count; ++i) {
3304    result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer);
3305    if (result) {
3306      return result;
3307    }
3308  }
3309  return result;
3310}
3311
3312TPM_RC Parse_TPML_ALG(std::string* buffer,
3313                      TPML_ALG* value,
3314                      std::string* value_bytes) {
3315  TPM_RC result = TPM_RC_SUCCESS;
3316  VLOG(3) << __func__;
3317
3318  result = Parse_UINT32(buffer, &value->count, value_bytes);
3319  if (result) {
3320    return result;
3321  }
3322
3323  if (arraysize(value->algorithms) < value->count) {
3324    return TPM_RC_INSUFFICIENT;
3325  }
3326  for (uint32_t i = 0; i < value->count; ++i) {
3327    result = Parse_TPM_ALG_ID(buffer, &value->algorithms[i], value_bytes);
3328    if (result) {
3329      return result;
3330    }
3331  }
3332  return result;
3333}
3334
3335TPM_RC Serialize_TPML_HANDLE(const TPML_HANDLE& value, std::string* buffer) {
3336  TPM_RC result = TPM_RC_SUCCESS;
3337  VLOG(3) << __func__;
3338
3339  result = Serialize_UINT32(value.count, buffer);
3340  if (result) {
3341    return result;
3342  }
3343
3344  if (arraysize(value.handle) < value.count) {
3345    return TPM_RC_INSUFFICIENT;
3346  }
3347  for (uint32_t i = 0; i < value.count; ++i) {
3348    result = Serialize_TPM_HANDLE(value.handle[i], buffer);
3349    if (result) {
3350      return result;
3351    }
3352  }
3353  return result;
3354}
3355
3356TPM_RC Parse_TPML_HANDLE(std::string* buffer,
3357                         TPML_HANDLE* value,
3358                         std::string* value_bytes) {
3359  TPM_RC result = TPM_RC_SUCCESS;
3360  VLOG(3) << __func__;
3361
3362  result = Parse_UINT32(buffer, &value->count, value_bytes);
3363  if (result) {
3364    return result;
3365  }
3366
3367  if (arraysize(value->handle) < value->count) {
3368    return TPM_RC_INSUFFICIENT;
3369  }
3370  for (uint32_t i = 0; i < value->count; ++i) {
3371    result = Parse_TPM_HANDLE(buffer, &value->handle[i], value_bytes);
3372    if (result) {
3373      return result;
3374    }
3375  }
3376  return result;
3377}
3378
3379TPM_RC Serialize_TPML_DIGEST(const TPML_DIGEST& value, std::string* buffer) {
3380  TPM_RC result = TPM_RC_SUCCESS;
3381  VLOG(3) << __func__;
3382
3383  result = Serialize_UINT32(value.count, buffer);
3384  if (result) {
3385    return result;
3386  }
3387
3388  if (arraysize(value.digests) < value.count) {
3389    return TPM_RC_INSUFFICIENT;
3390  }
3391  for (uint32_t i = 0; i < value.count; ++i) {
3392    result = Serialize_TPM2B_DIGEST(value.digests[i], buffer);
3393    if (result) {
3394      return result;
3395    }
3396  }
3397  return result;
3398}
3399
3400TPM_RC Parse_TPML_DIGEST(std::string* buffer,
3401                         TPML_DIGEST* value,
3402                         std::string* value_bytes) {
3403  TPM_RC result = TPM_RC_SUCCESS;
3404  VLOG(3) << __func__;
3405
3406  result = Parse_UINT32(buffer, &value->count, value_bytes);
3407  if (result) {
3408    return result;
3409  }
3410
3411  if (arraysize(value->digests) < value->count) {
3412    return TPM_RC_INSUFFICIENT;
3413  }
3414  for (uint32_t i = 0; i < value->count; ++i) {
3415    result = Parse_TPM2B_DIGEST(buffer, &value->digests[i], value_bytes);
3416    if (result) {
3417      return result;
3418    }
3419  }
3420  return result;
3421}
3422
3423TPM_RC Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES& value,
3424                                    std::string* buffer) {
3425  TPM_RC result = TPM_RC_SUCCESS;
3426  VLOG(3) << __func__;
3427
3428  result = Serialize_UINT32(value.count, buffer);
3429  if (result) {
3430    return result;
3431  }
3432
3433  if (arraysize(value.digests) < value.count) {
3434    return TPM_RC_INSUFFICIENT;
3435  }
3436  for (uint32_t i = 0; i < value.count; ++i) {
3437    result = Serialize_TPMT_HA(value.digests[i], buffer);
3438    if (result) {
3439      return result;
3440    }
3441  }
3442  return result;
3443}
3444
3445TPM_RC Parse_TPML_DIGEST_VALUES(std::string* buffer,
3446                                TPML_DIGEST_VALUES* value,
3447                                std::string* value_bytes) {
3448  TPM_RC result = TPM_RC_SUCCESS;
3449  VLOG(3) << __func__;
3450
3451  result = Parse_UINT32(buffer, &value->count, value_bytes);
3452  if (result) {
3453    return result;
3454  }
3455
3456  if (arraysize(value->digests) < value->count) {
3457    return TPM_RC_INSUFFICIENT;
3458  }
3459  for (uint32_t i = 0; i < value->count; ++i) {
3460    result = Parse_TPMT_HA(buffer, &value->digests[i], value_bytes);
3461    if (result) {
3462      return result;
3463    }
3464  }
3465  return result;
3466}
3467
3468TPM_RC Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& value,
3469                                     std::string* buffer) {
3470  TPM_RC result = TPM_RC_SUCCESS;
3471  VLOG(3) << __func__;
3472
3473  result = Serialize_UINT16(value.size, buffer);
3474  if (result) {
3475    return result;
3476  }
3477
3478  if (arraysize(value.buffer) < value.size) {
3479    return TPM_RC_INSUFFICIENT;
3480  }
3481  for (uint32_t i = 0; i < value.size; ++i) {
3482    result = Serialize_BYTE(value.buffer[i], buffer);
3483    if (result) {
3484      return result;
3485    }
3486  }
3487  return result;
3488}
3489
3490TPM_RC Parse_TPM2B_DIGEST_VALUES(std::string* buffer,
3491                                 TPM2B_DIGEST_VALUES* value,
3492                                 std::string* value_bytes) {
3493  TPM_RC result = TPM_RC_SUCCESS;
3494  VLOG(3) << __func__;
3495
3496  result = Parse_UINT16(buffer, &value->size, value_bytes);
3497  if (result) {
3498    return result;
3499  }
3500
3501  if (arraysize(value->buffer) < value->size) {
3502    return TPM_RC_INSUFFICIENT;
3503  }
3504  for (uint32_t i = 0; i < value->size; ++i) {
3505    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
3506    if (result) {
3507      return result;
3508    }
3509  }
3510  return result;
3511}
3512
3513TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES(const std::string& bytes) {
3514  TPM2B_DIGEST_VALUES tpm2b;
3515  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
3516  memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES));
3517  tpm2b.size = bytes.size();
3518  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
3519  return tpm2b;
3520}
3521
3522std::string StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& tpm2b) {
3523  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
3524  return std::string(char_buffer, tpm2b.size);
3525}
3526
3527TPM_RC Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION& value,
3528                                    std::string* buffer) {
3529  TPM_RC result = TPM_RC_SUCCESS;
3530  VLOG(3) << __func__;
3531
3532  result = Serialize_UINT32(value.count, buffer);
3533  if (result) {
3534    return result;
3535  }
3536
3537  if (arraysize(value.pcr_selections) < value.count) {
3538    return TPM_RC_INSUFFICIENT;
3539  }
3540  for (uint32_t i = 0; i < value.count; ++i) {
3541    result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer);
3542    if (result) {
3543      return result;
3544    }
3545  }
3546  return result;
3547}
3548
3549TPM_RC Parse_TPML_PCR_SELECTION(std::string* buffer,
3550                                TPML_PCR_SELECTION* value,
3551                                std::string* value_bytes) {
3552  TPM_RC result = TPM_RC_SUCCESS;
3553  VLOG(3) << __func__;
3554
3555  result = Parse_UINT32(buffer, &value->count, value_bytes);
3556  if (result) {
3557    return result;
3558  }
3559
3560  if (arraysize(value->pcr_selections) < value->count) {
3561    return TPM_RC_INSUFFICIENT;
3562  }
3563  for (uint32_t i = 0; i < value->count; ++i) {
3564    result = Parse_TPMS_PCR_SELECTION(buffer, &value->pcr_selections[i],
3565                                      value_bytes);
3566    if (result) {
3567      return result;
3568    }
3569  }
3570  return result;
3571}
3572
3573TPM_RC Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY& value,
3574                                   std::string* buffer) {
3575  TPM_RC result = TPM_RC_SUCCESS;
3576  VLOG(3) << __func__;
3577
3578  result = Serialize_UINT32(value.count, buffer);
3579  if (result) {
3580    return result;
3581  }
3582
3583  if (arraysize(value.alg_properties) < value.count) {
3584    return TPM_RC_INSUFFICIENT;
3585  }
3586  for (uint32_t i = 0; i < value.count; ++i) {
3587    result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer);
3588    if (result) {
3589      return result;
3590    }
3591  }
3592  return result;
3593}
3594
3595TPM_RC Parse_TPML_ALG_PROPERTY(std::string* buffer,
3596                               TPML_ALG_PROPERTY* value,
3597                               std::string* value_bytes) {
3598  TPM_RC result = TPM_RC_SUCCESS;
3599  VLOG(3) << __func__;
3600
3601  result = Parse_UINT32(buffer, &value->count, value_bytes);
3602  if (result) {
3603    return result;
3604  }
3605
3606  if (arraysize(value->alg_properties) < value->count) {
3607    return TPM_RC_INSUFFICIENT;
3608  }
3609  for (uint32_t i = 0; i < value->count; ++i) {
3610    result =
3611        Parse_TPMS_ALG_PROPERTY(buffer, &value->alg_properties[i], value_bytes);
3612    if (result) {
3613      return result;
3614    }
3615  }
3616  return result;
3617}
3618
3619TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY& value,
3620                                          std::string* buffer) {
3621  TPM_RC result = TPM_RC_SUCCESS;
3622  VLOG(3) << __func__;
3623
3624  result = Serialize_UINT32(value.count, buffer);
3625  if (result) {
3626    return result;
3627  }
3628
3629  if (arraysize(value.tpm_property) < value.count) {
3630    return TPM_RC_INSUFFICIENT;
3631  }
3632  for (uint32_t i = 0; i < value.count; ++i) {
3633    result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer);
3634    if (result) {
3635      return result;
3636    }
3637  }
3638  return result;
3639}
3640
3641TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY(std::string* buffer,
3642                                      TPML_TAGGED_TPM_PROPERTY* value,
3643                                      std::string* value_bytes) {
3644  TPM_RC result = TPM_RC_SUCCESS;
3645  VLOG(3) << __func__;
3646
3647  result = Parse_UINT32(buffer, &value->count, value_bytes);
3648  if (result) {
3649    return result;
3650  }
3651
3652  if (arraysize(value->tpm_property) < value->count) {
3653    return TPM_RC_INSUFFICIENT;
3654  }
3655  for (uint32_t i = 0; i < value->count; ++i) {
3656    result = Parse_TPMS_TAGGED_PROPERTY(buffer, &value->tpm_property[i],
3657                                        value_bytes);
3658    if (result) {
3659      return result;
3660    }
3661  }
3662  return result;
3663}
3664
3665TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY& value,
3666                                          std::string* buffer) {
3667  TPM_RC result = TPM_RC_SUCCESS;
3668  VLOG(3) << __func__;
3669
3670  result = Serialize_UINT32(value.count, buffer);
3671  if (result) {
3672    return result;
3673  }
3674
3675  if (arraysize(value.pcr_property) < value.count) {
3676    return TPM_RC_INSUFFICIENT;
3677  }
3678  for (uint32_t i = 0; i < value.count; ++i) {
3679    result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer);
3680    if (result) {
3681      return result;
3682    }
3683  }
3684  return result;
3685}
3686
3687TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY(std::string* buffer,
3688                                      TPML_TAGGED_PCR_PROPERTY* value,
3689                                      std::string* value_bytes) {
3690  TPM_RC result = TPM_RC_SUCCESS;
3691  VLOG(3) << __func__;
3692
3693  result = Parse_UINT32(buffer, &value->count, value_bytes);
3694  if (result) {
3695    return result;
3696  }
3697
3698  if (arraysize(value->pcr_property) < value->count) {
3699    return TPM_RC_INSUFFICIENT;
3700  }
3701  for (uint32_t i = 0; i < value->count; ++i) {
3702    result = Parse_TPMS_TAGGED_PCR_SELECT(buffer, &value->pcr_property[i],
3703                                          value_bytes);
3704    if (result) {
3705      return result;
3706    }
3707  }
3708  return result;
3709}
3710
3711TPM_RC Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE& value,
3712                                std::string* buffer) {
3713  TPM_RC result = TPM_RC_SUCCESS;
3714  VLOG(3) << __func__;
3715
3716  result = Serialize_UINT32(value.count, buffer);
3717  if (result) {
3718    return result;
3719  }
3720
3721  if (arraysize(value.ecc_curves) < value.count) {
3722    return TPM_RC_INSUFFICIENT;
3723  }
3724  for (uint32_t i = 0; i < value.count; ++i) {
3725    result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer);
3726    if (result) {
3727      return result;
3728    }
3729  }
3730  return result;
3731}
3732
3733TPM_RC Parse_TPML_ECC_CURVE(std::string* buffer,
3734                            TPML_ECC_CURVE* value,
3735                            std::string* value_bytes) {
3736  TPM_RC result = TPM_RC_SUCCESS;
3737  VLOG(3) << __func__;
3738
3739  result = Parse_UINT32(buffer, &value->count, value_bytes);
3740  if (result) {
3741    return result;
3742  }
3743
3744  if (arraysize(value->ecc_curves) < value->count) {
3745    return TPM_RC_INSUFFICIENT;
3746  }
3747  for (uint32_t i = 0; i < value->count; ++i) {
3748    result = Parse_TPM_ECC_CURVE(buffer, &value->ecc_curves[i], value_bytes);
3749    if (result) {
3750      return result;
3751    }
3752  }
3753  return result;
3754}
3755
3756TPM_RC Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES& value,
3757                                   TPM_CAP selector,
3758                                   std::string* buffer) {
3759  TPM_RC result = TPM_RC_SUCCESS;
3760  VLOG(3) << __func__;
3761
3762  if (selector == TPM_CAP_PCRS) {
3763    result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer);
3764    if (result) {
3765      return result;
3766    }
3767  }
3768
3769  if (selector == TPM_CAP_TPM_PROPERTIES) {
3770    result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer);
3771    if (result) {
3772      return result;
3773    }
3774  }
3775
3776  if (selector == TPM_CAP_PP_COMMANDS) {
3777    result = Serialize_TPML_CC(value.pp_commands, buffer);
3778    if (result) {
3779      return result;
3780    }
3781  }
3782
3783  if (selector == TPM_CAP_AUDIT_COMMANDS) {
3784    result = Serialize_TPML_CC(value.audit_commands, buffer);
3785    if (result) {
3786      return result;
3787    }
3788  }
3789
3790  if (selector == TPM_CAP_COMMANDS) {
3791    result = Serialize_TPML_CCA(value.command, buffer);
3792    if (result) {
3793      return result;
3794    }
3795  }
3796
3797  if (selector == TPM_CAP_ECC_CURVES) {
3798    result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer);
3799    if (result) {
3800      return result;
3801    }
3802  }
3803
3804  if (selector == TPM_CAP_PCR_PROPERTIES) {
3805    result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer);
3806    if (result) {
3807      return result;
3808    }
3809  }
3810
3811  if (selector == TPM_CAP_HANDLES) {
3812    result = Serialize_TPML_HANDLE(value.handles, buffer);
3813    if (result) {
3814      return result;
3815    }
3816  }
3817
3818  if (selector == TPM_CAP_ALGS) {
3819    result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer);
3820    if (result) {
3821      return result;
3822    }
3823  }
3824  return result;
3825}
3826
3827TPM_RC Parse_TPMU_CAPABILITIES(std::string* buffer,
3828                               TPM_CAP selector,
3829                               TPMU_CAPABILITIES* value,
3830                               std::string* value_bytes) {
3831  TPM_RC result = TPM_RC_SUCCESS;
3832  VLOG(3) << __func__;
3833
3834  if (selector == TPM_CAP_PCRS) {
3835    result =
3836        Parse_TPML_PCR_SELECTION(buffer, &value->assigned_pcr, value_bytes);
3837    if (result) {
3838      return result;
3839    }
3840  }
3841
3842  if (selector == TPM_CAP_TPM_PROPERTIES) {
3843    result = Parse_TPML_TAGGED_TPM_PROPERTY(buffer, &value->tpm_properties,
3844                                            value_bytes);
3845    if (result) {
3846      return result;
3847    }
3848  }
3849
3850  if (selector == TPM_CAP_PP_COMMANDS) {
3851    result = Parse_TPML_CC(buffer, &value->pp_commands, value_bytes);
3852    if (result) {
3853      return result;
3854    }
3855  }
3856
3857  if (selector == TPM_CAP_AUDIT_COMMANDS) {
3858    result = Parse_TPML_CC(buffer, &value->audit_commands, value_bytes);
3859    if (result) {
3860      return result;
3861    }
3862  }
3863
3864  if (selector == TPM_CAP_COMMANDS) {
3865    result = Parse_TPML_CCA(buffer, &value->command, value_bytes);
3866    if (result) {
3867      return result;
3868    }
3869  }
3870
3871  if (selector == TPM_CAP_ECC_CURVES) {
3872    result = Parse_TPML_ECC_CURVE(buffer, &value->ecc_curves, value_bytes);
3873    if (result) {
3874      return result;
3875    }
3876  }
3877
3878  if (selector == TPM_CAP_PCR_PROPERTIES) {
3879    result = Parse_TPML_TAGGED_PCR_PROPERTY(buffer, &value->pcr_properties,
3880                                            value_bytes);
3881    if (result) {
3882      return result;
3883    }
3884  }
3885
3886  if (selector == TPM_CAP_HANDLES) {
3887    result = Parse_TPML_HANDLE(buffer, &value->handles, value_bytes);
3888    if (result) {
3889      return result;
3890    }
3891  }
3892
3893  if (selector == TPM_CAP_ALGS) {
3894    result = Parse_TPML_ALG_PROPERTY(buffer, &value->algorithms, value_bytes);
3895    if (result) {
3896      return result;
3897    }
3898  }
3899  return result;
3900}
3901
3902TPM_RC Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA& value,
3903                                      std::string* buffer) {
3904  TPM_RC result = TPM_RC_SUCCESS;
3905  VLOG(3) << __func__;
3906
3907  result = Serialize_TPM_CAP(value.capability, buffer);
3908  if (result) {
3909    return result;
3910  }
3911
3912  result = Serialize_TPMU_CAPABILITIES(value.data, value.capability, buffer);
3913  if (result) {
3914    return result;
3915  }
3916  return result;
3917}
3918
3919TPM_RC Parse_TPMS_CAPABILITY_DATA(std::string* buffer,
3920                                  TPMS_CAPABILITY_DATA* value,
3921                                  std::string* value_bytes) {
3922  TPM_RC result = TPM_RC_SUCCESS;
3923  VLOG(3) << __func__;
3924
3925  result = Parse_TPM_CAP(buffer, &value->capability, value_bytes);
3926  if (result) {
3927    return result;
3928  }
3929
3930  result = Parse_TPMU_CAPABILITIES(buffer, value->capability, &value->data,
3931                                   value_bytes);
3932  if (result) {
3933    return result;
3934  }
3935  return result;
3936}
3937
3938TPM_RC Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO& value,
3939                                 std::string* buffer) {
3940  TPM_RC result = TPM_RC_SUCCESS;
3941  VLOG(3) << __func__;
3942
3943  result = Serialize_UINT64(value.clock, buffer);
3944  if (result) {
3945    return result;
3946  }
3947
3948  result = Serialize_UINT32(value.reset_count, buffer);
3949  if (result) {
3950    return result;
3951  }
3952
3953  result = Serialize_UINT32(value.restart_count, buffer);
3954  if (result) {
3955    return result;
3956  }
3957
3958  result = Serialize_TPMI_YES_NO(value.safe, buffer);
3959  if (result) {
3960    return result;
3961  }
3962  return result;
3963}
3964
3965TPM_RC Parse_TPMS_CLOCK_INFO(std::string* buffer,
3966                             TPMS_CLOCK_INFO* value,
3967                             std::string* value_bytes) {
3968  TPM_RC result = TPM_RC_SUCCESS;
3969  VLOG(3) << __func__;
3970
3971  result = Parse_UINT64(buffer, &value->clock, value_bytes);
3972  if (result) {
3973    return result;
3974  }
3975
3976  result = Parse_UINT32(buffer, &value->reset_count, value_bytes);
3977  if (result) {
3978    return result;
3979  }
3980
3981  result = Parse_UINT32(buffer, &value->restart_count, value_bytes);
3982  if (result) {
3983    return result;
3984  }
3985
3986  result = Parse_TPMI_YES_NO(buffer, &value->safe, value_bytes);
3987  if (result) {
3988    return result;
3989  }
3990  return result;
3991}
3992
3993TPM_RC Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO& value,
3994                                std::string* buffer) {
3995  TPM_RC result = TPM_RC_SUCCESS;
3996  VLOG(3) << __func__;
3997
3998  result = Serialize_UINT64(value.time, buffer);
3999  if (result) {
4000    return result;
4001  }
4002
4003  result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4004  if (result) {
4005    return result;
4006  }
4007  return result;
4008}
4009
4010TPM_RC Parse_TPMS_TIME_INFO(std::string* buffer,
4011                            TPMS_TIME_INFO* value,
4012                            std::string* value_bytes) {
4013  TPM_RC result = TPM_RC_SUCCESS;
4014  VLOG(3) << __func__;
4015
4016  result = Parse_UINT64(buffer, &value->time, value_bytes);
4017  if (result) {
4018    return result;
4019  }
4020
4021  result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4022  if (result) {
4023    return result;
4024  }
4025  return result;
4026}
4027
4028TPM_RC Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO& value,
4029                                       std::string* buffer) {
4030  TPM_RC result = TPM_RC_SUCCESS;
4031  VLOG(3) << __func__;
4032
4033  result = Serialize_TPMS_TIME_INFO(value.time, buffer);
4034  if (result) {
4035    return result;
4036  }
4037
4038  result = Serialize_UINT64(value.firmware_version, buffer);
4039  if (result) {
4040    return result;
4041  }
4042  return result;
4043}
4044
4045TPM_RC Parse_TPMS_TIME_ATTEST_INFO(std::string* buffer,
4046                                   TPMS_TIME_ATTEST_INFO* value,
4047                                   std::string* value_bytes) {
4048  TPM_RC result = TPM_RC_SUCCESS;
4049  VLOG(3) << __func__;
4050
4051  result = Parse_TPMS_TIME_INFO(buffer, &value->time, value_bytes);
4052  if (result) {
4053    return result;
4054  }
4055
4056  result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4057  if (result) {
4058    return result;
4059  }
4060  return result;
4061}
4062
4063TPM_RC Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO& value,
4064                                   std::string* buffer) {
4065  TPM_RC result = TPM_RC_SUCCESS;
4066  VLOG(3) << __func__;
4067
4068  result = Serialize_TPM2B_NAME(value.name, buffer);
4069  if (result) {
4070    return result;
4071  }
4072
4073  result = Serialize_TPM2B_NAME(value.qualified_name, buffer);
4074  if (result) {
4075    return result;
4076  }
4077  return result;
4078}
4079
4080TPM_RC Parse_TPMS_CERTIFY_INFO(std::string* buffer,
4081                               TPMS_CERTIFY_INFO* value,
4082                               std::string* value_bytes) {
4083  TPM_RC result = TPM_RC_SUCCESS;
4084  VLOG(3) << __func__;
4085
4086  result = Parse_TPM2B_NAME(buffer, &value->name, value_bytes);
4087  if (result) {
4088    return result;
4089  }
4090
4091  result = Parse_TPM2B_NAME(buffer, &value->qualified_name, value_bytes);
4092  if (result) {
4093    return result;
4094  }
4095  return result;
4096}
4097
4098TPM_RC Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO& value,
4099                                 std::string* buffer) {
4100  TPM_RC result = TPM_RC_SUCCESS;
4101  VLOG(3) << __func__;
4102
4103  result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
4104  if (result) {
4105    return result;
4106  }
4107
4108  result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
4109  if (result) {
4110    return result;
4111  }
4112  return result;
4113}
4114
4115TPM_RC Parse_TPMS_QUOTE_INFO(std::string* buffer,
4116                             TPMS_QUOTE_INFO* value,
4117                             std::string* value_bytes) {
4118  TPM_RC result = TPM_RC_SUCCESS;
4119  VLOG(3) << __func__;
4120
4121  result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
4122  if (result) {
4123    return result;
4124  }
4125
4126  result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
4127  if (result) {
4128    return result;
4129  }
4130  return result;
4131}
4132
4133TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO& value,
4134                                         std::string* buffer) {
4135  TPM_RC result = TPM_RC_SUCCESS;
4136  VLOG(3) << __func__;
4137
4138  result = Serialize_UINT64(value.audit_counter, buffer);
4139  if (result) {
4140    return result;
4141  }
4142
4143  result = Serialize_TPM_ALG_ID(value.digest_alg, buffer);
4144  if (result) {
4145    return result;
4146  }
4147
4148  result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer);
4149  if (result) {
4150    return result;
4151  }
4152
4153  result = Serialize_TPM2B_DIGEST(value.command_digest, buffer);
4154  if (result) {
4155    return result;
4156  }
4157  return result;
4158}
4159
4160TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO(std::string* buffer,
4161                                     TPMS_COMMAND_AUDIT_INFO* value,
4162                                     std::string* value_bytes) {
4163  TPM_RC result = TPM_RC_SUCCESS;
4164  VLOG(3) << __func__;
4165
4166  result = Parse_UINT64(buffer, &value->audit_counter, value_bytes);
4167  if (result) {
4168    return result;
4169  }
4170
4171  result = Parse_TPM_ALG_ID(buffer, &value->digest_alg, value_bytes);
4172  if (result) {
4173    return result;
4174  }
4175
4176  result = Parse_TPM2B_DIGEST(buffer, &value->audit_digest, value_bytes);
4177  if (result) {
4178    return result;
4179  }
4180
4181  result = Parse_TPM2B_DIGEST(buffer, &value->command_digest, value_bytes);
4182  if (result) {
4183    return result;
4184  }
4185  return result;
4186}
4187
4188TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO& value,
4189                                         std::string* buffer) {
4190  TPM_RC result = TPM_RC_SUCCESS;
4191  VLOG(3) << __func__;
4192
4193  result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer);
4194  if (result) {
4195    return result;
4196  }
4197
4198  result = Serialize_TPM2B_DIGEST(value.session_digest, buffer);
4199  if (result) {
4200    return result;
4201  }
4202  return result;
4203}
4204
4205TPM_RC Parse_TPMS_SESSION_AUDIT_INFO(std::string* buffer,
4206                                     TPMS_SESSION_AUDIT_INFO* value,
4207                                     std::string* value_bytes) {
4208  TPM_RC result = TPM_RC_SUCCESS;
4209  VLOG(3) << __func__;
4210
4211  result = Parse_TPMI_YES_NO(buffer, &value->exclusive_session, value_bytes);
4212  if (result) {
4213    return result;
4214  }
4215
4216  result = Parse_TPM2B_DIGEST(buffer, &value->session_digest, value_bytes);
4217  if (result) {
4218    return result;
4219  }
4220  return result;
4221}
4222
4223TPM_RC Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO& value,
4224                                    std::string* buffer) {
4225  TPM_RC result = TPM_RC_SUCCESS;
4226  VLOG(3) << __func__;
4227
4228  result = Serialize_TPM2B_NAME(value.object_name, buffer);
4229  if (result) {
4230    return result;
4231  }
4232
4233  result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer);
4234  if (result) {
4235    return result;
4236  }
4237  return result;
4238}
4239
4240TPM_RC Parse_TPMS_CREATION_INFO(std::string* buffer,
4241                                TPMS_CREATION_INFO* value,
4242                                std::string* value_bytes) {
4243  TPM_RC result = TPM_RC_SUCCESS;
4244  VLOG(3) << __func__;
4245
4246  result = Parse_TPM2B_NAME(buffer, &value->object_name, value_bytes);
4247  if (result) {
4248    return result;
4249  }
4250
4251  result = Parse_TPM2B_DIGEST(buffer, &value->creation_hash, value_bytes);
4252  if (result) {
4253    return result;
4254  }
4255  return result;
4256}
4257
4258TPM_RC Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO& value,
4259                                      std::string* buffer) {
4260  TPM_RC result = TPM_RC_SUCCESS;
4261  VLOG(3) << __func__;
4262
4263  result = Serialize_TPM2B_NAME(value.index_name, buffer);
4264  if (result) {
4265    return result;
4266  }
4267
4268  result = Serialize_UINT16(value.offset, buffer);
4269  if (result) {
4270    return result;
4271  }
4272
4273  result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer);
4274  if (result) {
4275    return result;
4276  }
4277  return result;
4278}
4279
4280TPM_RC Parse_TPMS_NV_CERTIFY_INFO(std::string* buffer,
4281                                  TPMS_NV_CERTIFY_INFO* value,
4282                                  std::string* value_bytes) {
4283  TPM_RC result = TPM_RC_SUCCESS;
4284  VLOG(3) << __func__;
4285
4286  result = Parse_TPM2B_NAME(buffer, &value->index_name, value_bytes);
4287  if (result) {
4288    return result;
4289  }
4290
4291  result = Parse_UINT16(buffer, &value->offset, value_bytes);
4292  if (result) {
4293    return result;
4294  }
4295
4296  result = Parse_TPM2B_MAX_NV_BUFFER(buffer, &value->nv_contents, value_bytes);
4297  if (result) {
4298    return result;
4299  }
4300  return result;
4301}
4302
4303TPM_RC Serialize_TPMU_ATTEST(const TPMU_ATTEST& value,
4304                             TPMI_ST_ATTEST selector,
4305                             std::string* buffer) {
4306  TPM_RC result = TPM_RC_SUCCESS;
4307  VLOG(3) << __func__;
4308
4309  if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4310    result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer);
4311    if (result) {
4312      return result;
4313    }
4314  }
4315
4316  if (selector == TPM_ST_ATTEST_QUOTE) {
4317    result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer);
4318    if (result) {
4319      return result;
4320    }
4321  }
4322
4323  if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4324    result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer);
4325    if (result) {
4326      return result;
4327    }
4328  }
4329
4330  if (selector == TPM_ST_ATTEST_CERTIFY) {
4331    result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer);
4332    if (result) {
4333      return result;
4334    }
4335  }
4336
4337  if (selector == TPM_ST_ATTEST_NV) {
4338    result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer);
4339    if (result) {
4340      return result;
4341    }
4342  }
4343
4344  if (selector == TPM_ST_ATTEST_TIME) {
4345    result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer);
4346    if (result) {
4347      return result;
4348    }
4349  }
4350
4351  if (selector == TPM_ST_ATTEST_CREATION) {
4352    result = Serialize_TPMS_CREATION_INFO(value.creation, buffer);
4353    if (result) {
4354      return result;
4355    }
4356  }
4357  return result;
4358}
4359
4360TPM_RC Parse_TPMU_ATTEST(std::string* buffer,
4361                         TPMI_ST_ATTEST selector,
4362                         TPMU_ATTEST* value,
4363                         std::string* value_bytes) {
4364  TPM_RC result = TPM_RC_SUCCESS;
4365  VLOG(3) << __func__;
4366
4367  if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4368    result = Parse_TPMS_SESSION_AUDIT_INFO(buffer, &value->session_audit,
4369                                           value_bytes);
4370    if (result) {
4371      return result;
4372    }
4373  }
4374
4375  if (selector == TPM_ST_ATTEST_QUOTE) {
4376    result = Parse_TPMS_QUOTE_INFO(buffer, &value->quote, value_bytes);
4377    if (result) {
4378      return result;
4379    }
4380  }
4381
4382  if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4383    result = Parse_TPMS_COMMAND_AUDIT_INFO(buffer, &value->command_audit,
4384                                           value_bytes);
4385    if (result) {
4386      return result;
4387    }
4388  }
4389
4390  if (selector == TPM_ST_ATTEST_CERTIFY) {
4391    result = Parse_TPMS_CERTIFY_INFO(buffer, &value->certify, value_bytes);
4392    if (result) {
4393      return result;
4394    }
4395  }
4396
4397  if (selector == TPM_ST_ATTEST_NV) {
4398    result = Parse_TPMS_NV_CERTIFY_INFO(buffer, &value->nv, value_bytes);
4399    if (result) {
4400      return result;
4401    }
4402  }
4403
4404  if (selector == TPM_ST_ATTEST_TIME) {
4405    result = Parse_TPMS_TIME_ATTEST_INFO(buffer, &value->time, value_bytes);
4406    if (result) {
4407      return result;
4408    }
4409  }
4410
4411  if (selector == TPM_ST_ATTEST_CREATION) {
4412    result = Parse_TPMS_CREATION_INFO(buffer, &value->creation, value_bytes);
4413    if (result) {
4414      return result;
4415    }
4416  }
4417  return result;
4418}
4419
4420TPM_RC Serialize_TPMS_ATTEST(const TPMS_ATTEST& value, std::string* buffer) {
4421  TPM_RC result = TPM_RC_SUCCESS;
4422  VLOG(3) << __func__;
4423
4424  result = Serialize_TPM_GENERATED(value.magic, buffer);
4425  if (result) {
4426    return result;
4427  }
4428
4429  result = Serialize_TPMI_ST_ATTEST(value.type, buffer);
4430  if (result) {
4431    return result;
4432  }
4433
4434  result = Serialize_TPM2B_NAME(value.qualified_signer, buffer);
4435  if (result) {
4436    return result;
4437  }
4438
4439  result = Serialize_TPM2B_DATA(value.extra_data, buffer);
4440  if (result) {
4441    return result;
4442  }
4443
4444  result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4445  if (result) {
4446    return result;
4447  }
4448
4449  result = Serialize_UINT64(value.firmware_version, buffer);
4450  if (result) {
4451    return result;
4452  }
4453
4454  result = Serialize_TPMU_ATTEST(value.attested, value.type, buffer);
4455  if (result) {
4456    return result;
4457  }
4458  return result;
4459}
4460
4461TPM_RC Parse_TPMS_ATTEST(std::string* buffer,
4462                         TPMS_ATTEST* value,
4463                         std::string* value_bytes) {
4464  TPM_RC result = TPM_RC_SUCCESS;
4465  VLOG(3) << __func__;
4466
4467  result = Parse_TPM_GENERATED(buffer, &value->magic, value_bytes);
4468  if (result) {
4469    return result;
4470  }
4471
4472  result = Parse_TPMI_ST_ATTEST(buffer, &value->type, value_bytes);
4473  if (result) {
4474    return result;
4475  }
4476
4477  result = Parse_TPM2B_NAME(buffer, &value->qualified_signer, value_bytes);
4478  if (result) {
4479    return result;
4480  }
4481
4482  result = Parse_TPM2B_DATA(buffer, &value->extra_data, value_bytes);
4483  if (result) {
4484    return result;
4485  }
4486
4487  result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4488  if (result) {
4489    return result;
4490  }
4491
4492  result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4493  if (result) {
4494    return result;
4495  }
4496
4497  result =
4498      Parse_TPMU_ATTEST(buffer, value->type, &value->attested, value_bytes);
4499  if (result) {
4500    return result;
4501  }
4502  return result;
4503}
4504
4505TPM_RC Serialize_TPM2B_ATTEST(const TPM2B_ATTEST& value, std::string* buffer) {
4506  TPM_RC result = TPM_RC_SUCCESS;
4507  VLOG(3) << __func__;
4508
4509  result = Serialize_UINT16(value.size, buffer);
4510  if (result) {
4511    return result;
4512  }
4513
4514  if (arraysize(value.attestation_data) < value.size) {
4515    return TPM_RC_INSUFFICIENT;
4516  }
4517  for (uint32_t i = 0; i < value.size; ++i) {
4518    result = Serialize_BYTE(value.attestation_data[i], buffer);
4519    if (result) {
4520      return result;
4521    }
4522  }
4523  return result;
4524}
4525
4526TPM_RC Parse_TPM2B_ATTEST(std::string* buffer,
4527                          TPM2B_ATTEST* value,
4528                          std::string* value_bytes) {
4529  TPM_RC result = TPM_RC_SUCCESS;
4530  VLOG(3) << __func__;
4531
4532  result = Parse_UINT16(buffer, &value->size, value_bytes);
4533  if (result) {
4534    return result;
4535  }
4536
4537  if (arraysize(value->attestation_data) < value->size) {
4538    return TPM_RC_INSUFFICIENT;
4539  }
4540  for (uint32_t i = 0; i < value->size; ++i) {
4541    result = Parse_BYTE(buffer, &value->attestation_data[i], value_bytes);
4542    if (result) {
4543      return result;
4544    }
4545  }
4546  return result;
4547}
4548
4549TPM2B_ATTEST Make_TPM2B_ATTEST(const std::string& bytes) {
4550  TPM2B_ATTEST tpm2b;
4551  CHECK(bytes.size() <= sizeof(tpm2b.attestation_data));
4552  memset(&tpm2b, 0, sizeof(TPM2B_ATTEST));
4553  tpm2b.size = bytes.size();
4554  memcpy(tpm2b.attestation_data, bytes.data(), bytes.size());
4555  return tpm2b;
4556}
4557
4558std::string StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST& tpm2b) {
4559  const char* char_buffer =
4560      reinterpret_cast<const char*>(tpm2b.attestation_data);
4561  return std::string(char_buffer, tpm2b.size);
4562}
4563
4564TPM_RC Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND& value,
4565                                   std::string* buffer) {
4566  TPM_RC result = TPM_RC_SUCCESS;
4567  VLOG(3) << __func__;
4568
4569  result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer);
4570  if (result) {
4571    return result;
4572  }
4573
4574  result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4575  if (result) {
4576    return result;
4577  }
4578
4579  result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4580  if (result) {
4581    return result;
4582  }
4583
4584  result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4585  if (result) {
4586    return result;
4587  }
4588  return result;
4589}
4590
4591TPM_RC Parse_TPMS_AUTH_COMMAND(std::string* buffer,
4592                               TPMS_AUTH_COMMAND* value,
4593                               std::string* value_bytes) {
4594  TPM_RC result = TPM_RC_SUCCESS;
4595  VLOG(3) << __func__;
4596
4597  result =
4598      Parse_TPMI_SH_AUTH_SESSION(buffer, &value->session_handle, value_bytes);
4599  if (result) {
4600    return result;
4601  }
4602
4603  result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4604  if (result) {
4605    return result;
4606  }
4607
4608  result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4609  if (result) {
4610    return result;
4611  }
4612
4613  result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4614  if (result) {
4615    return result;
4616  }
4617  return result;
4618}
4619
4620TPM_RC Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE& value,
4621                                    std::string* buffer) {
4622  TPM_RC result = TPM_RC_SUCCESS;
4623  VLOG(3) << __func__;
4624
4625  result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4626  if (result) {
4627    return result;
4628  }
4629
4630  result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4631  if (result) {
4632    return result;
4633  }
4634
4635  result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4636  if (result) {
4637    return result;
4638  }
4639  return result;
4640}
4641
4642TPM_RC Parse_TPMS_AUTH_RESPONSE(std::string* buffer,
4643                                TPMS_AUTH_RESPONSE* value,
4644                                std::string* value_bytes) {
4645  TPM_RC result = TPM_RC_SUCCESS;
4646  VLOG(3) << __func__;
4647
4648  result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4649  if (result) {
4650    return result;
4651  }
4652
4653  result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4654  if (result) {
4655    return result;
4656  }
4657
4658  result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4659  if (result) {
4660    return result;
4661  }
4662  return result;
4663}
4664
4665TPM_RC Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS& value,
4666                                   TPMI_ALG_SYM selector,
4667                                   std::string* buffer) {
4668  TPM_RC result = TPM_RC_SUCCESS;
4669  VLOG(3) << __func__;
4670
4671  if (selector == TPM_ALG_NULL) {
4672    // Do nothing.
4673  }
4674
4675  if (selector == TPM_ALG_SM4) {
4676    result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer);
4677    if (result) {
4678      return result;
4679    }
4680  }
4681
4682  if (selector == TPM_ALG_AES) {
4683    result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer);
4684    if (result) {
4685      return result;
4686    }
4687  }
4688
4689  if (selector == TPM_ALG_XOR) {
4690    result = Serialize_TPMI_ALG_HASH(value.xor_, buffer);
4691    if (result) {
4692      return result;
4693    }
4694  }
4695  return result;
4696}
4697
4698TPM_RC Parse_TPMU_SYM_KEY_BITS(std::string* buffer,
4699                               TPMI_ALG_SYM selector,
4700                               TPMU_SYM_KEY_BITS* value,
4701                               std::string* value_bytes) {
4702  TPM_RC result = TPM_RC_SUCCESS;
4703  VLOG(3) << __func__;
4704
4705  if (selector == TPM_ALG_NULL) {
4706    // Do nothing.
4707  }
4708
4709  if (selector == TPM_ALG_SM4) {
4710    result = Parse_TPMI_SM4_KEY_BITS(buffer, &value->sm4, value_bytes);
4711    if (result) {
4712      return result;
4713    }
4714  }
4715
4716  if (selector == TPM_ALG_AES) {
4717    result = Parse_TPMI_AES_KEY_BITS(buffer, &value->aes, value_bytes);
4718    if (result) {
4719      return result;
4720    }
4721  }
4722
4723  if (selector == TPM_ALG_XOR) {
4724    result = Parse_TPMI_ALG_HASH(buffer, &value->xor_, value_bytes);
4725    if (result) {
4726      return result;
4727    }
4728  }
4729  return result;
4730}
4731
4732TPM_RC Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE& value,
4733                               TPMI_ALG_SYM selector,
4734                               std::string* buffer) {
4735  TPM_RC result = TPM_RC_SUCCESS;
4736  VLOG(3) << __func__;
4737
4738  if (selector == TPM_ALG_NULL) {
4739    // Do nothing.
4740  }
4741
4742  if (selector == TPM_ALG_SM4) {
4743    result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer);
4744    if (result) {
4745      return result;
4746    }
4747  }
4748
4749  if (selector == TPM_ALG_AES) {
4750    result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer);
4751    if (result) {
4752      return result;
4753    }
4754  }
4755
4756  if (selector == TPM_ALG_XOR) {
4757    // Do nothing.
4758  }
4759  return result;
4760}
4761
4762TPM_RC Parse_TPMU_SYM_MODE(std::string* buffer,
4763                           TPMI_ALG_SYM selector,
4764                           TPMU_SYM_MODE* value,
4765                           std::string* value_bytes) {
4766  TPM_RC result = TPM_RC_SUCCESS;
4767  VLOG(3) << __func__;
4768
4769  if (selector == TPM_ALG_NULL) {
4770    // Do nothing.
4771  }
4772
4773  if (selector == TPM_ALG_SM4) {
4774    result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->sm4, value_bytes);
4775    if (result) {
4776      return result;
4777    }
4778  }
4779
4780  if (selector == TPM_ALG_AES) {
4781    result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->aes, value_bytes);
4782    if (result) {
4783      return result;
4784    }
4785  }
4786
4787  if (selector == TPM_ALG_XOR) {
4788    // Do nothing.
4789  }
4790  return result;
4791}
4792
4793TPM_RC Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS& value,
4794                                  TPMI_ALG_SYM selector,
4795                                  std::string* buffer) {
4796  TPM_RC result = TPM_RC_SUCCESS;
4797  VLOG(3) << __func__;
4798  return result;
4799}
4800
4801TPM_RC Parse_TPMU_SYM_DETAILS(std::string* buffer,
4802                              TPMI_ALG_SYM selector,
4803                              TPMU_SYM_DETAILS* value,
4804                              std::string* value_bytes) {
4805  TPM_RC result = TPM_RC_SUCCESS;
4806  VLOG(3) << __func__;
4807  return result;
4808}
4809
4810TPM_RC Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF& value, std::string* buffer) {
4811  TPM_RC result = TPM_RC_SUCCESS;
4812  VLOG(3) << __func__;
4813
4814  result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer);
4815  if (result) {
4816    return result;
4817  }
4818
4819  result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4820  if (result) {
4821    return result;
4822  }
4823
4824  result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4825  if (result) {
4826    return result;
4827  }
4828
4829  result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4830  if (result) {
4831    return result;
4832  }
4833  return result;
4834}
4835
4836TPM_RC Parse_TPMT_SYM_DEF(std::string* buffer,
4837                          TPMT_SYM_DEF* value,
4838                          std::string* value_bytes) {
4839  TPM_RC result = TPM_RC_SUCCESS;
4840  VLOG(3) << __func__;
4841
4842  result = Parse_TPMI_ALG_SYM(buffer, &value->algorithm, value_bytes);
4843  if (result) {
4844    return result;
4845  }
4846
4847  result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4848                                   value_bytes);
4849  if (result) {
4850    return result;
4851  }
4852
4853  result =
4854      Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4855  if (result) {
4856    return result;
4857  }
4858
4859  result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4860                                  value_bytes);
4861  if (result) {
4862    return result;
4863  }
4864  return result;
4865}
4866
4867TPM_RC Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT& value,
4868                                     std::string* buffer) {
4869  TPM_RC result = TPM_RC_SUCCESS;
4870  VLOG(3) << __func__;
4871
4872  result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer);
4873  if (result) {
4874    return result;
4875  }
4876
4877  result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4878  if (result) {
4879    return result;
4880  }
4881
4882  result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4883  if (result) {
4884    return result;
4885  }
4886
4887  result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4888  if (result) {
4889    return result;
4890  }
4891  return result;
4892}
4893
4894TPM_RC Parse_TPMT_SYM_DEF_OBJECT(std::string* buffer,
4895                                 TPMT_SYM_DEF_OBJECT* value,
4896                                 std::string* value_bytes) {
4897  TPM_RC result = TPM_RC_SUCCESS;
4898  VLOG(3) << __func__;
4899
4900  result = Parse_TPMI_ALG_SYM_OBJECT(buffer, &value->algorithm, value_bytes);
4901  if (result) {
4902    return result;
4903  }
4904
4905  result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4906                                   value_bytes);
4907  if (result) {
4908    return result;
4909  }
4910
4911  result =
4912      Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4913  if (result) {
4914    return result;
4915  }
4916
4917  result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4918                                  value_bytes);
4919  if (result) {
4920    return result;
4921  }
4922  return result;
4923}
4924
4925TPM_RC Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& value,
4926                               std::string* buffer) {
4927  TPM_RC result = TPM_RC_SUCCESS;
4928  VLOG(3) << __func__;
4929
4930  result = Serialize_UINT16(value.size, buffer);
4931  if (result) {
4932    return result;
4933  }
4934
4935  if (arraysize(value.buffer) < value.size) {
4936    return TPM_RC_INSUFFICIENT;
4937  }
4938  for (uint32_t i = 0; i < value.size; ++i) {
4939    result = Serialize_BYTE(value.buffer[i], buffer);
4940    if (result) {
4941      return result;
4942    }
4943  }
4944  return result;
4945}
4946
4947TPM_RC Parse_TPM2B_SYM_KEY(std::string* buffer,
4948                           TPM2B_SYM_KEY* value,
4949                           std::string* value_bytes) {
4950  TPM_RC result = TPM_RC_SUCCESS;
4951  VLOG(3) << __func__;
4952
4953  result = Parse_UINT16(buffer, &value->size, value_bytes);
4954  if (result) {
4955    return result;
4956  }
4957
4958  if (arraysize(value->buffer) < value->size) {
4959    return TPM_RC_INSUFFICIENT;
4960  }
4961  for (uint32_t i = 0; i < value->size; ++i) {
4962    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
4963    if (result) {
4964      return result;
4965    }
4966  }
4967  return result;
4968}
4969
4970TPM2B_SYM_KEY Make_TPM2B_SYM_KEY(const std::string& bytes) {
4971  TPM2B_SYM_KEY tpm2b;
4972  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
4973  memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY));
4974  tpm2b.size = bytes.size();
4975  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
4976  return tpm2b;
4977}
4978
4979std::string StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& tpm2b) {
4980  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
4981  return std::string(char_buffer, tpm2b.size);
4982}
4983
4984TPM_RC Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS& value,
4985                                      std::string* buffer) {
4986  TPM_RC result = TPM_RC_SUCCESS;
4987  VLOG(3) << __func__;
4988
4989  result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer);
4990  if (result) {
4991    return result;
4992  }
4993  return result;
4994}
4995
4996TPM_RC Parse_TPMS_SYMCIPHER_PARMS(std::string* buffer,
4997                                  TPMS_SYMCIPHER_PARMS* value,
4998                                  std::string* value_bytes) {
4999  TPM_RC result = TPM_RC_SUCCESS;
5000  VLOG(3) << __func__;
5001
5002  result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->sym, value_bytes);
5003  if (result) {
5004    return result;
5005  }
5006  return result;
5007}
5008
5009TPM_RC Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& value,
5010                                      std::string* buffer) {
5011  TPM_RC result = TPM_RC_SUCCESS;
5012  VLOG(3) << __func__;
5013
5014  result = Serialize_UINT16(value.size, buffer);
5015  if (result) {
5016    return result;
5017  }
5018
5019  if (arraysize(value.buffer) < value.size) {
5020    return TPM_RC_INSUFFICIENT;
5021  }
5022  for (uint32_t i = 0; i < value.size; ++i) {
5023    result = Serialize_BYTE(value.buffer[i], buffer);
5024    if (result) {
5025      return result;
5026    }
5027  }
5028  return result;
5029}
5030
5031TPM_RC Parse_TPM2B_SENSITIVE_DATA(std::string* buffer,
5032                                  TPM2B_SENSITIVE_DATA* value,
5033                                  std::string* value_bytes) {
5034  TPM_RC result = TPM_RC_SUCCESS;
5035  VLOG(3) << __func__;
5036
5037  result = Parse_UINT16(buffer, &value->size, value_bytes);
5038  if (result) {
5039    return result;
5040  }
5041
5042  if (arraysize(value->buffer) < value->size) {
5043    return TPM_RC_INSUFFICIENT;
5044  }
5045  for (uint32_t i = 0; i < value->size; ++i) {
5046    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
5047    if (result) {
5048      return result;
5049    }
5050  }
5051  return result;
5052}
5053
5054TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA(const std::string& bytes) {
5055  TPM2B_SENSITIVE_DATA tpm2b;
5056  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
5057  memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA));
5058  tpm2b.size = bytes.size();
5059  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
5060  return tpm2b;
5061}
5062
5063std::string StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& tpm2b) {
5064  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
5065  return std::string(char_buffer, tpm2b.size);
5066}
5067
5068TPM_RC Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE& value,
5069                                       std::string* buffer) {
5070  TPM_RC result = TPM_RC_SUCCESS;
5071  VLOG(3) << __func__;
5072
5073  result = Serialize_TPM2B_AUTH(value.user_auth, buffer);
5074  if (result) {
5075    return result;
5076  }
5077
5078  result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer);
5079  if (result) {
5080    return result;
5081  }
5082  return result;
5083}
5084
5085TPM_RC Parse_TPMS_SENSITIVE_CREATE(std::string* buffer,
5086                                   TPMS_SENSITIVE_CREATE* value,
5087                                   std::string* value_bytes) {
5088  TPM_RC result = TPM_RC_SUCCESS;
5089  VLOG(3) << __func__;
5090
5091  result = Parse_TPM2B_AUTH(buffer, &value->user_auth, value_bytes);
5092  if (result) {
5093    return result;
5094  }
5095
5096  result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->data, value_bytes);
5097  if (result) {
5098    return result;
5099  }
5100  return result;
5101}
5102
5103TPM_RC Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE& value,
5104                                        std::string* buffer) {
5105  TPM_RC result = TPM_RC_SUCCESS;
5106  VLOG(3) << __func__;
5107
5108  std::string field_bytes;
5109  result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes);
5110  if (result) {
5111    return result;
5112  }
5113  std::string size_bytes;
5114  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
5115  if (result) {
5116    return result;
5117  }
5118  buffer->append(size_bytes + field_bytes);
5119  return result;
5120}
5121
5122TPM_RC Parse_TPM2B_SENSITIVE_CREATE(std::string* buffer,
5123                                    TPM2B_SENSITIVE_CREATE* value,
5124                                    std::string* value_bytes) {
5125  TPM_RC result = TPM_RC_SUCCESS;
5126  VLOG(3) << __func__;
5127
5128  result = Parse_UINT16(buffer, &value->size, value_bytes);
5129  if (result) {
5130    return result;
5131  }
5132
5133  result = Parse_TPMS_SENSITIVE_CREATE(buffer, &value->sensitive, value_bytes);
5134  if (result) {
5135    return result;
5136  }
5137  return result;
5138}
5139
5140TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE(
5141    const TPMS_SENSITIVE_CREATE& inner) {
5142  TPM2B_SENSITIVE_CREATE tpm2b;
5143  tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE);
5144  tpm2b.sensitive = inner;
5145  return tpm2b;
5146}
5147
5148TPM_RC Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR& value,
5149                                 std::string* buffer) {
5150  TPM_RC result = TPM_RC_SUCCESS;
5151  VLOG(3) << __func__;
5152
5153  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5154  if (result) {
5155    return result;
5156  }
5157
5158  result = Serialize_TPMI_ALG_KDF(value.kdf, buffer);
5159  if (result) {
5160    return result;
5161  }
5162  return result;
5163}
5164
5165TPM_RC Parse_TPMS_SCHEME_XOR(std::string* buffer,
5166                             TPMS_SCHEME_XOR* value,
5167                             std::string* value_bytes) {
5168  TPM_RC result = TPM_RC_SUCCESS;
5169  VLOG(3) << __func__;
5170
5171  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5172  if (result) {
5173    return result;
5174  }
5175
5176  result = Parse_TPMI_ALG_KDF(buffer, &value->kdf, value_bytes);
5177  if (result) {
5178    return result;
5179  }
5180  return result;
5181}
5182
5183TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH& value,
5184                                       TPMI_ALG_KEYEDHASH_SCHEME selector,
5185                                       std::string* buffer) {
5186  TPM_RC result = TPM_RC_SUCCESS;
5187  VLOG(3) << __func__;
5188
5189  if (selector == TPM_ALG_NULL) {
5190    // Do nothing.
5191  }
5192
5193  if (selector == TPM_ALG_HMAC) {
5194    result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5195    if (result) {
5196      return result;
5197    }
5198  }
5199
5200  if (selector == TPM_ALG_XOR) {
5201    result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer);
5202    if (result) {
5203      return result;
5204    }
5205  }
5206  return result;
5207}
5208
5209TPM_RC Parse_TPMU_SCHEME_KEYEDHASH(std::string* buffer,
5210                                   TPMI_ALG_KEYEDHASH_SCHEME selector,
5211                                   TPMU_SCHEME_KEYEDHASH* value,
5212                                   std::string* value_bytes) {
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 = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5222    if (result) {
5223      return result;
5224    }
5225  }
5226
5227  if (selector == TPM_ALG_XOR) {
5228    result = Parse_TPMS_SCHEME_XOR(buffer, &value->xor_, value_bytes);
5229    if (result) {
5230      return result;
5231    }
5232  }
5233  return result;
5234}
5235
5236TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME& value,
5237                                       std::string* buffer) {
5238  TPM_RC result = TPM_RC_SUCCESS;
5239  VLOG(3) << __func__;
5240
5241  result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer);
5242  if (result) {
5243    return result;
5244  }
5245
5246  result = Serialize_TPMU_SCHEME_KEYEDHASH(value.details, value.scheme, buffer);
5247  if (result) {
5248    return result;
5249  }
5250  return result;
5251}
5252
5253TPM_RC Parse_TPMT_KEYEDHASH_SCHEME(std::string* buffer,
5254                                   TPMT_KEYEDHASH_SCHEME* value,
5255                                   std::string* value_bytes) {
5256  TPM_RC result = TPM_RC_SUCCESS;
5257  VLOG(3) << __func__;
5258
5259  result = Parse_TPMI_ALG_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
5260  if (result) {
5261    return result;
5262  }
5263
5264  result = Parse_TPMU_SCHEME_KEYEDHASH(buffer, value->scheme, &value->details,
5265                                       value_bytes);
5266  if (result) {
5267    return result;
5268  }
5269  return result;
5270}
5271
5272TPM_RC Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA& value,
5273                                   std::string* buffer) {
5274  TPM_RC result = TPM_RC_SUCCESS;
5275  VLOG(3) << __func__;
5276
5277  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5278  if (result) {
5279    return result;
5280  }
5281
5282  result = Serialize_UINT16(value.count, buffer);
5283  if (result) {
5284    return result;
5285  }
5286  return result;
5287}
5288
5289TPM_RC Parse_TPMS_SCHEME_ECDAA(std::string* buffer,
5290                               TPMS_SCHEME_ECDAA* value,
5291                               std::string* value_bytes) {
5292  TPM_RC result = TPM_RC_SUCCESS;
5293  VLOG(3) << __func__;
5294
5295  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5296  if (result) {
5297    return result;
5298  }
5299
5300  result = Parse_UINT16(buffer, &value->count, value_bytes);
5301  if (result) {
5302    return result;
5303  }
5304  return result;
5305}
5306
5307TPM_RC Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME& value,
5308                                 TPMI_ALG_SIG_SCHEME selector,
5309                                 std::string* buffer) {
5310  TPM_RC result = TPM_RC_SUCCESS;
5311  VLOG(3) << __func__;
5312
5313  if (selector == TPM_ALG_HMAC) {
5314    result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5315    if (result) {
5316      return result;
5317    }
5318  }
5319
5320  if (selector == TPM_ALG_ECSCHNORR) {
5321    result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5322    if (result) {
5323      return result;
5324    }
5325  }
5326
5327  if (selector == TPM_ALG_RSAPSS) {
5328    result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5329    if (result) {
5330      return result;
5331    }
5332  }
5333
5334  if (selector == TPM_ALG_ECDAA) {
5335    result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5336    if (result) {
5337      return result;
5338    }
5339  }
5340
5341  if (selector == TPM_ALG_RSASSA) {
5342    result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5343    if (result) {
5344      return result;
5345    }
5346  }
5347
5348  if (selector == TPM_ALG_SM2) {
5349    result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5350    if (result) {
5351      return result;
5352    }
5353  }
5354
5355  if (selector == TPM_ALG_ECDSA) {
5356    result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5357    if (result) {
5358      return result;
5359    }
5360  }
5361
5362  if (selector == TPM_ALG_NULL) {
5363    // Do nothing.
5364  }
5365  return result;
5366}
5367
5368TPM_RC Parse_TPMU_SIG_SCHEME(std::string* buffer,
5369                             TPMI_ALG_SIG_SCHEME selector,
5370                             TPMU_SIG_SCHEME* value,
5371                             std::string* value_bytes) {
5372  TPM_RC result = TPM_RC_SUCCESS;
5373  VLOG(3) << __func__;
5374
5375  if (selector == TPM_ALG_HMAC) {
5376    result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5377    if (result) {
5378      return result;
5379    }
5380  }
5381
5382  if (selector == TPM_ALG_ECSCHNORR) {
5383    result =
5384        Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5385    if (result) {
5386      return result;
5387    }
5388  }
5389
5390  if (selector == TPM_ALG_RSAPSS) {
5391    result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5392    if (result) {
5393      return result;
5394    }
5395  }
5396
5397  if (selector == TPM_ALG_ECDAA) {
5398    result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5399    if (result) {
5400      return result;
5401    }
5402  }
5403
5404  if (selector == TPM_ALG_RSASSA) {
5405    result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5406    if (result) {
5407      return result;
5408    }
5409  }
5410
5411  if (selector == TPM_ALG_SM2) {
5412    result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5413    if (result) {
5414      return result;
5415    }
5416  }
5417
5418  if (selector == TPM_ALG_ECDSA) {
5419    result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5420    if (result) {
5421      return result;
5422    }
5423  }
5424
5425  if (selector == TPM_ALG_NULL) {
5426    // Do nothing.
5427  }
5428  return result;
5429}
5430
5431TPM_RC Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME& value,
5432                                 std::string* buffer) {
5433  TPM_RC result = TPM_RC_SUCCESS;
5434  VLOG(3) << __func__;
5435
5436  result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer);
5437  if (result) {
5438    return result;
5439  }
5440
5441  result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
5442  if (result) {
5443    return result;
5444  }
5445  return result;
5446}
5447
5448TPM_RC Parse_TPMT_SIG_SCHEME(std::string* buffer,
5449                             TPMT_SIG_SCHEME* value,
5450                             std::string* value_bytes) {
5451  TPM_RC result = TPM_RC_SUCCESS;
5452  VLOG(3) << __func__;
5453
5454  result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->scheme, value_bytes);
5455  if (result) {
5456    return result;
5457  }
5458
5459  result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
5460                                 value_bytes);
5461  if (result) {
5462    return result;
5463  }
5464  return result;
5465}
5466
5467TPM_RC Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP& value,
5468                                  std::string* buffer) {
5469  TPM_RC result = TPM_RC_SUCCESS;
5470  VLOG(3) << __func__;
5471
5472  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5473  if (result) {
5474    return result;
5475  }
5476  return result;
5477}
5478
5479TPM_RC Parse_TPMS_SCHEME_OAEP(std::string* buffer,
5480                              TPMS_SCHEME_OAEP* value,
5481                              std::string* value_bytes) {
5482  TPM_RC result = TPM_RC_SUCCESS;
5483  VLOG(3) << __func__;
5484
5485  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5486  if (result) {
5487    return result;
5488  }
5489  return result;
5490}
5491
5492TPM_RC Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH& value,
5493                                  std::string* buffer) {
5494  TPM_RC result = TPM_RC_SUCCESS;
5495  VLOG(3) << __func__;
5496
5497  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5498  if (result) {
5499    return result;
5500  }
5501  return result;
5502}
5503
5504TPM_RC Parse_TPMS_SCHEME_ECDH(std::string* buffer,
5505                              TPMS_SCHEME_ECDH* value,
5506                              std::string* value_bytes) {
5507  TPM_RC result = TPM_RC_SUCCESS;
5508  VLOG(3) << __func__;
5509
5510  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5511  if (result) {
5512    return result;
5513  }
5514  return result;
5515}
5516
5517TPM_RC Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1& value,
5518                                  std::string* buffer) {
5519  TPM_RC result = TPM_RC_SUCCESS;
5520  VLOG(3) << __func__;
5521
5522  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5523  if (result) {
5524    return result;
5525  }
5526  return result;
5527}
5528
5529TPM_RC Parse_TPMS_SCHEME_MGF1(std::string* buffer,
5530                              TPMS_SCHEME_MGF1* value,
5531                              std::string* value_bytes) {
5532  TPM_RC result = TPM_RC_SUCCESS;
5533  VLOG(3) << __func__;
5534
5535  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5536  if (result) {
5537    return result;
5538  }
5539  return result;
5540}
5541
5542TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a(
5543    const TPMS_SCHEME_KDF1_SP800_56a& value,
5544    std::string* buffer) {
5545  TPM_RC result = TPM_RC_SUCCESS;
5546  VLOG(3) << __func__;
5547
5548  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5549  if (result) {
5550    return result;
5551  }
5552  return result;
5553}
5554
5555TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string* buffer,
5556                                        TPMS_SCHEME_KDF1_SP800_56a* value,
5557                                        std::string* value_bytes) {
5558  TPM_RC result = TPM_RC_SUCCESS;
5559  VLOG(3) << __func__;
5560
5561  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5562  if (result) {
5563    return result;
5564  }
5565  return result;
5566}
5567
5568TPM_RC Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2& value,
5569                                  std::string* buffer) {
5570  TPM_RC result = TPM_RC_SUCCESS;
5571  VLOG(3) << __func__;
5572
5573  result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5574  if (result) {
5575    return result;
5576  }
5577  return result;
5578}
5579
5580TPM_RC Parse_TPMS_SCHEME_KDF2(std::string* buffer,
5581                              TPMS_SCHEME_KDF2* value,
5582                              std::string* value_bytes) {
5583  TPM_RC result = TPM_RC_SUCCESS;
5584  VLOG(3) << __func__;
5585
5586  result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5587  if (result) {
5588    return result;
5589  }
5590  return result;
5591}
5592
5593TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108(
5594    const TPMS_SCHEME_KDF1_SP800_108& 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
5606TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108(std::string* buffer,
5607                                        TPMS_SCHEME_KDF1_SP800_108* 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
5619TPM_RC Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME& value,
5620                                 TPMI_ALG_KDF selector,
5621                                 std::string* buffer) {
5622  TPM_RC result = TPM_RC_SUCCESS;
5623  VLOG(3) << __func__;
5624
5625  if (selector == TPM_ALG_KDF1_SP800_56a) {
5626    result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer);
5627    if (result) {
5628      return result;
5629    }
5630  }
5631
5632  if (selector == TPM_ALG_MGF1) {
5633    result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer);
5634    if (result) {
5635      return result;
5636    }
5637  }
5638
5639  if (selector == TPM_ALG_KDF1_SP800_108) {
5640    result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer);
5641    if (result) {
5642      return result;
5643    }
5644  }
5645
5646  if (selector == TPM_ALG_KDF2) {
5647    result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer);
5648    if (result) {
5649      return result;
5650    }
5651  }
5652
5653  if (selector == TPM_ALG_NULL) {
5654    // Do nothing.
5655  }
5656  return result;
5657}
5658
5659TPM_RC Parse_TPMU_KDF_SCHEME(std::string* buffer,
5660                             TPMI_ALG_KDF selector,
5661                             TPMU_KDF_SCHEME* value,
5662                             std::string* value_bytes) {
5663  TPM_RC result = TPM_RC_SUCCESS;
5664  VLOG(3) << __func__;
5665
5666  if (selector == TPM_ALG_KDF1_SP800_56a) {
5667    result = Parse_TPMS_SCHEME_KDF1_SP800_56a(buffer, &value->kdf1_sp800_56a,
5668                                              value_bytes);
5669    if (result) {
5670      return result;
5671    }
5672  }
5673
5674  if (selector == TPM_ALG_MGF1) {
5675    result = Parse_TPMS_SCHEME_MGF1(buffer, &value->mgf1, value_bytes);
5676    if (result) {
5677      return result;
5678    }
5679  }
5680
5681  if (selector == TPM_ALG_KDF1_SP800_108) {
5682    result = Parse_TPMS_SCHEME_KDF1_SP800_108(buffer, &value->kdf1_sp800_108,
5683                                              value_bytes);
5684    if (result) {
5685      return result;
5686    }
5687  }
5688
5689  if (selector == TPM_ALG_KDF2) {
5690    result = Parse_TPMS_SCHEME_KDF2(buffer, &value->kdf2, value_bytes);
5691    if (result) {
5692      return result;
5693    }
5694  }
5695
5696  if (selector == TPM_ALG_NULL) {
5697    // Do nothing.
5698  }
5699  return result;
5700}
5701
5702TPM_RC Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME& value,
5703                                 std::string* buffer) {
5704  TPM_RC result = TPM_RC_SUCCESS;
5705  VLOG(3) << __func__;
5706
5707  result = Serialize_TPMI_ALG_KDF(value.scheme, buffer);
5708  if (result) {
5709    return result;
5710  }
5711
5712  result = Serialize_TPMU_KDF_SCHEME(value.details, value.scheme, buffer);
5713  if (result) {
5714    return result;
5715  }
5716  return result;
5717}
5718
5719TPM_RC Parse_TPMT_KDF_SCHEME(std::string* buffer,
5720                             TPMT_KDF_SCHEME* value,
5721                             std::string* value_bytes) {
5722  TPM_RC result = TPM_RC_SUCCESS;
5723  VLOG(3) << __func__;
5724
5725  result = Parse_TPMI_ALG_KDF(buffer, &value->scheme, value_bytes);
5726  if (result) {
5727    return result;
5728  }
5729
5730  result = Parse_TPMU_KDF_SCHEME(buffer, value->scheme, &value->details,
5731                                 value_bytes);
5732  if (result) {
5733    return result;
5734  }
5735  return result;
5736}
5737
5738TPM_RC Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME& value,
5739                                  TPMI_ALG_ASYM_SCHEME selector,
5740                                  std::string* buffer) {
5741  TPM_RC result = TPM_RC_SUCCESS;
5742  VLOG(3) << __func__;
5743
5744  if (selector == TPM_ALG_RSAES) {
5745    // Do nothing.
5746  }
5747
5748  if (selector == TPM_ALG_ECSCHNORR) {
5749    result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5750    if (result) {
5751      return result;
5752    }
5753  }
5754
5755  if (selector == TPM_ALG_NULL) {
5756    // Do nothing.
5757  }
5758
5759  if (selector == TPM_ALG_ECDH) {
5760    result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer);
5761    if (result) {
5762      return result;
5763    }
5764  }
5765
5766  if (selector == TPM_ALG_OAEP) {
5767    result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer);
5768    if (result) {
5769      return result;
5770    }
5771  }
5772
5773  if (selector == TPM_ALG_RSAPSS) {
5774    result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5775    if (result) {
5776      return result;
5777    }
5778  }
5779
5780  if (selector == TPM_ALG_ECDAA) {
5781    result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5782    if (result) {
5783      return result;
5784    }
5785  }
5786
5787  if (selector == TPM_ALG_RSASSA) {
5788    result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5789    if (result) {
5790      return result;
5791    }
5792  }
5793
5794  if (selector == TPM_ALG_SM2) {
5795    result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5796    if (result) {
5797      return result;
5798    }
5799  }
5800
5801  if (selector == TPM_ALG_ECDSA) {
5802    result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5803    if (result) {
5804      return result;
5805    }
5806  }
5807  return result;
5808}
5809
5810TPM_RC Parse_TPMU_ASYM_SCHEME(std::string* buffer,
5811                              TPMI_ALG_ASYM_SCHEME selector,
5812                              TPMU_ASYM_SCHEME* value,
5813                              std::string* value_bytes) {
5814  TPM_RC result = TPM_RC_SUCCESS;
5815  VLOG(3) << __func__;
5816
5817  if (selector == TPM_ALG_RSAES) {
5818    // Do nothing.
5819  }
5820
5821  if (selector == TPM_ALG_ECSCHNORR) {
5822    result =
5823        Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5824    if (result) {
5825      return result;
5826    }
5827  }
5828
5829  if (selector == TPM_ALG_NULL) {
5830    // Do nothing.
5831  }
5832
5833  if (selector == TPM_ALG_ECDH) {
5834    result = Parse_TPMS_SCHEME_ECDH(buffer, &value->ecdh, value_bytes);
5835    if (result) {
5836      return result;
5837    }
5838  }
5839
5840  if (selector == TPM_ALG_OAEP) {
5841    result = Parse_TPMS_SCHEME_OAEP(buffer, &value->oaep, value_bytes);
5842    if (result) {
5843      return result;
5844    }
5845  }
5846
5847  if (selector == TPM_ALG_RSAPSS) {
5848    result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5849    if (result) {
5850      return result;
5851    }
5852  }
5853
5854  if (selector == TPM_ALG_ECDAA) {
5855    result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5856    if (result) {
5857      return result;
5858    }
5859  }
5860
5861  if (selector == TPM_ALG_RSASSA) {
5862    result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5863    if (result) {
5864      return result;
5865    }
5866  }
5867
5868  if (selector == TPM_ALG_SM2) {
5869    result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5870    if (result) {
5871      return result;
5872    }
5873  }
5874
5875  if (selector == TPM_ALG_ECDSA) {
5876    result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5877    if (result) {
5878      return result;
5879    }
5880  }
5881  return result;
5882}
5883
5884TPM_RC Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME& value,
5885                                  std::string* buffer) {
5886  TPM_RC result = TPM_RC_SUCCESS;
5887  VLOG(3) << __func__;
5888
5889  result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer);
5890  if (result) {
5891    return result;
5892  }
5893
5894  result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5895  if (result) {
5896    return result;
5897  }
5898  return result;
5899}
5900
5901TPM_RC Parse_TPMT_ASYM_SCHEME(std::string* buffer,
5902                              TPMT_ASYM_SCHEME* value,
5903                              std::string* value_bytes) {
5904  TPM_RC result = TPM_RC_SUCCESS;
5905  VLOG(3) << __func__;
5906
5907  result = Parse_TPMI_ALG_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
5908  if (result) {
5909    return result;
5910  }
5911
5912  result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5913                                  value_bytes);
5914  if (result) {
5915    return result;
5916  }
5917  return result;
5918}
5919
5920TPM_RC Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME& value,
5921                                 std::string* buffer) {
5922  TPM_RC result = TPM_RC_SUCCESS;
5923  VLOG(3) << __func__;
5924
5925  result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer);
5926  if (result) {
5927    return result;
5928  }
5929
5930  result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5931  if (result) {
5932    return result;
5933  }
5934  return result;
5935}
5936
5937TPM_RC Parse_TPMT_RSA_SCHEME(std::string* buffer,
5938                             TPMT_RSA_SCHEME* value,
5939                             std::string* value_bytes) {
5940  TPM_RC result = TPM_RC_SUCCESS;
5941  VLOG(3) << __func__;
5942
5943  result = Parse_TPMI_ALG_RSA_SCHEME(buffer, &value->scheme, value_bytes);
5944  if (result) {
5945    return result;
5946  }
5947
5948  result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5949                                  value_bytes);
5950  if (result) {
5951    return result;
5952  }
5953  return result;
5954}
5955
5956TPM_RC Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT& value,
5957                                  std::string* buffer) {
5958  TPM_RC result = TPM_RC_SUCCESS;
5959  VLOG(3) << __func__;
5960
5961  result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer);
5962  if (result) {
5963    return result;
5964  }
5965
5966  result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5967  if (result) {
5968    return result;
5969  }
5970  return result;
5971}
5972
5973TPM_RC Parse_TPMT_RSA_DECRYPT(std::string* buffer,
5974                              TPMT_RSA_DECRYPT* value,
5975                              std::string* value_bytes) {
5976  TPM_RC result = TPM_RC_SUCCESS;
5977  VLOG(3) << __func__;
5978
5979  result = Parse_TPMI_ALG_RSA_DECRYPT(buffer, &value->scheme, value_bytes);
5980  if (result) {
5981    return result;
5982  }
5983
5984  result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5985                                  value_bytes);
5986  if (result) {
5987    return result;
5988  }
5989  return result;
5990}
5991
5992TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& value,
5993                                      std::string* buffer) {
5994  TPM_RC result = TPM_RC_SUCCESS;
5995  VLOG(3) << __func__;
5996
5997  result = Serialize_UINT16(value.size, buffer);
5998  if (result) {
5999    return result;
6000  }
6001
6002  if (arraysize(value.buffer) < value.size) {
6003    return TPM_RC_INSUFFICIENT;
6004  }
6005  for (uint32_t i = 0; i < value.size; ++i) {
6006    result = Serialize_BYTE(value.buffer[i], buffer);
6007    if (result) {
6008      return result;
6009    }
6010  }
6011  return result;
6012}
6013
6014TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA(std::string* buffer,
6015                                  TPM2B_PUBLIC_KEY_RSA* value,
6016                                  std::string* value_bytes) {
6017  TPM_RC result = TPM_RC_SUCCESS;
6018  VLOG(3) << __func__;
6019
6020  result = Parse_UINT16(buffer, &value->size, value_bytes);
6021  if (result) {
6022    return result;
6023  }
6024
6025  if (arraysize(value->buffer) < value->size) {
6026    return TPM_RC_INSUFFICIENT;
6027  }
6028  for (uint32_t i = 0; i < value->size; ++i) {
6029    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6030    if (result) {
6031      return result;
6032    }
6033  }
6034  return result;
6035}
6036
6037TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA(const std::string& bytes) {
6038  TPM2B_PUBLIC_KEY_RSA tpm2b;
6039  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6040  memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA));
6041  tpm2b.size = bytes.size();
6042  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6043  return tpm2b;
6044}
6045
6046std::string StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& tpm2b) {
6047  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6048  return std::string(char_buffer, tpm2b.size);
6049}
6050
6051TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA& value,
6052                                       std::string* buffer) {
6053  TPM_RC result = TPM_RC_SUCCESS;
6054  VLOG(3) << __func__;
6055
6056  result = Serialize_UINT16(value.size, buffer);
6057  if (result) {
6058    return result;
6059  }
6060
6061  if (arraysize(value.buffer) < value.size) {
6062    return TPM_RC_INSUFFICIENT;
6063  }
6064  for (uint32_t i = 0; i < value.size; ++i) {
6065    result = Serialize_BYTE(value.buffer[i], buffer);
6066    if (result) {
6067      return result;
6068    }
6069  }
6070  return result;
6071}
6072
6073TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA(std::string* buffer,
6074                                   TPM2B_PRIVATE_KEY_RSA* value,
6075                                   std::string* value_bytes) {
6076  TPM_RC result = TPM_RC_SUCCESS;
6077  VLOG(3) << __func__;
6078
6079  result = Parse_UINT16(buffer, &value->size, value_bytes);
6080  if (result) {
6081    return result;
6082  }
6083
6084  if (arraysize(value->buffer) < value->size) {
6085    return TPM_RC_INSUFFICIENT;
6086  }
6087  for (uint32_t i = 0; i < value->size; ++i) {
6088    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6089    if (result) {
6090      return result;
6091    }
6092  }
6093  return result;
6094}
6095
6096TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA(const std::string& bytes) {
6097  TPM2B_PRIVATE_KEY_RSA tpm2b;
6098  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6099  memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA));
6100  tpm2b.size = bytes.size();
6101  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6102  return tpm2b;
6103}
6104
6105std::string StringFrom_TPM2B_PRIVATE_KEY_RSA(
6106    const TPM2B_PRIVATE_KEY_RSA& tpm2b) {
6107  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6108  return std::string(char_buffer, tpm2b.size);
6109}
6110
6111TPM_RC Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& value,
6112                                     std::string* buffer) {
6113  TPM_RC result = TPM_RC_SUCCESS;
6114  VLOG(3) << __func__;
6115
6116  result = Serialize_UINT16(value.size, buffer);
6117  if (result) {
6118    return result;
6119  }
6120
6121  if (arraysize(value.buffer) < value.size) {
6122    return TPM_RC_INSUFFICIENT;
6123  }
6124  for (uint32_t i = 0; i < value.size; ++i) {
6125    result = Serialize_BYTE(value.buffer[i], buffer);
6126    if (result) {
6127      return result;
6128    }
6129  }
6130  return result;
6131}
6132
6133TPM_RC Parse_TPM2B_ECC_PARAMETER(std::string* buffer,
6134                                 TPM2B_ECC_PARAMETER* value,
6135                                 std::string* value_bytes) {
6136  TPM_RC result = TPM_RC_SUCCESS;
6137  VLOG(3) << __func__;
6138
6139  result = Parse_UINT16(buffer, &value->size, value_bytes);
6140  if (result) {
6141    return result;
6142  }
6143
6144  if (arraysize(value->buffer) < value->size) {
6145    return TPM_RC_INSUFFICIENT;
6146  }
6147  for (uint32_t i = 0; i < value->size; ++i) {
6148    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6149    if (result) {
6150      return result;
6151    }
6152  }
6153  return result;
6154}
6155
6156TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER(const std::string& bytes) {
6157  TPM2B_ECC_PARAMETER tpm2b;
6158  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6159  memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER));
6160  tpm2b.size = bytes.size();
6161  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6162  return tpm2b;
6163}
6164
6165std::string StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& tpm2b) {
6166  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6167  return std::string(char_buffer, tpm2b.size);
6168}
6169
6170TPM_RC Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT& value,
6171                                std::string* buffer) {
6172  TPM_RC result = TPM_RC_SUCCESS;
6173  VLOG(3) << __func__;
6174
6175  result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer);
6176  if (result) {
6177    return result;
6178  }
6179
6180  result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer);
6181  if (result) {
6182    return result;
6183  }
6184  return result;
6185}
6186
6187TPM_RC Parse_TPMS_ECC_POINT(std::string* buffer,
6188                            TPMS_ECC_POINT* value,
6189                            std::string* value_bytes) {
6190  TPM_RC result = TPM_RC_SUCCESS;
6191  VLOG(3) << __func__;
6192
6193  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->x, value_bytes);
6194  if (result) {
6195    return result;
6196  }
6197
6198  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->y, value_bytes);
6199  if (result) {
6200    return result;
6201  }
6202  return result;
6203}
6204
6205TPM_RC Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT& value,
6206                                 std::string* buffer) {
6207  TPM_RC result = TPM_RC_SUCCESS;
6208  VLOG(3) << __func__;
6209
6210  std::string field_bytes;
6211  result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes);
6212  if (result) {
6213    return result;
6214  }
6215  std::string size_bytes;
6216  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
6217  if (result) {
6218    return result;
6219  }
6220  buffer->append(size_bytes + field_bytes);
6221  return result;
6222}
6223
6224TPM_RC Parse_TPM2B_ECC_POINT(std::string* buffer,
6225                             TPM2B_ECC_POINT* value,
6226                             std::string* value_bytes) {
6227  TPM_RC result = TPM_RC_SUCCESS;
6228  VLOG(3) << __func__;
6229
6230  result = Parse_UINT16(buffer, &value->size, value_bytes);
6231  if (result) {
6232    return result;
6233  }
6234
6235  result = Parse_TPMS_ECC_POINT(buffer, &value->point, value_bytes);
6236  if (result) {
6237    return result;
6238  }
6239  return result;
6240}
6241
6242TPM2B_ECC_POINT Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT& inner) {
6243  TPM2B_ECC_POINT tpm2b;
6244  tpm2b.size = sizeof(TPMS_ECC_POINT);
6245  tpm2b.point = inner;
6246  return tpm2b;
6247}
6248
6249TPM_RC Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME& value,
6250                                 std::string* buffer) {
6251  TPM_RC result = TPM_RC_SUCCESS;
6252  VLOG(3) << __func__;
6253
6254  result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer);
6255  if (result) {
6256    return result;
6257  }
6258
6259  result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
6260  if (result) {
6261    return result;
6262  }
6263  return result;
6264}
6265
6266TPM_RC Parse_TPMT_ECC_SCHEME(std::string* buffer,
6267                             TPMT_ECC_SCHEME* value,
6268                             std::string* value_bytes) {
6269  TPM_RC result = TPM_RC_SUCCESS;
6270  VLOG(3) << __func__;
6271
6272  result = Parse_TPMI_ALG_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6273  if (result) {
6274    return result;
6275  }
6276
6277  result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
6278                                 value_bytes);
6279  if (result) {
6280    return result;
6281  }
6282  return result;
6283}
6284
6285TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC(
6286    const TPMS_ALGORITHM_DETAIL_ECC& value,
6287    std::string* buffer) {
6288  TPM_RC result = TPM_RC_SUCCESS;
6289  VLOG(3) << __func__;
6290
6291  result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer);
6292  if (result) {
6293    return result;
6294  }
6295
6296  result = Serialize_UINT16(value.key_size, buffer);
6297  if (result) {
6298    return result;
6299  }
6300
6301  result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6302  if (result) {
6303    return result;
6304  }
6305
6306  result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer);
6307  if (result) {
6308    return result;
6309  }
6310
6311  result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer);
6312  if (result) {
6313    return result;
6314  }
6315
6316  result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer);
6317  if (result) {
6318    return result;
6319  }
6320
6321  result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer);
6322  if (result) {
6323    return result;
6324  }
6325
6326  result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer);
6327  if (result) {
6328    return result;
6329  }
6330
6331  result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer);
6332  if (result) {
6333    return result;
6334  }
6335
6336  result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer);
6337  if (result) {
6338    return result;
6339  }
6340
6341  result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer);
6342  if (result) {
6343    return result;
6344  }
6345  return result;
6346}
6347
6348TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string* buffer,
6349                                       TPMS_ALGORITHM_DETAIL_ECC* value,
6350                                       std::string* value_bytes) {
6351  TPM_RC result = TPM_RC_SUCCESS;
6352  VLOG(3) << __func__;
6353
6354  result = Parse_TPM_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6355  if (result) {
6356    return result;
6357  }
6358
6359  result = Parse_UINT16(buffer, &value->key_size, value_bytes);
6360  if (result) {
6361    return result;
6362  }
6363
6364  result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6365  if (result) {
6366    return result;
6367  }
6368
6369  result = Parse_TPMT_ECC_SCHEME(buffer, &value->sign, value_bytes);
6370  if (result) {
6371    return result;
6372  }
6373
6374  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->p, value_bytes);
6375  if (result) {
6376    return result;
6377  }
6378
6379  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->a, value_bytes);
6380  if (result) {
6381    return result;
6382  }
6383
6384  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->b, value_bytes);
6385  if (result) {
6386    return result;
6387  }
6388
6389  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_x, value_bytes);
6390  if (result) {
6391    return result;
6392  }
6393
6394  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_y, value_bytes);
6395  if (result) {
6396    return result;
6397  }
6398
6399  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->n, value_bytes);
6400  if (result) {
6401    return result;
6402  }
6403
6404  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->h, value_bytes);
6405  if (result) {
6406    return result;
6407  }
6408  return result;
6409}
6410
6411TPM_RC Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA& value,
6412                                       std::string* buffer) {
6413  TPM_RC result = TPM_RC_SUCCESS;
6414  VLOG(3) << __func__;
6415
6416  result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6417  if (result) {
6418    return result;
6419  }
6420
6421  result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6422  if (result) {
6423    return result;
6424  }
6425  return result;
6426}
6427
6428TPM_RC Parse_TPMS_SIGNATURE_RSASSA(std::string* buffer,
6429                                   TPMS_SIGNATURE_RSASSA* value,
6430                                   std::string* value_bytes) {
6431  TPM_RC result = TPM_RC_SUCCESS;
6432  VLOG(3) << __func__;
6433
6434  result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6435  if (result) {
6436    return result;
6437  }
6438
6439  result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6440  if (result) {
6441    return result;
6442  }
6443  return result;
6444}
6445
6446TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS& value,
6447                                       std::string* buffer) {
6448  TPM_RC result = TPM_RC_SUCCESS;
6449  VLOG(3) << __func__;
6450
6451  result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6452  if (result) {
6453    return result;
6454  }
6455
6456  result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6457  if (result) {
6458    return result;
6459  }
6460  return result;
6461}
6462
6463TPM_RC Parse_TPMS_SIGNATURE_RSAPSS(std::string* buffer,
6464                                   TPMS_SIGNATURE_RSAPSS* value,
6465                                   std::string* value_bytes) {
6466  TPM_RC result = TPM_RC_SUCCESS;
6467  VLOG(3) << __func__;
6468
6469  result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6470  if (result) {
6471    return result;
6472  }
6473
6474  result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6475  if (result) {
6476    return result;
6477  }
6478  return result;
6479}
6480
6481TPM_RC Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA& value,
6482                                      std::string* buffer) {
6483  TPM_RC result = TPM_RC_SUCCESS;
6484  VLOG(3) << __func__;
6485
6486  result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6487  if (result) {
6488    return result;
6489  }
6490
6491  result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer);
6492  if (result) {
6493    return result;
6494  }
6495
6496  result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer);
6497  if (result) {
6498    return result;
6499  }
6500  return result;
6501}
6502
6503TPM_RC Parse_TPMS_SIGNATURE_ECDSA(std::string* buffer,
6504                                  TPMS_SIGNATURE_ECDSA* value,
6505                                  std::string* value_bytes) {
6506  TPM_RC result = TPM_RC_SUCCESS;
6507  VLOG(3) << __func__;
6508
6509  result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6510  if (result) {
6511    return result;
6512  }
6513
6514  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_r, value_bytes);
6515  if (result) {
6516    return result;
6517  }
6518
6519  result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_s, value_bytes);
6520  if (result) {
6521    return result;
6522  }
6523  return result;
6524}
6525
6526TPM_RC Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE& value,
6527                                TPMI_ALG_SIG_SCHEME selector,
6528                                std::string* buffer) {
6529  TPM_RC result = TPM_RC_SUCCESS;
6530  VLOG(3) << __func__;
6531
6532  if (selector == TPM_ALG_HMAC) {
6533    result = Serialize_TPMT_HA(value.hmac, buffer);
6534    if (result) {
6535      return result;
6536    }
6537  }
6538
6539  if (selector == TPM_ALG_ECSCHNORR) {
6540    result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer);
6541    if (result) {
6542      return result;
6543    }
6544  }
6545
6546  if (selector == TPM_ALG_RSAPSS) {
6547    result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer);
6548    if (result) {
6549      return result;
6550    }
6551  }
6552
6553  if (selector == TPM_ALG_ECDAA) {
6554    result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer);
6555    if (result) {
6556      return result;
6557    }
6558  }
6559
6560  if (selector == TPM_ALG_RSASSA) {
6561    result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer);
6562    if (result) {
6563      return result;
6564    }
6565  }
6566
6567  if (selector == TPM_ALG_SM2) {
6568    result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer);
6569    if (result) {
6570      return result;
6571    }
6572  }
6573
6574  if (selector == TPM_ALG_ECDSA) {
6575    result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer);
6576    if (result) {
6577      return result;
6578    }
6579  }
6580
6581  if (selector == TPM_ALG_NULL) {
6582    // Do nothing.
6583  }
6584  return result;
6585}
6586
6587TPM_RC Parse_TPMU_SIGNATURE(std::string* buffer,
6588                            TPMI_ALG_SIG_SCHEME selector,
6589                            TPMU_SIGNATURE* value,
6590                            std::string* value_bytes) {
6591  TPM_RC result = TPM_RC_SUCCESS;
6592  VLOG(3) << __func__;
6593
6594  if (selector == TPM_ALG_HMAC) {
6595    result = Parse_TPMT_HA(buffer, &value->hmac, value_bytes);
6596    if (result) {
6597      return result;
6598    }
6599  }
6600
6601  if (selector == TPM_ALG_ECSCHNORR) {
6602    result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecschnorr, value_bytes);
6603    if (result) {
6604      return result;
6605    }
6606  }
6607
6608  if (selector == TPM_ALG_RSAPSS) {
6609    result = Parse_TPMS_SIGNATURE_RSAPSS(buffer, &value->rsapss, value_bytes);
6610    if (result) {
6611      return result;
6612    }
6613  }
6614
6615  if (selector == TPM_ALG_ECDAA) {
6616    result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdaa, value_bytes);
6617    if (result) {
6618      return result;
6619    }
6620  }
6621
6622  if (selector == TPM_ALG_RSASSA) {
6623    result = Parse_TPMS_SIGNATURE_RSASSA(buffer, &value->rsassa, value_bytes);
6624    if (result) {
6625      return result;
6626    }
6627  }
6628
6629  if (selector == TPM_ALG_SM2) {
6630    result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->sm2, value_bytes);
6631    if (result) {
6632      return result;
6633    }
6634  }
6635
6636  if (selector == TPM_ALG_ECDSA) {
6637    result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdsa, value_bytes);
6638    if (result) {
6639      return result;
6640    }
6641  }
6642
6643  if (selector == TPM_ALG_NULL) {
6644    // Do nothing.
6645  }
6646  return result;
6647}
6648
6649TPM_RC Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE& value,
6650                                std::string* buffer) {
6651  TPM_RC result = TPM_RC_SUCCESS;
6652  VLOG(3) << __func__;
6653
6654  result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer);
6655  if (result) {
6656    return result;
6657  }
6658
6659  result = Serialize_TPMU_SIGNATURE(value.signature, value.sig_alg, buffer);
6660  if (result) {
6661    return result;
6662  }
6663  return result;
6664}
6665
6666TPM_RC Parse_TPMT_SIGNATURE(std::string* buffer,
6667                            TPMT_SIGNATURE* value,
6668                            std::string* value_bytes) {
6669  TPM_RC result = TPM_RC_SUCCESS;
6670  VLOG(3) << __func__;
6671
6672  result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->sig_alg, value_bytes);
6673  if (result) {
6674    return result;
6675  }
6676
6677  result = Parse_TPMU_SIGNATURE(buffer, value->sig_alg, &value->signature,
6678                                value_bytes);
6679  if (result) {
6680    return result;
6681  }
6682  return result;
6683}
6684
6685TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET& value,
6686                                        std::string* buffer) {
6687  TPM_RC result = TPM_RC_SUCCESS;
6688  VLOG(3) << __func__;
6689
6690  result = Serialize_UINT16(value.size, buffer);
6691  if (result) {
6692    return result;
6693  }
6694
6695  if (arraysize(value.secret) < value.size) {
6696    return TPM_RC_INSUFFICIENT;
6697  }
6698  for (uint32_t i = 0; i < value.size; ++i) {
6699    result = Serialize_BYTE(value.secret[i], buffer);
6700    if (result) {
6701      return result;
6702    }
6703  }
6704  return result;
6705}
6706
6707TPM_RC Parse_TPM2B_ENCRYPTED_SECRET(std::string* buffer,
6708                                    TPM2B_ENCRYPTED_SECRET* value,
6709                                    std::string* value_bytes) {
6710  TPM_RC result = TPM_RC_SUCCESS;
6711  VLOG(3) << __func__;
6712
6713  result = Parse_UINT16(buffer, &value->size, value_bytes);
6714  if (result) {
6715    return result;
6716  }
6717
6718  if (arraysize(value->secret) < value->size) {
6719    return TPM_RC_INSUFFICIENT;
6720  }
6721  for (uint32_t i = 0; i < value->size; ++i) {
6722    result = Parse_BYTE(buffer, &value->secret[i], value_bytes);
6723    if (result) {
6724      return result;
6725    }
6726  }
6727  return result;
6728}
6729
6730TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET(const std::string& bytes) {
6731  TPM2B_ENCRYPTED_SECRET tpm2b;
6732  CHECK(bytes.size() <= sizeof(tpm2b.secret));
6733  memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
6734  tpm2b.size = bytes.size();
6735  memcpy(tpm2b.secret, bytes.data(), bytes.size());
6736  return tpm2b;
6737}
6738
6739std::string StringFrom_TPM2B_ENCRYPTED_SECRET(
6740    const TPM2B_ENCRYPTED_SECRET& tpm2b) {
6741  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.secret);
6742  return std::string(char_buffer, tpm2b.size);
6743}
6744
6745TPM_RC Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS& value,
6746                                      std::string* buffer) {
6747  TPM_RC result = TPM_RC_SUCCESS;
6748  VLOG(3) << __func__;
6749
6750  result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer);
6751  if (result) {
6752    return result;
6753  }
6754  return result;
6755}
6756
6757TPM_RC Parse_TPMS_KEYEDHASH_PARMS(std::string* buffer,
6758                                  TPMS_KEYEDHASH_PARMS* value,
6759                                  std::string* value_bytes) {
6760  TPM_RC result = TPM_RC_SUCCESS;
6761  VLOG(3) << __func__;
6762
6763  result = Parse_TPMT_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
6764  if (result) {
6765    return result;
6766  }
6767  return result;
6768}
6769
6770TPM_RC Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS& value,
6771                                 std::string* buffer) {
6772  TPM_RC result = TPM_RC_SUCCESS;
6773  VLOG(3) << __func__;
6774
6775  result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6776  if (result) {
6777    return result;
6778  }
6779
6780  result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer);
6781  if (result) {
6782    return result;
6783  }
6784  return result;
6785}
6786
6787TPM_RC Parse_TPMS_ASYM_PARMS(std::string* buffer,
6788                             TPMS_ASYM_PARMS* value,
6789                             std::string* value_bytes) {
6790  TPM_RC result = TPM_RC_SUCCESS;
6791  VLOG(3) << __func__;
6792
6793  result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6794  if (result) {
6795    return result;
6796  }
6797
6798  result = Parse_TPMT_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
6799  if (result) {
6800    return result;
6801  }
6802  return result;
6803}
6804
6805TPM_RC Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS& value,
6806                                std::string* buffer) {
6807  TPM_RC result = TPM_RC_SUCCESS;
6808  VLOG(3) << __func__;
6809
6810  result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6811  if (result) {
6812    return result;
6813  }
6814
6815  result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer);
6816  if (result) {
6817    return result;
6818  }
6819
6820  result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer);
6821  if (result) {
6822    return result;
6823  }
6824
6825  result = Serialize_UINT32(value.exponent, buffer);
6826  if (result) {
6827    return result;
6828  }
6829  return result;
6830}
6831
6832TPM_RC Parse_TPMS_RSA_PARMS(std::string* buffer,
6833                            TPMS_RSA_PARMS* value,
6834                            std::string* value_bytes) {
6835  TPM_RC result = TPM_RC_SUCCESS;
6836  VLOG(3) << __func__;
6837
6838  result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6839  if (result) {
6840    return result;
6841  }
6842
6843  result = Parse_TPMT_RSA_SCHEME(buffer, &value->scheme, value_bytes);
6844  if (result) {
6845    return result;
6846  }
6847
6848  result = Parse_TPMI_RSA_KEY_BITS(buffer, &value->key_bits, value_bytes);
6849  if (result) {
6850    return result;
6851  }
6852
6853  result = Parse_UINT32(buffer, &value->exponent, value_bytes);
6854  if (result) {
6855    return result;
6856  }
6857  return result;
6858}
6859
6860TPM_RC Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS& value,
6861                                std::string* buffer) {
6862  TPM_RC result = TPM_RC_SUCCESS;
6863  VLOG(3) << __func__;
6864
6865  result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6866  if (result) {
6867    return result;
6868  }
6869
6870  result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer);
6871  if (result) {
6872    return result;
6873  }
6874
6875  result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer);
6876  if (result) {
6877    return result;
6878  }
6879
6880  result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6881  if (result) {
6882    return result;
6883  }
6884  return result;
6885}
6886
6887TPM_RC Parse_TPMS_ECC_PARMS(std::string* buffer,
6888                            TPMS_ECC_PARMS* value,
6889                            std::string* value_bytes) {
6890  TPM_RC result = TPM_RC_SUCCESS;
6891  VLOG(3) << __func__;
6892
6893  result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6894  if (result) {
6895    return result;
6896  }
6897
6898  result = Parse_TPMT_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6899  if (result) {
6900    return result;
6901  }
6902
6903  result = Parse_TPMI_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6904  if (result) {
6905    return result;
6906  }
6907
6908  result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6909  if (result) {
6910    return result;
6911  }
6912  return result;
6913}
6914
6915TPM_RC Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS& value,
6916                                   TPMI_ALG_PUBLIC selector,
6917                                   std::string* buffer) {
6918  TPM_RC result = TPM_RC_SUCCESS;
6919  VLOG(3) << __func__;
6920
6921  if (selector == TPM_ALG_KEYEDHASH) {
6922    result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer);
6923    if (result) {
6924      return result;
6925    }
6926  }
6927
6928  if (selector == TPM_ALG_RSA) {
6929    result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer);
6930    if (result) {
6931      return result;
6932    }
6933  }
6934
6935  if (selector == TPM_ALG_SYMCIPHER) {
6936    result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer);
6937    if (result) {
6938      return result;
6939    }
6940  }
6941
6942  if (selector == TPM_ALG_ECC) {
6943    result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer);
6944    if (result) {
6945      return result;
6946    }
6947  }
6948  return result;
6949}
6950
6951TPM_RC Parse_TPMU_PUBLIC_PARMS(std::string* buffer,
6952                               TPMI_ALG_PUBLIC selector,
6953                               TPMU_PUBLIC_PARMS* value,
6954                               std::string* value_bytes) {
6955  TPM_RC result = TPM_RC_SUCCESS;
6956  VLOG(3) << __func__;
6957
6958  if (selector == TPM_ALG_KEYEDHASH) {
6959    result = Parse_TPMS_KEYEDHASH_PARMS(buffer, &value->keyed_hash_detail,
6960                                        value_bytes);
6961    if (result) {
6962      return result;
6963    }
6964  }
6965
6966  if (selector == TPM_ALG_RSA) {
6967    result = Parse_TPMS_RSA_PARMS(buffer, &value->rsa_detail, value_bytes);
6968    if (result) {
6969      return result;
6970    }
6971  }
6972
6973  if (selector == TPM_ALG_SYMCIPHER) {
6974    result =
6975        Parse_TPMS_SYMCIPHER_PARMS(buffer, &value->sym_detail, value_bytes);
6976    if (result) {
6977      return result;
6978    }
6979  }
6980
6981  if (selector == TPM_ALG_ECC) {
6982    result = Parse_TPMS_ECC_PARMS(buffer, &value->ecc_detail, value_bytes);
6983    if (result) {
6984      return result;
6985    }
6986  }
6987  return result;
6988}
6989
6990TPM_RC Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS& value,
6991                                   std::string* buffer) {
6992  TPM_RC result = TPM_RC_SUCCESS;
6993  VLOG(3) << __func__;
6994
6995  result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
6996  if (result) {
6997    return result;
6998  }
6999
7000  result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7001  if (result) {
7002    return result;
7003  }
7004  return result;
7005}
7006
7007TPM_RC Parse_TPMT_PUBLIC_PARMS(std::string* buffer,
7008                               TPMT_PUBLIC_PARMS* value,
7009                               std::string* value_bytes) {
7010  TPM_RC result = TPM_RC_SUCCESS;
7011  VLOG(3) << __func__;
7012
7013  result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7014  if (result) {
7015    return result;
7016  }
7017
7018  result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7019                                   value_bytes);
7020  if (result) {
7021    return result;
7022  }
7023  return result;
7024}
7025
7026TPM_RC Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID& value,
7027                                TPMI_ALG_PUBLIC selector,
7028                                std::string* buffer) {
7029  TPM_RC result = TPM_RC_SUCCESS;
7030  VLOG(3) << __func__;
7031
7032  if (selector == TPM_ALG_KEYEDHASH) {
7033    result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer);
7034    if (result) {
7035      return result;
7036    }
7037  }
7038
7039  if (selector == TPM_ALG_RSA) {
7040    result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer);
7041    if (result) {
7042      return result;
7043    }
7044  }
7045
7046  if (selector == TPM_ALG_SYMCIPHER) {
7047    result = Serialize_TPM2B_DIGEST(value.sym, buffer);
7048    if (result) {
7049      return result;
7050    }
7051  }
7052
7053  if (selector == TPM_ALG_ECC) {
7054    result = Serialize_TPMS_ECC_POINT(value.ecc, buffer);
7055    if (result) {
7056      return result;
7057    }
7058  }
7059  return result;
7060}
7061
7062TPM_RC Parse_TPMU_PUBLIC_ID(std::string* buffer,
7063                            TPMI_ALG_PUBLIC selector,
7064                            TPMU_PUBLIC_ID* value,
7065                            std::string* value_bytes) {
7066  TPM_RC result = TPM_RC_SUCCESS;
7067  VLOG(3) << __func__;
7068
7069  if (selector == TPM_ALG_KEYEDHASH) {
7070    result = Parse_TPM2B_DIGEST(buffer, &value->keyed_hash, value_bytes);
7071    if (result) {
7072      return result;
7073    }
7074  }
7075
7076  if (selector == TPM_ALG_RSA) {
7077    result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->rsa, value_bytes);
7078    if (result) {
7079      return result;
7080    }
7081  }
7082
7083  if (selector == TPM_ALG_SYMCIPHER) {
7084    result = Parse_TPM2B_DIGEST(buffer, &value->sym, value_bytes);
7085    if (result) {
7086      return result;
7087    }
7088  }
7089
7090  if (selector == TPM_ALG_ECC) {
7091    result = Parse_TPMS_ECC_POINT(buffer, &value->ecc, value_bytes);
7092    if (result) {
7093      return result;
7094    }
7095  }
7096  return result;
7097}
7098
7099TPM_RC Serialize_TPMT_PUBLIC(const TPMT_PUBLIC& value, std::string* buffer) {
7100  TPM_RC result = TPM_RC_SUCCESS;
7101  VLOG(3) << __func__;
7102
7103  result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7104  if (result) {
7105    return result;
7106  }
7107
7108  result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7109  if (result) {
7110    return result;
7111  }
7112
7113  result = Serialize_TPMA_OBJECT(value.object_attributes, buffer);
7114  if (result) {
7115    return result;
7116  }
7117
7118  result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7119  if (result) {
7120    return result;
7121  }
7122
7123  result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7124  if (result) {
7125    return result;
7126  }
7127
7128  result = Serialize_TPMU_PUBLIC_ID(value.unique, value.type, buffer);
7129  if (result) {
7130    return result;
7131  }
7132  return result;
7133}
7134
7135TPM_RC Parse_TPMT_PUBLIC(std::string* buffer,
7136                         TPMT_PUBLIC* value,
7137                         std::string* value_bytes) {
7138  TPM_RC result = TPM_RC_SUCCESS;
7139  VLOG(3) << __func__;
7140
7141  result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7142  if (result) {
7143    return result;
7144  }
7145
7146  result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7147  if (result) {
7148    return result;
7149  }
7150
7151  result = Parse_TPMA_OBJECT(buffer, &value->object_attributes, value_bytes);
7152  if (result) {
7153    return result;
7154  }
7155
7156  result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7157  if (result) {
7158    return result;
7159  }
7160
7161  result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7162                                   value_bytes);
7163  if (result) {
7164    return result;
7165  }
7166
7167  result =
7168      Parse_TPMU_PUBLIC_ID(buffer, value->type, &value->unique, value_bytes);
7169  if (result) {
7170    return result;
7171  }
7172  return result;
7173}
7174
7175TPM_RC Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC& value, std::string* buffer) {
7176  TPM_RC result = TPM_RC_SUCCESS;
7177  VLOG(3) << __func__;
7178
7179  std::string field_bytes;
7180  result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes);
7181  if (result) {
7182    return result;
7183  }
7184  std::string size_bytes;
7185  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7186  if (result) {
7187    return result;
7188  }
7189  buffer->append(size_bytes + field_bytes);
7190  return result;
7191}
7192
7193TPM_RC Parse_TPM2B_PUBLIC(std::string* buffer,
7194                          TPM2B_PUBLIC* value,
7195                          std::string* value_bytes) {
7196  TPM_RC result = TPM_RC_SUCCESS;
7197  VLOG(3) << __func__;
7198
7199  result = Parse_UINT16(buffer, &value->size, value_bytes);
7200  if (result) {
7201    return result;
7202  }
7203
7204  result = Parse_TPMT_PUBLIC(buffer, &value->public_area, value_bytes);
7205  if (result) {
7206    return result;
7207  }
7208  return result;
7209}
7210
7211TPM2B_PUBLIC Make_TPM2B_PUBLIC(const TPMT_PUBLIC& inner) {
7212  TPM2B_PUBLIC tpm2b;
7213  tpm2b.size = sizeof(TPMT_PUBLIC);
7214  tpm2b.public_area = inner;
7215  return tpm2b;
7216}
7217
7218TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7219    const TPM2B_PRIVATE_VENDOR_SPECIFIC& value,
7220    std::string* buffer) {
7221  TPM_RC result = TPM_RC_SUCCESS;
7222  VLOG(3) << __func__;
7223
7224  result = Serialize_UINT16(value.size, buffer);
7225  if (result) {
7226    return result;
7227  }
7228
7229  if (arraysize(value.buffer) < value.size) {
7230    return TPM_RC_INSUFFICIENT;
7231  }
7232  for (uint32_t i = 0; i < value.size; ++i) {
7233    result = Serialize_BYTE(value.buffer[i], buffer);
7234    if (result) {
7235      return result;
7236    }
7237  }
7238  return result;
7239}
7240
7241TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string* buffer,
7242                                           TPM2B_PRIVATE_VENDOR_SPECIFIC* value,
7243                                           std::string* value_bytes) {
7244  TPM_RC result = TPM_RC_SUCCESS;
7245  VLOG(3) << __func__;
7246
7247  result = Parse_UINT16(buffer, &value->size, value_bytes);
7248  if (result) {
7249    return result;
7250  }
7251
7252  if (arraysize(value->buffer) < value->size) {
7253    return TPM_RC_INSUFFICIENT;
7254  }
7255  for (uint32_t i = 0; i < value->size; ++i) {
7256    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7257    if (result) {
7258      return result;
7259    }
7260  }
7261  return result;
7262}
7263
7264TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7265    const std::string& bytes) {
7266  TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b;
7267  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7268  memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC));
7269  tpm2b.size = bytes.size();
7270  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7271  return tpm2b;
7272}
7273
7274std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7275    const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) {
7276  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7277  return std::string(char_buffer, tpm2b.size);
7278}
7279
7280TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE& value,
7281                                          TPMI_ALG_PUBLIC selector,
7282                                          std::string* buffer) {
7283  TPM_RC result = TPM_RC_SUCCESS;
7284  VLOG(3) << __func__;
7285
7286  if (selector == TPM_ALG_KEYEDHASH) {
7287    result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer);
7288    if (result) {
7289      return result;
7290    }
7291  }
7292
7293  if (selector == TPM_ALG_RSA) {
7294    result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer);
7295    if (result) {
7296      return result;
7297    }
7298  }
7299
7300  if (selector == TPM_ALG_SYMCIPHER) {
7301    result = Serialize_TPM2B_SYM_KEY(value.sym, buffer);
7302    if (result) {
7303      return result;
7304    }
7305  }
7306
7307  if (selector == TPM_ALG_ECC) {
7308    result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer);
7309    if (result) {
7310      return result;
7311    }
7312  }
7313  return result;
7314}
7315
7316TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE(std::string* buffer,
7317                                      TPMI_ALG_PUBLIC selector,
7318                                      TPMU_SENSITIVE_COMPOSITE* value,
7319                                      std::string* value_bytes) {
7320  TPM_RC result = TPM_RC_SUCCESS;
7321  VLOG(3) << __func__;
7322
7323  if (selector == TPM_ALG_KEYEDHASH) {
7324    result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->bits, value_bytes);
7325    if (result) {
7326      return result;
7327    }
7328  }
7329
7330  if (selector == TPM_ALG_RSA) {
7331    result = Parse_TPM2B_PRIVATE_KEY_RSA(buffer, &value->rsa, value_bytes);
7332    if (result) {
7333      return result;
7334    }
7335  }
7336
7337  if (selector == TPM_ALG_SYMCIPHER) {
7338    result = Parse_TPM2B_SYM_KEY(buffer, &value->sym, value_bytes);
7339    if (result) {
7340      return result;
7341    }
7342  }
7343
7344  if (selector == TPM_ALG_ECC) {
7345    result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->ecc, value_bytes);
7346    if (result) {
7347      return result;
7348    }
7349  }
7350  return result;
7351}
7352
7353TPM_RC Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE& value,
7354                                std::string* buffer) {
7355  TPM_RC result = TPM_RC_SUCCESS;
7356  VLOG(3) << __func__;
7357
7358  result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer);
7359  if (result) {
7360    return result;
7361  }
7362
7363  result = Serialize_TPM2B_AUTH(value.auth_value, buffer);
7364  if (result) {
7365    return result;
7366  }
7367
7368  result = Serialize_TPM2B_DIGEST(value.seed_value, buffer);
7369  if (result) {
7370    return result;
7371  }
7372
7373  result = Serialize_TPMU_SENSITIVE_COMPOSITE(value.sensitive,
7374                                              value.sensitive_type, buffer);
7375  if (result) {
7376    return result;
7377  }
7378  return result;
7379}
7380
7381TPM_RC Parse_TPMT_SENSITIVE(std::string* buffer,
7382                            TPMT_SENSITIVE* value,
7383                            std::string* value_bytes) {
7384  TPM_RC result = TPM_RC_SUCCESS;
7385  VLOG(3) << __func__;
7386
7387  result = Parse_TPMI_ALG_PUBLIC(buffer, &value->sensitive_type, value_bytes);
7388  if (result) {
7389    return result;
7390  }
7391
7392  result = Parse_TPM2B_AUTH(buffer, &value->auth_value, value_bytes);
7393  if (result) {
7394    return result;
7395  }
7396
7397  result = Parse_TPM2B_DIGEST(buffer, &value->seed_value, value_bytes);
7398  if (result) {
7399    return result;
7400  }
7401
7402  result = Parse_TPMU_SENSITIVE_COMPOSITE(buffer, value->sensitive_type,
7403                                          &value->sensitive, value_bytes);
7404  if (result) {
7405    return result;
7406  }
7407  return result;
7408}
7409
7410TPM_RC Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE& value,
7411                                 std::string* buffer) {
7412  TPM_RC result = TPM_RC_SUCCESS;
7413  VLOG(3) << __func__;
7414
7415  std::string field_bytes;
7416  result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes);
7417  if (result) {
7418    return result;
7419  }
7420  std::string size_bytes;
7421  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7422  if (result) {
7423    return result;
7424  }
7425  buffer->append(size_bytes + field_bytes);
7426  return result;
7427}
7428
7429TPM_RC Parse_TPM2B_SENSITIVE(std::string* buffer,
7430                             TPM2B_SENSITIVE* value,
7431                             std::string* value_bytes) {
7432  TPM_RC result = TPM_RC_SUCCESS;
7433  VLOG(3) << __func__;
7434
7435  result = Parse_UINT16(buffer, &value->size, value_bytes);
7436  if (result) {
7437    return result;
7438  }
7439
7440  result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive_area, value_bytes);
7441  if (result) {
7442    return result;
7443  }
7444  return result;
7445}
7446
7447TPM2B_SENSITIVE Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE& inner) {
7448  TPM2B_SENSITIVE tpm2b;
7449  tpm2b.size = sizeof(TPMT_SENSITIVE);
7450  tpm2b.sensitive_area = inner;
7451  return tpm2b;
7452}
7453
7454TPM_RC Serialize__PRIVATE(const _PRIVATE& value, std::string* buffer) {
7455  TPM_RC result = TPM_RC_SUCCESS;
7456  VLOG(3) << __func__;
7457
7458  result = Serialize_TPM2B_DIGEST(value.integrity_outer, buffer);
7459  if (result) {
7460    return result;
7461  }
7462
7463  result = Serialize_TPM2B_DIGEST(value.integrity_inner, buffer);
7464  if (result) {
7465    return result;
7466  }
7467
7468  result = Serialize_TPMT_SENSITIVE(value.sensitive, buffer);
7469  if (result) {
7470    return result;
7471  }
7472  return result;
7473}
7474
7475TPM_RC Parse__PRIVATE(std::string* buffer,
7476                      _PRIVATE* value,
7477                      std::string* value_bytes) {
7478  TPM_RC result = TPM_RC_SUCCESS;
7479  VLOG(3) << __func__;
7480
7481  result = Parse_TPM2B_DIGEST(buffer, &value->integrity_outer, value_bytes);
7482  if (result) {
7483    return result;
7484  }
7485
7486  result = Parse_TPM2B_DIGEST(buffer, &value->integrity_inner, value_bytes);
7487  if (result) {
7488    return result;
7489  }
7490
7491  result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive, value_bytes);
7492  if (result) {
7493    return result;
7494  }
7495  return result;
7496}
7497
7498TPM_RC Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE& value,
7499                               std::string* buffer) {
7500  TPM_RC result = TPM_RC_SUCCESS;
7501  VLOG(3) << __func__;
7502
7503  result = Serialize_UINT16(value.size, buffer);
7504  if (result) {
7505    return result;
7506  }
7507
7508  if (arraysize(value.buffer) < value.size) {
7509    return TPM_RC_INSUFFICIENT;
7510  }
7511  for (uint32_t i = 0; i < value.size; ++i) {
7512    result = Serialize_BYTE(value.buffer[i], buffer);
7513    if (result) {
7514      return result;
7515    }
7516  }
7517  return result;
7518}
7519
7520TPM_RC Parse_TPM2B_PRIVATE(std::string* buffer,
7521                           TPM2B_PRIVATE* value,
7522                           std::string* value_bytes) {
7523  TPM_RC result = TPM_RC_SUCCESS;
7524  VLOG(3) << __func__;
7525
7526  result = Parse_UINT16(buffer, &value->size, value_bytes);
7527  if (result) {
7528    return result;
7529  }
7530
7531  if (arraysize(value->buffer) < value->size) {
7532    return TPM_RC_INSUFFICIENT;
7533  }
7534  for (uint32_t i = 0; i < value->size; ++i) {
7535    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7536    if (result) {
7537      return result;
7538    }
7539  }
7540  return result;
7541}
7542
7543TPM2B_PRIVATE Make_TPM2B_PRIVATE(const std::string& bytes) {
7544  TPM2B_PRIVATE tpm2b;
7545  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7546  memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE));
7547  tpm2b.size = bytes.size();
7548  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7549  return tpm2b;
7550}
7551
7552std::string StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE& tpm2b) {
7553  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7554  return std::string(char_buffer, tpm2b.size);
7555}
7556
7557TPM_RC Serialize__ID_OBJECT(const _ID_OBJECT& value, std::string* buffer) {
7558  TPM_RC result = TPM_RC_SUCCESS;
7559  VLOG(3) << __func__;
7560
7561  result = Serialize_TPM2B_DIGEST(value.integrity_hmac, buffer);
7562  if (result) {
7563    return result;
7564  }
7565
7566  result = Serialize_TPM2B_DIGEST(value.enc_identity, buffer);
7567  if (result) {
7568    return result;
7569  }
7570  return result;
7571}
7572
7573TPM_RC Parse__ID_OBJECT(std::string* buffer,
7574                        _ID_OBJECT* value,
7575                        std::string* value_bytes) {
7576  TPM_RC result = TPM_RC_SUCCESS;
7577  VLOG(3) << __func__;
7578
7579  result = Parse_TPM2B_DIGEST(buffer, &value->integrity_hmac, value_bytes);
7580  if (result) {
7581    return result;
7582  }
7583
7584  result = Parse_TPM2B_DIGEST(buffer, &value->enc_identity, value_bytes);
7585  if (result) {
7586    return result;
7587  }
7588  return result;
7589}
7590
7591TPM_RC Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& value,
7592                                 std::string* buffer) {
7593  TPM_RC result = TPM_RC_SUCCESS;
7594  VLOG(3) << __func__;
7595
7596  result = Serialize_UINT16(value.size, buffer);
7597  if (result) {
7598    return result;
7599  }
7600
7601  if (arraysize(value.credential) < value.size) {
7602    return TPM_RC_INSUFFICIENT;
7603  }
7604  for (uint32_t i = 0; i < value.size; ++i) {
7605    result = Serialize_BYTE(value.credential[i], buffer);
7606    if (result) {
7607      return result;
7608    }
7609  }
7610  return result;
7611}
7612
7613TPM_RC Parse_TPM2B_ID_OBJECT(std::string* buffer,
7614                             TPM2B_ID_OBJECT* value,
7615                             std::string* value_bytes) {
7616  TPM_RC result = TPM_RC_SUCCESS;
7617  VLOG(3) << __func__;
7618
7619  result = Parse_UINT16(buffer, &value->size, value_bytes);
7620  if (result) {
7621    return result;
7622  }
7623
7624  if (arraysize(value->credential) < value->size) {
7625    return TPM_RC_INSUFFICIENT;
7626  }
7627  for (uint32_t i = 0; i < value->size; ++i) {
7628    result = Parse_BYTE(buffer, &value->credential[i], value_bytes);
7629    if (result) {
7630      return result;
7631    }
7632  }
7633  return result;
7634}
7635
7636TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT(const std::string& bytes) {
7637  TPM2B_ID_OBJECT tpm2b;
7638  CHECK(bytes.size() <= sizeof(tpm2b.credential));
7639  memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT));
7640  tpm2b.size = bytes.size();
7641  memcpy(tpm2b.credential, bytes.data(), bytes.size());
7642  return tpm2b;
7643}
7644
7645std::string StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& tpm2b) {
7646  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.credential);
7647  return std::string(char_buffer, tpm2b.size);
7648}
7649
7650TPM_RC Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC& value,
7651                                std::string* buffer) {
7652  TPM_RC result = TPM_RC_SUCCESS;
7653  VLOG(3) << __func__;
7654
7655  result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer);
7656  if (result) {
7657    return result;
7658  }
7659
7660  result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7661  if (result) {
7662    return result;
7663  }
7664
7665  result = Serialize_TPMA_NV(value.attributes, buffer);
7666  if (result) {
7667    return result;
7668  }
7669
7670  result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7671  if (result) {
7672    return result;
7673  }
7674
7675  result = Serialize_UINT16(value.data_size, buffer);
7676  if (result) {
7677    return result;
7678  }
7679  return result;
7680}
7681
7682TPM_RC Parse_TPMS_NV_PUBLIC(std::string* buffer,
7683                            TPMS_NV_PUBLIC* value,
7684                            std::string* value_bytes) {
7685  TPM_RC result = TPM_RC_SUCCESS;
7686  VLOG(3) << __func__;
7687
7688  result = Parse_TPMI_RH_NV_INDEX(buffer, &value->nv_index, value_bytes);
7689  if (result) {
7690    return result;
7691  }
7692
7693  result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7694  if (result) {
7695    return result;
7696  }
7697
7698  result = Parse_TPMA_NV(buffer, &value->attributes, value_bytes);
7699  if (result) {
7700    return result;
7701  }
7702
7703  result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7704  if (result) {
7705    return result;
7706  }
7707
7708  result = Parse_UINT16(buffer, &value->data_size, value_bytes);
7709  if (result) {
7710    return result;
7711  }
7712  return result;
7713}
7714
7715TPM_RC Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC& value,
7716                                 std::string* buffer) {
7717  TPM_RC result = TPM_RC_SUCCESS;
7718  VLOG(3) << __func__;
7719
7720  std::string field_bytes;
7721  result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes);
7722  if (result) {
7723    return result;
7724  }
7725  std::string size_bytes;
7726  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7727  if (result) {
7728    return result;
7729  }
7730  buffer->append(size_bytes + field_bytes);
7731  return result;
7732}
7733
7734TPM_RC Parse_TPM2B_NV_PUBLIC(std::string* buffer,
7735                             TPM2B_NV_PUBLIC* value,
7736                             std::string* value_bytes) {
7737  TPM_RC result = TPM_RC_SUCCESS;
7738  VLOG(3) << __func__;
7739
7740  result = Parse_UINT16(buffer, &value->size, value_bytes);
7741  if (result) {
7742    return result;
7743  }
7744
7745  result = Parse_TPMS_NV_PUBLIC(buffer, &value->nv_public, value_bytes);
7746  if (result) {
7747    return result;
7748  }
7749  return result;
7750}
7751
7752TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC& inner) {
7753  TPM2B_NV_PUBLIC tpm2b;
7754  tpm2b.size = sizeof(TPMS_NV_PUBLIC);
7755  tpm2b.nv_public = inner;
7756  return tpm2b;
7757}
7758
7759TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE& value,
7760                                         std::string* buffer) {
7761  TPM_RC result = TPM_RC_SUCCESS;
7762  VLOG(3) << __func__;
7763
7764  result = Serialize_UINT16(value.size, buffer);
7765  if (result) {
7766    return result;
7767  }
7768
7769  if (arraysize(value.buffer) < value.size) {
7770    return TPM_RC_INSUFFICIENT;
7771  }
7772  for (uint32_t i = 0; i < value.size; ++i) {
7773    result = Serialize_BYTE(value.buffer[i], buffer);
7774    if (result) {
7775      return result;
7776    }
7777  }
7778  return result;
7779}
7780
7781TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE(std::string* buffer,
7782                                     TPM2B_CONTEXT_SENSITIVE* value,
7783                                     std::string* value_bytes) {
7784  TPM_RC result = TPM_RC_SUCCESS;
7785  VLOG(3) << __func__;
7786
7787  result = Parse_UINT16(buffer, &value->size, value_bytes);
7788  if (result) {
7789    return result;
7790  }
7791
7792  if (arraysize(value->buffer) < value->size) {
7793    return TPM_RC_INSUFFICIENT;
7794  }
7795  for (uint32_t i = 0; i < value->size; ++i) {
7796    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7797    if (result) {
7798      return result;
7799    }
7800  }
7801  return result;
7802}
7803
7804TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE(const std::string& bytes) {
7805  TPM2B_CONTEXT_SENSITIVE tpm2b;
7806  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7807  memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE));
7808  tpm2b.size = bytes.size();
7809  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7810  return tpm2b;
7811}
7812
7813std::string StringFrom_TPM2B_CONTEXT_SENSITIVE(
7814    const TPM2B_CONTEXT_SENSITIVE& tpm2b) {
7815  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7816  return std::string(char_buffer, tpm2b.size);
7817}
7818
7819TPM_RC Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA& value,
7820                                   std::string* buffer) {
7821  TPM_RC result = TPM_RC_SUCCESS;
7822  VLOG(3) << __func__;
7823
7824  result = Serialize_TPM2B_DIGEST(value.integrity, buffer);
7825  if (result) {
7826    return result;
7827  }
7828
7829  result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer);
7830  if (result) {
7831    return result;
7832  }
7833  return result;
7834}
7835
7836TPM_RC Parse_TPMS_CONTEXT_DATA(std::string* buffer,
7837                               TPMS_CONTEXT_DATA* value,
7838                               std::string* value_bytes) {
7839  TPM_RC result = TPM_RC_SUCCESS;
7840  VLOG(3) << __func__;
7841
7842  result = Parse_TPM2B_DIGEST(buffer, &value->integrity, value_bytes);
7843  if (result) {
7844    return result;
7845  }
7846
7847  result =
7848      Parse_TPM2B_CONTEXT_SENSITIVE(buffer, &value->encrypted, value_bytes);
7849  if (result) {
7850    return result;
7851  }
7852  return result;
7853}
7854
7855TPM_RC Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& value,
7856                                    std::string* buffer) {
7857  TPM_RC result = TPM_RC_SUCCESS;
7858  VLOG(3) << __func__;
7859
7860  result = Serialize_UINT16(value.size, buffer);
7861  if (result) {
7862    return result;
7863  }
7864
7865  if (arraysize(value.buffer) < value.size) {
7866    return TPM_RC_INSUFFICIENT;
7867  }
7868  for (uint32_t i = 0; i < value.size; ++i) {
7869    result = Serialize_BYTE(value.buffer[i], buffer);
7870    if (result) {
7871      return result;
7872    }
7873  }
7874  return result;
7875}
7876
7877TPM_RC Parse_TPM2B_CONTEXT_DATA(std::string* buffer,
7878                                TPM2B_CONTEXT_DATA* value,
7879                                std::string* value_bytes) {
7880  TPM_RC result = TPM_RC_SUCCESS;
7881  VLOG(3) << __func__;
7882
7883  result = Parse_UINT16(buffer, &value->size, value_bytes);
7884  if (result) {
7885    return result;
7886  }
7887
7888  if (arraysize(value->buffer) < value->size) {
7889    return TPM_RC_INSUFFICIENT;
7890  }
7891  for (uint32_t i = 0; i < value->size; ++i) {
7892    result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7893    if (result) {
7894      return result;
7895    }
7896  }
7897  return result;
7898}
7899
7900TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA(const std::string& bytes) {
7901  TPM2B_CONTEXT_DATA tpm2b;
7902  CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7903  memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA));
7904  tpm2b.size = bytes.size();
7905  memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7906  return tpm2b;
7907}
7908
7909std::string StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& tpm2b) {
7910  const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7911  return std::string(char_buffer, tpm2b.size);
7912}
7913
7914TPM_RC Serialize_TPMS_CONTEXT(const TPMS_CONTEXT& value, std::string* buffer) {
7915  TPM_RC result = TPM_RC_SUCCESS;
7916  VLOG(3) << __func__;
7917
7918  result = Serialize_UINT64(value.sequence, buffer);
7919  if (result) {
7920    return result;
7921  }
7922
7923  result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer);
7924  if (result) {
7925    return result;
7926  }
7927
7928  result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
7929  if (result) {
7930    return result;
7931  }
7932
7933  result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer);
7934  if (result) {
7935    return result;
7936  }
7937  return result;
7938}
7939
7940TPM_RC Parse_TPMS_CONTEXT(std::string* buffer,
7941                          TPMS_CONTEXT* value,
7942                          std::string* value_bytes) {
7943  TPM_RC result = TPM_RC_SUCCESS;
7944  VLOG(3) << __func__;
7945
7946  result = Parse_UINT64(buffer, &value->sequence, value_bytes);
7947  if (result) {
7948    return result;
7949  }
7950
7951  result = Parse_TPMI_DH_CONTEXT(buffer, &value->saved_handle, value_bytes);
7952  if (result) {
7953    return result;
7954  }
7955
7956  result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
7957  if (result) {
7958    return result;
7959  }
7960
7961  result = Parse_TPM2B_CONTEXT_DATA(buffer, &value->context_blob, value_bytes);
7962  if (result) {
7963    return result;
7964  }
7965  return result;
7966}
7967
7968TPM_RC Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA& value,
7969                                    std::string* buffer) {
7970  TPM_RC result = TPM_RC_SUCCESS;
7971  VLOG(3) << __func__;
7972
7973  result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
7974  if (result) {
7975    return result;
7976  }
7977
7978  result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
7979  if (result) {
7980    return result;
7981  }
7982
7983  result = Serialize_TPMA_LOCALITY(value.locality, buffer);
7984  if (result) {
7985    return result;
7986  }
7987
7988  result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer);
7989  if (result) {
7990    return result;
7991  }
7992
7993  result = Serialize_TPM2B_NAME(value.parent_name, buffer);
7994  if (result) {
7995    return result;
7996  }
7997
7998  result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer);
7999  if (result) {
8000    return result;
8001  }
8002
8003  result = Serialize_TPM2B_DATA(value.outside_info, buffer);
8004  if (result) {
8005    return result;
8006  }
8007  return result;
8008}
8009
8010TPM_RC Parse_TPMS_CREATION_DATA(std::string* buffer,
8011                                TPMS_CREATION_DATA* value,
8012                                std::string* value_bytes) {
8013  TPM_RC result = TPM_RC_SUCCESS;
8014  VLOG(3) << __func__;
8015
8016  result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
8017  if (result) {
8018    return result;
8019  }
8020
8021  result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
8022  if (result) {
8023    return result;
8024  }
8025
8026  result = Parse_TPMA_LOCALITY(buffer, &value->locality, value_bytes);
8027  if (result) {
8028    return result;
8029  }
8030
8031  result = Parse_TPM_ALG_ID(buffer, &value->parent_name_alg, value_bytes);
8032  if (result) {
8033    return result;
8034  }
8035
8036  result = Parse_TPM2B_NAME(buffer, &value->parent_name, value_bytes);
8037  if (result) {
8038    return result;
8039  }
8040
8041  result = Parse_TPM2B_NAME(buffer, &value->parent_qualified_name, value_bytes);
8042  if (result) {
8043    return result;
8044  }
8045
8046  result = Parse_TPM2B_DATA(buffer, &value->outside_info, value_bytes);
8047  if (result) {
8048    return result;
8049  }
8050  return result;
8051}
8052
8053TPM_RC Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA& value,
8054                                     std::string* buffer) {
8055  TPM_RC result = TPM_RC_SUCCESS;
8056  VLOG(3) << __func__;
8057
8058  std::string field_bytes;
8059  result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes);
8060  if (result) {
8061    return result;
8062  }
8063  std::string size_bytes;
8064  result = Serialize_UINT16(field_bytes.size(), &size_bytes);
8065  if (result) {
8066    return result;
8067  }
8068  buffer->append(size_bytes + field_bytes);
8069  return result;
8070}
8071
8072TPM_RC Parse_TPM2B_CREATION_DATA(std::string* buffer,
8073                                 TPM2B_CREATION_DATA* value,
8074                                 std::string* value_bytes) {
8075  TPM_RC result = TPM_RC_SUCCESS;
8076  VLOG(3) << __func__;
8077
8078  result = Parse_UINT16(buffer, &value->size, value_bytes);
8079  if (result) {
8080    return result;
8081  }
8082
8083  result = Parse_TPMS_CREATION_DATA(buffer, &value->creation_data, value_bytes);
8084  if (result) {
8085    return result;
8086  }
8087  return result;
8088}
8089
8090TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA& inner) {
8091  TPM2B_CREATION_DATA tpm2b;
8092  tpm2b.size = sizeof(TPMS_CREATION_DATA);
8093  tpm2b.creation_data = inner;
8094  return tpm2b;
8095}
8096
8097TPM_RC Tpm::SerializeCommand_Startup(
8098    const TPM_SU& startup_type,
8099    std::string* serialized_command,
8100    AuthorizationDelegate* authorization_delegate) {
8101  VLOG(3) << __func__;
8102  TPM_RC rc = TPM_RC_SUCCESS;
8103  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8104  UINT32 command_size = 10;  // Header size.
8105  std::string handle_section_bytes;
8106  std::string parameter_section_bytes;
8107  TPM_CC command_code = TPM_CC_Startup;
8108  bool is_command_parameter_encryption_possible = false;
8109  bool is_response_parameter_encryption_possible = false;
8110  std::string command_code_bytes;
8111  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8112  if (rc != TPM_RC_SUCCESS) {
8113    return rc;
8114  }
8115  std::string startup_type_bytes;
8116  rc = Serialize_TPM_SU(startup_type, &startup_type_bytes);
8117  if (rc != TPM_RC_SUCCESS) {
8118    return rc;
8119  }
8120  std::unique_ptr<crypto::SecureHash> hash(
8121      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8122  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8123  hash->Update(startup_type_bytes.data(), startup_type_bytes.size());
8124  parameter_section_bytes += startup_type_bytes;
8125  command_size += startup_type_bytes.size();
8126  std::string command_hash(32, 0);
8127  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
8128  std::string authorization_section_bytes;
8129  std::string authorization_size_bytes;
8130  if (authorization_delegate) {
8131    if (!authorization_delegate->GetCommandAuthorization(
8132            command_hash, is_command_parameter_encryption_possible,
8133            is_response_parameter_encryption_possible,
8134            &authorization_section_bytes)) {
8135      return TRUNKS_RC_AUTHORIZATION_FAILED;
8136    }
8137    if (!authorization_section_bytes.empty()) {
8138      tag = TPM_ST_SESSIONS;
8139      std::string tmp;
8140      rc = Serialize_UINT32(authorization_section_bytes.size(),
8141                            &authorization_size_bytes);
8142      if (rc != TPM_RC_SUCCESS) {
8143        return rc;
8144      }
8145      command_size +=
8146          authorization_size_bytes.size() + authorization_section_bytes.size();
8147    }
8148  }
8149  std::string tag_bytes;
8150  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8151  if (rc != TPM_RC_SUCCESS) {
8152    return rc;
8153  }
8154  std::string command_size_bytes;
8155  rc = Serialize_UINT32(command_size, &command_size_bytes);
8156  if (rc != TPM_RC_SUCCESS) {
8157    return rc;
8158  }
8159  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8160                        handle_section_bytes + authorization_size_bytes +
8161                        authorization_section_bytes + parameter_section_bytes;
8162  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8163  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
8164                                            serialized_command->size());
8165  return TPM_RC_SUCCESS;
8166}
8167
8168TPM_RC Tpm::ParseResponse_Startup(
8169    const std::string& response,
8170    AuthorizationDelegate* authorization_delegate) {
8171  VLOG(3) << __func__;
8172  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8173  TPM_RC rc = TPM_RC_SUCCESS;
8174  std::string buffer(response);
8175  TPM_ST tag;
8176  std::string tag_bytes;
8177  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8178  if (rc != TPM_RC_SUCCESS) {
8179    return rc;
8180  }
8181  UINT32 response_size;
8182  std::string response_size_bytes;
8183  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8184  if (rc != TPM_RC_SUCCESS) {
8185    return rc;
8186  }
8187  TPM_RC response_code;
8188  std::string response_code_bytes;
8189  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8190  if (rc != TPM_RC_SUCCESS) {
8191    return rc;
8192  }
8193  if (response_size != response.size()) {
8194    return TPM_RC_SIZE;
8195  }
8196  if (response_code != TPM_RC_SUCCESS) {
8197    return response_code;
8198  }
8199  TPM_CC command_code = TPM_CC_Startup;
8200  std::string command_code_bytes;
8201  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8202  if (rc != TPM_RC_SUCCESS) {
8203    return rc;
8204  }
8205  std::string authorization_section_bytes;
8206  if (tag == TPM_ST_SESSIONS) {
8207    UINT32 parameter_section_size = buffer.size();
8208    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8209    if (rc != TPM_RC_SUCCESS) {
8210      return rc;
8211    }
8212    if (parameter_section_size > buffer.size()) {
8213      return TPM_RC_INSUFFICIENT;
8214    }
8215    authorization_section_bytes = buffer.substr(parameter_section_size);
8216    // Keep the parameter section in |buffer|.
8217    buffer.erase(parameter_section_size);
8218  }
8219  std::unique_ptr<crypto::SecureHash> hash(
8220      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8221  hash->Update(response_code_bytes.data(), response_code_bytes.size());
8222  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8223  hash->Update(buffer.data(), buffer.size());
8224  std::string response_hash(32, 0);
8225  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
8226  if (tag == TPM_ST_SESSIONS) {
8227    CHECK(authorization_delegate) << "Authorization delegate missing!";
8228    if (!authorization_delegate->CheckResponseAuthorization(
8229            response_hash, authorization_section_bytes)) {
8230      return TRUNKS_RC_AUTHORIZATION_FAILED;
8231    }
8232  }
8233  return TPM_RC_SUCCESS;
8234}
8235
8236void StartupErrorCallback(const Tpm::StartupResponse& callback,
8237                          TPM_RC response_code) {
8238  VLOG(1) << __func__;
8239  callback.Run(response_code);
8240}
8241
8242void StartupResponseParser(const Tpm::StartupResponse& callback,
8243                           AuthorizationDelegate* authorization_delegate,
8244                           const std::string& response) {
8245  VLOG(1) << __func__;
8246  base::Callback<void(TPM_RC)> error_reporter =
8247      base::Bind(StartupErrorCallback, callback);
8248  TPM_RC rc = Tpm::ParseResponse_Startup(response, authorization_delegate);
8249  if (rc != TPM_RC_SUCCESS) {
8250    error_reporter.Run(rc);
8251    return;
8252  }
8253  callback.Run(rc);
8254}
8255
8256void Tpm::Startup(const TPM_SU& startup_type,
8257                  AuthorizationDelegate* authorization_delegate,
8258                  const StartupResponse& callback) {
8259  VLOG(1) << __func__;
8260  base::Callback<void(TPM_RC)> error_reporter =
8261      base::Bind(StartupErrorCallback, callback);
8262  base::Callback<void(const std::string&)> parser =
8263      base::Bind(StartupResponseParser, callback, authorization_delegate);
8264  std::string command;
8265  TPM_RC rc =
8266      SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8267  if (rc != TPM_RC_SUCCESS) {
8268    error_reporter.Run(rc);
8269    return;
8270  }
8271  transceiver_->SendCommand(command, parser);
8272}
8273
8274TPM_RC Tpm::StartupSync(const TPM_SU& startup_type,
8275                        AuthorizationDelegate* authorization_delegate) {
8276  VLOG(1) << __func__;
8277  std::string command;
8278  TPM_RC rc =
8279      SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8280  if (rc != TPM_RC_SUCCESS) {
8281    return rc;
8282  }
8283  std::string response = transceiver_->SendCommandAndWait(command);
8284  rc = ParseResponse_Startup(response, authorization_delegate);
8285  return rc;
8286}
8287
8288TPM_RC Tpm::SerializeCommand_Shutdown(
8289    const TPM_SU& shutdown_type,
8290    std::string* serialized_command,
8291    AuthorizationDelegate* authorization_delegate) {
8292  VLOG(3) << __func__;
8293  TPM_RC rc = TPM_RC_SUCCESS;
8294  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8295  UINT32 command_size = 10;  // Header size.
8296  std::string handle_section_bytes;
8297  std::string parameter_section_bytes;
8298  TPM_CC command_code = TPM_CC_Shutdown;
8299  bool is_command_parameter_encryption_possible = false;
8300  bool is_response_parameter_encryption_possible = false;
8301  std::string command_code_bytes;
8302  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8303  if (rc != TPM_RC_SUCCESS) {
8304    return rc;
8305  }
8306  std::string shutdown_type_bytes;
8307  rc = Serialize_TPM_SU(shutdown_type, &shutdown_type_bytes);
8308  if (rc != TPM_RC_SUCCESS) {
8309    return rc;
8310  }
8311  std::unique_ptr<crypto::SecureHash> hash(
8312      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8313  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8314  hash->Update(shutdown_type_bytes.data(), shutdown_type_bytes.size());
8315  parameter_section_bytes += shutdown_type_bytes;
8316  command_size += shutdown_type_bytes.size();
8317  std::string command_hash(32, 0);
8318  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
8319  std::string authorization_section_bytes;
8320  std::string authorization_size_bytes;
8321  if (authorization_delegate) {
8322    if (!authorization_delegate->GetCommandAuthorization(
8323            command_hash, is_command_parameter_encryption_possible,
8324            is_response_parameter_encryption_possible,
8325            &authorization_section_bytes)) {
8326      return TRUNKS_RC_AUTHORIZATION_FAILED;
8327    }
8328    if (!authorization_section_bytes.empty()) {
8329      tag = TPM_ST_SESSIONS;
8330      std::string tmp;
8331      rc = Serialize_UINT32(authorization_section_bytes.size(),
8332                            &authorization_size_bytes);
8333      if (rc != TPM_RC_SUCCESS) {
8334        return rc;
8335      }
8336      command_size +=
8337          authorization_size_bytes.size() + authorization_section_bytes.size();
8338    }
8339  }
8340  std::string tag_bytes;
8341  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8342  if (rc != TPM_RC_SUCCESS) {
8343    return rc;
8344  }
8345  std::string command_size_bytes;
8346  rc = Serialize_UINT32(command_size, &command_size_bytes);
8347  if (rc != TPM_RC_SUCCESS) {
8348    return rc;
8349  }
8350  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8351                        handle_section_bytes + authorization_size_bytes +
8352                        authorization_section_bytes + parameter_section_bytes;
8353  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8354  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
8355                                            serialized_command->size());
8356  return TPM_RC_SUCCESS;
8357}
8358
8359TPM_RC Tpm::ParseResponse_Shutdown(
8360    const std::string& response,
8361    AuthorizationDelegate* authorization_delegate) {
8362  VLOG(3) << __func__;
8363  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8364  TPM_RC rc = TPM_RC_SUCCESS;
8365  std::string buffer(response);
8366  TPM_ST tag;
8367  std::string tag_bytes;
8368  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8369  if (rc != TPM_RC_SUCCESS) {
8370    return rc;
8371  }
8372  UINT32 response_size;
8373  std::string response_size_bytes;
8374  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8375  if (rc != TPM_RC_SUCCESS) {
8376    return rc;
8377  }
8378  TPM_RC response_code;
8379  std::string response_code_bytes;
8380  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8381  if (rc != TPM_RC_SUCCESS) {
8382    return rc;
8383  }
8384  if (response_size != response.size()) {
8385    return TPM_RC_SIZE;
8386  }
8387  if (response_code != TPM_RC_SUCCESS) {
8388    return response_code;
8389  }
8390  TPM_CC command_code = TPM_CC_Shutdown;
8391  std::string command_code_bytes;
8392  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8393  if (rc != TPM_RC_SUCCESS) {
8394    return rc;
8395  }
8396  std::string authorization_section_bytes;
8397  if (tag == TPM_ST_SESSIONS) {
8398    UINT32 parameter_section_size = buffer.size();
8399    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8400    if (rc != TPM_RC_SUCCESS) {
8401      return rc;
8402    }
8403    if (parameter_section_size > buffer.size()) {
8404      return TPM_RC_INSUFFICIENT;
8405    }
8406    authorization_section_bytes = buffer.substr(parameter_section_size);
8407    // Keep the parameter section in |buffer|.
8408    buffer.erase(parameter_section_size);
8409  }
8410  std::unique_ptr<crypto::SecureHash> hash(
8411      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8412  hash->Update(response_code_bytes.data(), response_code_bytes.size());
8413  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8414  hash->Update(buffer.data(), buffer.size());
8415  std::string response_hash(32, 0);
8416  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
8417  if (tag == TPM_ST_SESSIONS) {
8418    CHECK(authorization_delegate) << "Authorization delegate missing!";
8419    if (!authorization_delegate->CheckResponseAuthorization(
8420            response_hash, authorization_section_bytes)) {
8421      return TRUNKS_RC_AUTHORIZATION_FAILED;
8422    }
8423  }
8424  return TPM_RC_SUCCESS;
8425}
8426
8427void ShutdownErrorCallback(const Tpm::ShutdownResponse& callback,
8428                           TPM_RC response_code) {
8429  VLOG(1) << __func__;
8430  callback.Run(response_code);
8431}
8432
8433void ShutdownResponseParser(const Tpm::ShutdownResponse& callback,
8434                            AuthorizationDelegate* authorization_delegate,
8435                            const std::string& response) {
8436  VLOG(1) << __func__;
8437  base::Callback<void(TPM_RC)> error_reporter =
8438      base::Bind(ShutdownErrorCallback, callback);
8439  TPM_RC rc = Tpm::ParseResponse_Shutdown(response, authorization_delegate);
8440  if (rc != TPM_RC_SUCCESS) {
8441    error_reporter.Run(rc);
8442    return;
8443  }
8444  callback.Run(rc);
8445}
8446
8447void Tpm::Shutdown(const TPM_SU& shutdown_type,
8448                   AuthorizationDelegate* authorization_delegate,
8449                   const ShutdownResponse& callback) {
8450  VLOG(1) << __func__;
8451  base::Callback<void(TPM_RC)> error_reporter =
8452      base::Bind(ShutdownErrorCallback, callback);
8453  base::Callback<void(const std::string&)> parser =
8454      base::Bind(ShutdownResponseParser, callback, authorization_delegate);
8455  std::string command;
8456  TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8457                                        authorization_delegate);
8458  if (rc != TPM_RC_SUCCESS) {
8459    error_reporter.Run(rc);
8460    return;
8461  }
8462  transceiver_->SendCommand(command, parser);
8463}
8464
8465TPM_RC Tpm::ShutdownSync(const TPM_SU& shutdown_type,
8466                         AuthorizationDelegate* authorization_delegate) {
8467  VLOG(1) << __func__;
8468  std::string command;
8469  TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8470                                        authorization_delegate);
8471  if (rc != TPM_RC_SUCCESS) {
8472    return rc;
8473  }
8474  std::string response = transceiver_->SendCommandAndWait(command);
8475  rc = ParseResponse_Shutdown(response, authorization_delegate);
8476  return rc;
8477}
8478
8479TPM_RC Tpm::SerializeCommand_SelfTest(
8480    const TPMI_YES_NO& full_test,
8481    std::string* serialized_command,
8482    AuthorizationDelegate* authorization_delegate) {
8483  VLOG(3) << __func__;
8484  TPM_RC rc = TPM_RC_SUCCESS;
8485  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8486  UINT32 command_size = 10;  // Header size.
8487  std::string handle_section_bytes;
8488  std::string parameter_section_bytes;
8489  TPM_CC command_code = TPM_CC_SelfTest;
8490  bool is_command_parameter_encryption_possible = false;
8491  bool is_response_parameter_encryption_possible = false;
8492  std::string command_code_bytes;
8493  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8494  if (rc != TPM_RC_SUCCESS) {
8495    return rc;
8496  }
8497  std::string full_test_bytes;
8498  rc = Serialize_TPMI_YES_NO(full_test, &full_test_bytes);
8499  if (rc != TPM_RC_SUCCESS) {
8500    return rc;
8501  }
8502  std::unique_ptr<crypto::SecureHash> hash(
8503      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8504  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8505  hash->Update(full_test_bytes.data(), full_test_bytes.size());
8506  parameter_section_bytes += full_test_bytes;
8507  command_size += full_test_bytes.size();
8508  std::string command_hash(32, 0);
8509  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
8510  std::string authorization_section_bytes;
8511  std::string authorization_size_bytes;
8512  if (authorization_delegate) {
8513    if (!authorization_delegate->GetCommandAuthorization(
8514            command_hash, is_command_parameter_encryption_possible,
8515            is_response_parameter_encryption_possible,
8516            &authorization_section_bytes)) {
8517      return TRUNKS_RC_AUTHORIZATION_FAILED;
8518    }
8519    if (!authorization_section_bytes.empty()) {
8520      tag = TPM_ST_SESSIONS;
8521      std::string tmp;
8522      rc = Serialize_UINT32(authorization_section_bytes.size(),
8523                            &authorization_size_bytes);
8524      if (rc != TPM_RC_SUCCESS) {
8525        return rc;
8526      }
8527      command_size +=
8528          authorization_size_bytes.size() + authorization_section_bytes.size();
8529    }
8530  }
8531  std::string tag_bytes;
8532  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8533  if (rc != TPM_RC_SUCCESS) {
8534    return rc;
8535  }
8536  std::string command_size_bytes;
8537  rc = Serialize_UINT32(command_size, &command_size_bytes);
8538  if (rc != TPM_RC_SUCCESS) {
8539    return rc;
8540  }
8541  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8542                        handle_section_bytes + authorization_size_bytes +
8543                        authorization_section_bytes + parameter_section_bytes;
8544  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8545  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
8546                                            serialized_command->size());
8547  return TPM_RC_SUCCESS;
8548}
8549
8550TPM_RC Tpm::ParseResponse_SelfTest(
8551    const std::string& response,
8552    AuthorizationDelegate* authorization_delegate) {
8553  VLOG(3) << __func__;
8554  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8555  TPM_RC rc = TPM_RC_SUCCESS;
8556  std::string buffer(response);
8557  TPM_ST tag;
8558  std::string tag_bytes;
8559  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8560  if (rc != TPM_RC_SUCCESS) {
8561    return rc;
8562  }
8563  UINT32 response_size;
8564  std::string response_size_bytes;
8565  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8566  if (rc != TPM_RC_SUCCESS) {
8567    return rc;
8568  }
8569  TPM_RC response_code;
8570  std::string response_code_bytes;
8571  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8572  if (rc != TPM_RC_SUCCESS) {
8573    return rc;
8574  }
8575  if (response_size != response.size()) {
8576    return TPM_RC_SIZE;
8577  }
8578  if (response_code != TPM_RC_SUCCESS) {
8579    return response_code;
8580  }
8581  TPM_CC command_code = TPM_CC_SelfTest;
8582  std::string command_code_bytes;
8583  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8584  if (rc != TPM_RC_SUCCESS) {
8585    return rc;
8586  }
8587  std::string authorization_section_bytes;
8588  if (tag == TPM_ST_SESSIONS) {
8589    UINT32 parameter_section_size = buffer.size();
8590    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8591    if (rc != TPM_RC_SUCCESS) {
8592      return rc;
8593    }
8594    if (parameter_section_size > buffer.size()) {
8595      return TPM_RC_INSUFFICIENT;
8596    }
8597    authorization_section_bytes = buffer.substr(parameter_section_size);
8598    // Keep the parameter section in |buffer|.
8599    buffer.erase(parameter_section_size);
8600  }
8601  std::unique_ptr<crypto::SecureHash> hash(
8602      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8603  hash->Update(response_code_bytes.data(), response_code_bytes.size());
8604  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8605  hash->Update(buffer.data(), buffer.size());
8606  std::string response_hash(32, 0);
8607  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
8608  if (tag == TPM_ST_SESSIONS) {
8609    CHECK(authorization_delegate) << "Authorization delegate missing!";
8610    if (!authorization_delegate->CheckResponseAuthorization(
8611            response_hash, authorization_section_bytes)) {
8612      return TRUNKS_RC_AUTHORIZATION_FAILED;
8613    }
8614  }
8615  return TPM_RC_SUCCESS;
8616}
8617
8618void SelfTestErrorCallback(const Tpm::SelfTestResponse& callback,
8619                           TPM_RC response_code) {
8620  VLOG(1) << __func__;
8621  callback.Run(response_code);
8622}
8623
8624void SelfTestResponseParser(const Tpm::SelfTestResponse& callback,
8625                            AuthorizationDelegate* authorization_delegate,
8626                            const std::string& response) {
8627  VLOG(1) << __func__;
8628  base::Callback<void(TPM_RC)> error_reporter =
8629      base::Bind(SelfTestErrorCallback, callback);
8630  TPM_RC rc = Tpm::ParseResponse_SelfTest(response, authorization_delegate);
8631  if (rc != TPM_RC_SUCCESS) {
8632    error_reporter.Run(rc);
8633    return;
8634  }
8635  callback.Run(rc);
8636}
8637
8638void Tpm::SelfTest(const TPMI_YES_NO& full_test,
8639                   AuthorizationDelegate* authorization_delegate,
8640                   const SelfTestResponse& callback) {
8641  VLOG(1) << __func__;
8642  base::Callback<void(TPM_RC)> error_reporter =
8643      base::Bind(SelfTestErrorCallback, callback);
8644  base::Callback<void(const std::string&)> parser =
8645      base::Bind(SelfTestResponseParser, callback, authorization_delegate);
8646  std::string command;
8647  TPM_RC rc =
8648      SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8649  if (rc != TPM_RC_SUCCESS) {
8650    error_reporter.Run(rc);
8651    return;
8652  }
8653  transceiver_->SendCommand(command, parser);
8654}
8655
8656TPM_RC Tpm::SelfTestSync(const TPMI_YES_NO& full_test,
8657                         AuthorizationDelegate* authorization_delegate) {
8658  VLOG(1) << __func__;
8659  std::string command;
8660  TPM_RC rc =
8661      SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8662  if (rc != TPM_RC_SUCCESS) {
8663    return rc;
8664  }
8665  std::string response = transceiver_->SendCommandAndWait(command);
8666  rc = ParseResponse_SelfTest(response, authorization_delegate);
8667  return rc;
8668}
8669
8670TPM_RC Tpm::SerializeCommand_IncrementalSelfTest(
8671    const TPML_ALG& to_test,
8672    std::string* serialized_command,
8673    AuthorizationDelegate* authorization_delegate) {
8674  VLOG(3) << __func__;
8675  TPM_RC rc = TPM_RC_SUCCESS;
8676  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8677  UINT32 command_size = 10;  // Header size.
8678  std::string handle_section_bytes;
8679  std::string parameter_section_bytes;
8680  TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8681  bool is_command_parameter_encryption_possible = false;
8682  bool is_response_parameter_encryption_possible = false;
8683  std::string command_code_bytes;
8684  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8685  if (rc != TPM_RC_SUCCESS) {
8686    return rc;
8687  }
8688  std::string to_test_bytes;
8689  rc = Serialize_TPML_ALG(to_test, &to_test_bytes);
8690  if (rc != TPM_RC_SUCCESS) {
8691    return rc;
8692  }
8693  std::unique_ptr<crypto::SecureHash> hash(
8694      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8695  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8696  hash->Update(to_test_bytes.data(), to_test_bytes.size());
8697  parameter_section_bytes += to_test_bytes;
8698  command_size += to_test_bytes.size();
8699  std::string command_hash(32, 0);
8700  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
8701  std::string authorization_section_bytes;
8702  std::string authorization_size_bytes;
8703  if (authorization_delegate) {
8704    if (!authorization_delegate->GetCommandAuthorization(
8705            command_hash, is_command_parameter_encryption_possible,
8706            is_response_parameter_encryption_possible,
8707            &authorization_section_bytes)) {
8708      return TRUNKS_RC_AUTHORIZATION_FAILED;
8709    }
8710    if (!authorization_section_bytes.empty()) {
8711      tag = TPM_ST_SESSIONS;
8712      std::string tmp;
8713      rc = Serialize_UINT32(authorization_section_bytes.size(),
8714                            &authorization_size_bytes);
8715      if (rc != TPM_RC_SUCCESS) {
8716        return rc;
8717      }
8718      command_size +=
8719          authorization_size_bytes.size() + authorization_section_bytes.size();
8720    }
8721  }
8722  std::string tag_bytes;
8723  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8724  if (rc != TPM_RC_SUCCESS) {
8725    return rc;
8726  }
8727  std::string command_size_bytes;
8728  rc = Serialize_UINT32(command_size, &command_size_bytes);
8729  if (rc != TPM_RC_SUCCESS) {
8730    return rc;
8731  }
8732  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8733                        handle_section_bytes + authorization_size_bytes +
8734                        authorization_section_bytes + parameter_section_bytes;
8735  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8736  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
8737                                            serialized_command->size());
8738  return TPM_RC_SUCCESS;
8739}
8740
8741TPM_RC Tpm::ParseResponse_IncrementalSelfTest(
8742    const std::string& response,
8743    TPML_ALG* to_do_list,
8744    AuthorizationDelegate* authorization_delegate) {
8745  VLOG(3) << __func__;
8746  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8747  TPM_RC rc = TPM_RC_SUCCESS;
8748  std::string buffer(response);
8749  TPM_ST tag;
8750  std::string tag_bytes;
8751  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8752  if (rc != TPM_RC_SUCCESS) {
8753    return rc;
8754  }
8755  UINT32 response_size;
8756  std::string response_size_bytes;
8757  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8758  if (rc != TPM_RC_SUCCESS) {
8759    return rc;
8760  }
8761  TPM_RC response_code;
8762  std::string response_code_bytes;
8763  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8764  if (rc != TPM_RC_SUCCESS) {
8765    return rc;
8766  }
8767  if (response_size != response.size()) {
8768    return TPM_RC_SIZE;
8769  }
8770  if (response_code != TPM_RC_SUCCESS) {
8771    return response_code;
8772  }
8773  TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8774  std::string command_code_bytes;
8775  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8776  if (rc != TPM_RC_SUCCESS) {
8777    return rc;
8778  }
8779  std::string authorization_section_bytes;
8780  if (tag == TPM_ST_SESSIONS) {
8781    UINT32 parameter_section_size = buffer.size();
8782    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8783    if (rc != TPM_RC_SUCCESS) {
8784      return rc;
8785    }
8786    if (parameter_section_size > buffer.size()) {
8787      return TPM_RC_INSUFFICIENT;
8788    }
8789    authorization_section_bytes = buffer.substr(parameter_section_size);
8790    // Keep the parameter section in |buffer|.
8791    buffer.erase(parameter_section_size);
8792  }
8793  std::unique_ptr<crypto::SecureHash> hash(
8794      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8795  hash->Update(response_code_bytes.data(), response_code_bytes.size());
8796  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8797  hash->Update(buffer.data(), buffer.size());
8798  std::string response_hash(32, 0);
8799  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
8800  if (tag == TPM_ST_SESSIONS) {
8801    CHECK(authorization_delegate) << "Authorization delegate missing!";
8802    if (!authorization_delegate->CheckResponseAuthorization(
8803            response_hash, authorization_section_bytes)) {
8804      return TRUNKS_RC_AUTHORIZATION_FAILED;
8805    }
8806  }
8807  std::string to_do_list_bytes;
8808  rc = Parse_TPML_ALG(&buffer, to_do_list, &to_do_list_bytes);
8809  if (rc != TPM_RC_SUCCESS) {
8810    return rc;
8811  }
8812  return TPM_RC_SUCCESS;
8813}
8814
8815void IncrementalSelfTestErrorCallback(
8816    const Tpm::IncrementalSelfTestResponse& callback,
8817    TPM_RC response_code) {
8818  VLOG(1) << __func__;
8819  callback.Run(response_code, TPML_ALG());
8820}
8821
8822void IncrementalSelfTestResponseParser(
8823    const Tpm::IncrementalSelfTestResponse& callback,
8824    AuthorizationDelegate* authorization_delegate,
8825    const std::string& response) {
8826  VLOG(1) << __func__;
8827  base::Callback<void(TPM_RC)> error_reporter =
8828      base::Bind(IncrementalSelfTestErrorCallback, callback);
8829  TPML_ALG to_do_list;
8830  TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest(response, &to_do_list,
8831                                                     authorization_delegate);
8832  if (rc != TPM_RC_SUCCESS) {
8833    error_reporter.Run(rc);
8834    return;
8835  }
8836  callback.Run(rc, to_do_list);
8837}
8838
8839void Tpm::IncrementalSelfTest(const TPML_ALG& to_test,
8840                              AuthorizationDelegate* authorization_delegate,
8841                              const IncrementalSelfTestResponse& callback) {
8842  VLOG(1) << __func__;
8843  base::Callback<void(TPM_RC)> error_reporter =
8844      base::Bind(IncrementalSelfTestErrorCallback, callback);
8845  base::Callback<void(const std::string&)> parser = base::Bind(
8846      IncrementalSelfTestResponseParser, callback, authorization_delegate);
8847  std::string command;
8848  TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8849                                                   authorization_delegate);
8850  if (rc != TPM_RC_SUCCESS) {
8851    error_reporter.Run(rc);
8852    return;
8853  }
8854  transceiver_->SendCommand(command, parser);
8855}
8856
8857TPM_RC Tpm::IncrementalSelfTestSync(
8858    const TPML_ALG& to_test,
8859    TPML_ALG* to_do_list,
8860    AuthorizationDelegate* authorization_delegate) {
8861  VLOG(1) << __func__;
8862  std::string command;
8863  TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8864                                                   authorization_delegate);
8865  if (rc != TPM_RC_SUCCESS) {
8866    return rc;
8867  }
8868  std::string response = transceiver_->SendCommandAndWait(command);
8869  rc = ParseResponse_IncrementalSelfTest(response, to_do_list,
8870                                         authorization_delegate);
8871  return rc;
8872}
8873
8874TPM_RC Tpm::SerializeCommand_GetTestResult(
8875    std::string* serialized_command,
8876    AuthorizationDelegate* authorization_delegate) {
8877  VLOG(3) << __func__;
8878  TPM_RC rc = TPM_RC_SUCCESS;
8879  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8880  UINT32 command_size = 10;  // Header size.
8881  std::string handle_section_bytes;
8882  std::string parameter_section_bytes;
8883  TPM_CC command_code = TPM_CC_GetTestResult;
8884  bool is_command_parameter_encryption_possible = false;
8885  bool is_response_parameter_encryption_possible = true;
8886  std::string command_code_bytes;
8887  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8888  if (rc != TPM_RC_SUCCESS) {
8889    return rc;
8890  }
8891  std::unique_ptr<crypto::SecureHash> hash(
8892      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8893  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8894  std::string command_hash(32, 0);
8895  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
8896  std::string authorization_section_bytes;
8897  std::string authorization_size_bytes;
8898  if (authorization_delegate) {
8899    if (!authorization_delegate->GetCommandAuthorization(
8900            command_hash, is_command_parameter_encryption_possible,
8901            is_response_parameter_encryption_possible,
8902            &authorization_section_bytes)) {
8903      return TRUNKS_RC_AUTHORIZATION_FAILED;
8904    }
8905    if (!authorization_section_bytes.empty()) {
8906      tag = TPM_ST_SESSIONS;
8907      std::string tmp;
8908      rc = Serialize_UINT32(authorization_section_bytes.size(),
8909                            &authorization_size_bytes);
8910      if (rc != TPM_RC_SUCCESS) {
8911        return rc;
8912      }
8913      command_size +=
8914          authorization_size_bytes.size() + authorization_section_bytes.size();
8915    }
8916  }
8917  std::string tag_bytes;
8918  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8919  if (rc != TPM_RC_SUCCESS) {
8920    return rc;
8921  }
8922  std::string command_size_bytes;
8923  rc = Serialize_UINT32(command_size, &command_size_bytes);
8924  if (rc != TPM_RC_SUCCESS) {
8925    return rc;
8926  }
8927  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8928                        handle_section_bytes + authorization_size_bytes +
8929                        authorization_section_bytes + parameter_section_bytes;
8930  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8931  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
8932                                            serialized_command->size());
8933  return TPM_RC_SUCCESS;
8934}
8935
8936TPM_RC Tpm::ParseResponse_GetTestResult(
8937    const std::string& response,
8938    TPM2B_MAX_BUFFER* out_data,
8939    TPM_RC* test_result,
8940    AuthorizationDelegate* authorization_delegate) {
8941  VLOG(3) << __func__;
8942  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8943  TPM_RC rc = TPM_RC_SUCCESS;
8944  std::string buffer(response);
8945  TPM_ST tag;
8946  std::string tag_bytes;
8947  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8948  if (rc != TPM_RC_SUCCESS) {
8949    return rc;
8950  }
8951  UINT32 response_size;
8952  std::string response_size_bytes;
8953  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8954  if (rc != TPM_RC_SUCCESS) {
8955    return rc;
8956  }
8957  TPM_RC response_code;
8958  std::string response_code_bytes;
8959  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8960  if (rc != TPM_RC_SUCCESS) {
8961    return rc;
8962  }
8963  if (response_size != response.size()) {
8964    return TPM_RC_SIZE;
8965  }
8966  if (response_code != TPM_RC_SUCCESS) {
8967    return response_code;
8968  }
8969  TPM_CC command_code = TPM_CC_GetTestResult;
8970  std::string command_code_bytes;
8971  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8972  if (rc != TPM_RC_SUCCESS) {
8973    return rc;
8974  }
8975  std::string authorization_section_bytes;
8976  if (tag == TPM_ST_SESSIONS) {
8977    UINT32 parameter_section_size = buffer.size();
8978    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8979    if (rc != TPM_RC_SUCCESS) {
8980      return rc;
8981    }
8982    if (parameter_section_size > buffer.size()) {
8983      return TPM_RC_INSUFFICIENT;
8984    }
8985    authorization_section_bytes = buffer.substr(parameter_section_size);
8986    // Keep the parameter section in |buffer|.
8987    buffer.erase(parameter_section_size);
8988  }
8989  std::unique_ptr<crypto::SecureHash> hash(
8990      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8991  hash->Update(response_code_bytes.data(), response_code_bytes.size());
8992  hash->Update(command_code_bytes.data(), command_code_bytes.size());
8993  hash->Update(buffer.data(), buffer.size());
8994  std::string response_hash(32, 0);
8995  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
8996  if (tag == TPM_ST_SESSIONS) {
8997    CHECK(authorization_delegate) << "Authorization delegate missing!";
8998    if (!authorization_delegate->CheckResponseAuthorization(
8999            response_hash, authorization_section_bytes)) {
9000      return TRUNKS_RC_AUTHORIZATION_FAILED;
9001    }
9002  }
9003  std::string out_data_bytes;
9004  rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
9005  if (rc != TPM_RC_SUCCESS) {
9006    return rc;
9007  }
9008  std::string test_result_bytes;
9009  rc = Parse_TPM_RC(&buffer, test_result, &test_result_bytes);
9010  if (rc != TPM_RC_SUCCESS) {
9011    return rc;
9012  }
9013  if (tag == TPM_ST_SESSIONS) {
9014    CHECK(authorization_delegate) << "Authorization delegate missing!";
9015    // Decrypt just the parameter data, not the size.
9016    std::string tmp = out_data_bytes.substr(2);
9017    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
9018      return TRUNKS_RC_ENCRYPTION_FAILED;
9019    }
9020    out_data_bytes.replace(2, std::string::npos, tmp);
9021    rc = Parse_TPM2B_MAX_BUFFER(&out_data_bytes, out_data, nullptr);
9022    if (rc != TPM_RC_SUCCESS) {
9023      return rc;
9024    }
9025  }
9026  return TPM_RC_SUCCESS;
9027}
9028
9029void GetTestResultErrorCallback(const Tpm::GetTestResultResponse& callback,
9030                                TPM_RC response_code) {
9031  VLOG(1) << __func__;
9032  callback.Run(response_code, TPM2B_MAX_BUFFER(), TPM_RC());
9033}
9034
9035void GetTestResultResponseParser(const Tpm::GetTestResultResponse& callback,
9036                                 AuthorizationDelegate* authorization_delegate,
9037                                 const std::string& response) {
9038  VLOG(1) << __func__;
9039  base::Callback<void(TPM_RC)> error_reporter =
9040      base::Bind(GetTestResultErrorCallback, callback);
9041  TPM2B_MAX_BUFFER out_data;
9042  TPM_RC test_result;
9043  TPM_RC rc = Tpm::ParseResponse_GetTestResult(
9044      response, &out_data, &test_result, authorization_delegate);
9045  if (rc != TPM_RC_SUCCESS) {
9046    error_reporter.Run(rc);
9047    return;
9048  }
9049  callback.Run(rc, out_data, test_result);
9050}
9051
9052void Tpm::GetTestResult(AuthorizationDelegate* authorization_delegate,
9053                        const GetTestResultResponse& callback) {
9054  VLOG(1) << __func__;
9055  base::Callback<void(TPM_RC)> error_reporter =
9056      base::Bind(GetTestResultErrorCallback, callback);
9057  base::Callback<void(const std::string&)> parser =
9058      base::Bind(GetTestResultResponseParser, callback, authorization_delegate);
9059  std::string command;
9060  TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9061  if (rc != TPM_RC_SUCCESS) {
9062    error_reporter.Run(rc);
9063    return;
9064  }
9065  transceiver_->SendCommand(command, parser);
9066}
9067
9068TPM_RC Tpm::GetTestResultSync(TPM2B_MAX_BUFFER* out_data,
9069                              TPM_RC* test_result,
9070                              AuthorizationDelegate* authorization_delegate) {
9071  VLOG(1) << __func__;
9072  std::string command;
9073  TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9074  if (rc != TPM_RC_SUCCESS) {
9075    return rc;
9076  }
9077  std::string response = transceiver_->SendCommandAndWait(command);
9078  rc = ParseResponse_GetTestResult(response, out_data, test_result,
9079                                   authorization_delegate);
9080  return rc;
9081}
9082
9083TPM_RC Tpm::SerializeCommand_StartAuthSession(
9084    const TPMI_DH_OBJECT& tpm_key,
9085    const std::string& tpm_key_name,
9086    const TPMI_DH_ENTITY& bind,
9087    const std::string& bind_name,
9088    const TPM2B_NONCE& nonce_caller,
9089    const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9090    const TPM_SE& session_type,
9091    const TPMT_SYM_DEF& symmetric,
9092    const TPMI_ALG_HASH& auth_hash,
9093    std::string* serialized_command,
9094    AuthorizationDelegate* authorization_delegate) {
9095  VLOG(3) << __func__;
9096  TPM_RC rc = TPM_RC_SUCCESS;
9097  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9098  UINT32 command_size = 10;  // Header size.
9099  std::string handle_section_bytes;
9100  std::string parameter_section_bytes;
9101  TPM_CC command_code = TPM_CC_StartAuthSession;
9102  bool is_command_parameter_encryption_possible = true;
9103  bool is_response_parameter_encryption_possible = true;
9104  std::string command_code_bytes;
9105  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9106  if (rc != TPM_RC_SUCCESS) {
9107    return rc;
9108  }
9109  std::string tpm_key_bytes;
9110  rc = Serialize_TPMI_DH_OBJECT(tpm_key, &tpm_key_bytes);
9111  if (rc != TPM_RC_SUCCESS) {
9112    return rc;
9113  }
9114  std::string bind_bytes;
9115  rc = Serialize_TPMI_DH_ENTITY(bind, &bind_bytes);
9116  if (rc != TPM_RC_SUCCESS) {
9117    return rc;
9118  }
9119  std::string nonce_caller_bytes;
9120  rc = Serialize_TPM2B_NONCE(nonce_caller, &nonce_caller_bytes);
9121  if (rc != TPM_RC_SUCCESS) {
9122    return rc;
9123  }
9124  std::string encrypted_salt_bytes;
9125  rc = Serialize_TPM2B_ENCRYPTED_SECRET(encrypted_salt, &encrypted_salt_bytes);
9126  if (rc != TPM_RC_SUCCESS) {
9127    return rc;
9128  }
9129  std::string session_type_bytes;
9130  rc = Serialize_TPM_SE(session_type, &session_type_bytes);
9131  if (rc != TPM_RC_SUCCESS) {
9132    return rc;
9133  }
9134  std::string symmetric_bytes;
9135  rc = Serialize_TPMT_SYM_DEF(symmetric, &symmetric_bytes);
9136  if (rc != TPM_RC_SUCCESS) {
9137    return rc;
9138  }
9139  std::string auth_hash_bytes;
9140  rc = Serialize_TPMI_ALG_HASH(auth_hash, &auth_hash_bytes);
9141  if (rc != TPM_RC_SUCCESS) {
9142    return rc;
9143  }
9144  if (authorization_delegate) {
9145    // Encrypt just the parameter data, not the size.
9146    std::string tmp = nonce_caller_bytes.substr(2);
9147    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9148      return TRUNKS_RC_ENCRYPTION_FAILED;
9149    }
9150    nonce_caller_bytes.replace(2, std::string::npos, tmp);
9151  }
9152  std::unique_ptr<crypto::SecureHash> hash(
9153      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9154  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9155  hash->Update(tpm_key_name.data(), tpm_key_name.size());
9156  handle_section_bytes += tpm_key_bytes;
9157  command_size += tpm_key_bytes.size();
9158  hash->Update(bind_name.data(), bind_name.size());
9159  handle_section_bytes += bind_bytes;
9160  command_size += bind_bytes.size();
9161  hash->Update(nonce_caller_bytes.data(), nonce_caller_bytes.size());
9162  parameter_section_bytes += nonce_caller_bytes;
9163  command_size += nonce_caller_bytes.size();
9164  hash->Update(encrypted_salt_bytes.data(), encrypted_salt_bytes.size());
9165  parameter_section_bytes += encrypted_salt_bytes;
9166  command_size += encrypted_salt_bytes.size();
9167  hash->Update(session_type_bytes.data(), session_type_bytes.size());
9168  parameter_section_bytes += session_type_bytes;
9169  command_size += session_type_bytes.size();
9170  hash->Update(symmetric_bytes.data(), symmetric_bytes.size());
9171  parameter_section_bytes += symmetric_bytes;
9172  command_size += symmetric_bytes.size();
9173  hash->Update(auth_hash_bytes.data(), auth_hash_bytes.size());
9174  parameter_section_bytes += auth_hash_bytes;
9175  command_size += auth_hash_bytes.size();
9176  std::string command_hash(32, 0);
9177  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
9178  std::string authorization_section_bytes;
9179  std::string authorization_size_bytes;
9180  if (authorization_delegate) {
9181    if (!authorization_delegate->GetCommandAuthorization(
9182            command_hash, is_command_parameter_encryption_possible,
9183            is_response_parameter_encryption_possible,
9184            &authorization_section_bytes)) {
9185      return TRUNKS_RC_AUTHORIZATION_FAILED;
9186    }
9187    if (!authorization_section_bytes.empty()) {
9188      tag = TPM_ST_SESSIONS;
9189      std::string tmp;
9190      rc = Serialize_UINT32(authorization_section_bytes.size(),
9191                            &authorization_size_bytes);
9192      if (rc != TPM_RC_SUCCESS) {
9193        return rc;
9194      }
9195      command_size +=
9196          authorization_size_bytes.size() + authorization_section_bytes.size();
9197    }
9198  }
9199  std::string tag_bytes;
9200  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9201  if (rc != TPM_RC_SUCCESS) {
9202    return rc;
9203  }
9204  std::string command_size_bytes;
9205  rc = Serialize_UINT32(command_size, &command_size_bytes);
9206  if (rc != TPM_RC_SUCCESS) {
9207    return rc;
9208  }
9209  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9210                        handle_section_bytes + authorization_size_bytes +
9211                        authorization_section_bytes + parameter_section_bytes;
9212  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9213  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
9214                                            serialized_command->size());
9215  return TPM_RC_SUCCESS;
9216}
9217
9218TPM_RC Tpm::ParseResponse_StartAuthSession(
9219    const std::string& response,
9220    TPMI_SH_AUTH_SESSION* session_handle,
9221    TPM2B_NONCE* nonce_tpm,
9222    AuthorizationDelegate* authorization_delegate) {
9223  VLOG(3) << __func__;
9224  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9225  TPM_RC rc = TPM_RC_SUCCESS;
9226  std::string buffer(response);
9227  TPM_ST tag;
9228  std::string tag_bytes;
9229  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9230  if (rc != TPM_RC_SUCCESS) {
9231    return rc;
9232  }
9233  UINT32 response_size;
9234  std::string response_size_bytes;
9235  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9236  if (rc != TPM_RC_SUCCESS) {
9237    return rc;
9238  }
9239  TPM_RC response_code;
9240  std::string response_code_bytes;
9241  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9242  if (rc != TPM_RC_SUCCESS) {
9243    return rc;
9244  }
9245  if (response_size != response.size()) {
9246    return TPM_RC_SIZE;
9247  }
9248  if (response_code != TPM_RC_SUCCESS) {
9249    return response_code;
9250  }
9251  std::string session_handle_bytes;
9252  rc = Parse_TPMI_SH_AUTH_SESSION(&buffer, session_handle,
9253                                  &session_handle_bytes);
9254  if (rc != TPM_RC_SUCCESS) {
9255    return rc;
9256  }
9257  TPM_CC command_code = TPM_CC_StartAuthSession;
9258  std::string command_code_bytes;
9259  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9260  if (rc != TPM_RC_SUCCESS) {
9261    return rc;
9262  }
9263  std::string authorization_section_bytes;
9264  if (tag == TPM_ST_SESSIONS) {
9265    UINT32 parameter_section_size = buffer.size();
9266    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9267    if (rc != TPM_RC_SUCCESS) {
9268      return rc;
9269    }
9270    if (parameter_section_size > buffer.size()) {
9271      return TPM_RC_INSUFFICIENT;
9272    }
9273    authorization_section_bytes = buffer.substr(parameter_section_size);
9274    // Keep the parameter section in |buffer|.
9275    buffer.erase(parameter_section_size);
9276  }
9277  std::unique_ptr<crypto::SecureHash> hash(
9278      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9279  hash->Update(response_code_bytes.data(), response_code_bytes.size());
9280  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9281  hash->Update(buffer.data(), buffer.size());
9282  std::string response_hash(32, 0);
9283  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
9284  if (tag == TPM_ST_SESSIONS) {
9285    CHECK(authorization_delegate) << "Authorization delegate missing!";
9286    if (!authorization_delegate->CheckResponseAuthorization(
9287            response_hash, authorization_section_bytes)) {
9288      return TRUNKS_RC_AUTHORIZATION_FAILED;
9289    }
9290  }
9291  std::string nonce_tpm_bytes;
9292  rc = Parse_TPM2B_NONCE(&buffer, nonce_tpm, &nonce_tpm_bytes);
9293  if (rc != TPM_RC_SUCCESS) {
9294    return rc;
9295  }
9296  if (tag == TPM_ST_SESSIONS) {
9297    CHECK(authorization_delegate) << "Authorization delegate missing!";
9298    // Decrypt just the parameter data, not the size.
9299    std::string tmp = nonce_tpm_bytes.substr(2);
9300    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
9301      return TRUNKS_RC_ENCRYPTION_FAILED;
9302    }
9303    nonce_tpm_bytes.replace(2, std::string::npos, tmp);
9304    rc = Parse_TPM2B_NONCE(&nonce_tpm_bytes, nonce_tpm, nullptr);
9305    if (rc != TPM_RC_SUCCESS) {
9306      return rc;
9307    }
9308  }
9309  return TPM_RC_SUCCESS;
9310}
9311
9312void StartAuthSessionErrorCallback(
9313    const Tpm::StartAuthSessionResponse& callback,
9314    TPM_RC response_code) {
9315  VLOG(1) << __func__;
9316  callback.Run(response_code, TPMI_SH_AUTH_SESSION(), TPM2B_NONCE());
9317}
9318
9319void StartAuthSessionResponseParser(
9320    const Tpm::StartAuthSessionResponse& callback,
9321    AuthorizationDelegate* authorization_delegate,
9322    const std::string& response) {
9323  VLOG(1) << __func__;
9324  base::Callback<void(TPM_RC)> error_reporter =
9325      base::Bind(StartAuthSessionErrorCallback, callback);
9326  TPMI_SH_AUTH_SESSION session_handle;
9327  TPM2B_NONCE nonce_tpm;
9328  TPM_RC rc = Tpm::ParseResponse_StartAuthSession(
9329      response, &session_handle, &nonce_tpm, authorization_delegate);
9330  if (rc != TPM_RC_SUCCESS) {
9331    error_reporter.Run(rc);
9332    return;
9333  }
9334  callback.Run(rc, session_handle, nonce_tpm);
9335}
9336
9337void Tpm::StartAuthSession(const TPMI_DH_OBJECT& tpm_key,
9338                           const std::string& tpm_key_name,
9339                           const TPMI_DH_ENTITY& bind,
9340                           const std::string& bind_name,
9341                           const TPM2B_NONCE& nonce_caller,
9342                           const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9343                           const TPM_SE& session_type,
9344                           const TPMT_SYM_DEF& symmetric,
9345                           const TPMI_ALG_HASH& auth_hash,
9346                           AuthorizationDelegate* authorization_delegate,
9347                           const StartAuthSessionResponse& callback) {
9348  VLOG(1) << __func__;
9349  base::Callback<void(TPM_RC)> error_reporter =
9350      base::Bind(StartAuthSessionErrorCallback, callback);
9351  base::Callback<void(const std::string&)> parser = base::Bind(
9352      StartAuthSessionResponseParser, callback, authorization_delegate);
9353  std::string command;
9354  TPM_RC rc = SerializeCommand_StartAuthSession(
9355      tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9356      session_type, symmetric, auth_hash, &command, authorization_delegate);
9357  if (rc != TPM_RC_SUCCESS) {
9358    error_reporter.Run(rc);
9359    return;
9360  }
9361  transceiver_->SendCommand(command, parser);
9362}
9363
9364TPM_RC Tpm::StartAuthSessionSync(
9365    const TPMI_DH_OBJECT& tpm_key,
9366    const std::string& tpm_key_name,
9367    const TPMI_DH_ENTITY& bind,
9368    const std::string& bind_name,
9369    const TPM2B_NONCE& nonce_caller,
9370    const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9371    const TPM_SE& session_type,
9372    const TPMT_SYM_DEF& symmetric,
9373    const TPMI_ALG_HASH& auth_hash,
9374    TPMI_SH_AUTH_SESSION* session_handle,
9375    TPM2B_NONCE* nonce_tpm,
9376    AuthorizationDelegate* authorization_delegate) {
9377  VLOG(1) << __func__;
9378  std::string command;
9379  TPM_RC rc = SerializeCommand_StartAuthSession(
9380      tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9381      session_type, symmetric, auth_hash, &command, authorization_delegate);
9382  if (rc != TPM_RC_SUCCESS) {
9383    return rc;
9384  }
9385  std::string response = transceiver_->SendCommandAndWait(command);
9386  rc = ParseResponse_StartAuthSession(response, session_handle, nonce_tpm,
9387                                      authorization_delegate);
9388  return rc;
9389}
9390
9391TPM_RC Tpm::SerializeCommand_PolicyRestart(
9392    const TPMI_SH_POLICY& session_handle,
9393    const std::string& session_handle_name,
9394    std::string* serialized_command,
9395    AuthorizationDelegate* authorization_delegate) {
9396  VLOG(3) << __func__;
9397  TPM_RC rc = TPM_RC_SUCCESS;
9398  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9399  UINT32 command_size = 10;  // Header size.
9400  std::string handle_section_bytes;
9401  std::string parameter_section_bytes;
9402  TPM_CC command_code = TPM_CC_PolicyRestart;
9403  bool is_command_parameter_encryption_possible = false;
9404  bool is_response_parameter_encryption_possible = false;
9405  std::string command_code_bytes;
9406  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9407  if (rc != TPM_RC_SUCCESS) {
9408    return rc;
9409  }
9410  std::string session_handle_bytes;
9411  rc = Serialize_TPMI_SH_POLICY(session_handle, &session_handle_bytes);
9412  if (rc != TPM_RC_SUCCESS) {
9413    return rc;
9414  }
9415  std::unique_ptr<crypto::SecureHash> hash(
9416      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9417  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9418  hash->Update(session_handle_name.data(), session_handle_name.size());
9419  handle_section_bytes += session_handle_bytes;
9420  command_size += session_handle_bytes.size();
9421  std::string command_hash(32, 0);
9422  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
9423  std::string authorization_section_bytes;
9424  std::string authorization_size_bytes;
9425  if (authorization_delegate) {
9426    if (!authorization_delegate->GetCommandAuthorization(
9427            command_hash, is_command_parameter_encryption_possible,
9428            is_response_parameter_encryption_possible,
9429            &authorization_section_bytes)) {
9430      return TRUNKS_RC_AUTHORIZATION_FAILED;
9431    }
9432    if (!authorization_section_bytes.empty()) {
9433      tag = TPM_ST_SESSIONS;
9434      std::string tmp;
9435      rc = Serialize_UINT32(authorization_section_bytes.size(),
9436                            &authorization_size_bytes);
9437      if (rc != TPM_RC_SUCCESS) {
9438        return rc;
9439      }
9440      command_size +=
9441          authorization_size_bytes.size() + authorization_section_bytes.size();
9442    }
9443  }
9444  std::string tag_bytes;
9445  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9446  if (rc != TPM_RC_SUCCESS) {
9447    return rc;
9448  }
9449  std::string command_size_bytes;
9450  rc = Serialize_UINT32(command_size, &command_size_bytes);
9451  if (rc != TPM_RC_SUCCESS) {
9452    return rc;
9453  }
9454  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9455                        handle_section_bytes + authorization_size_bytes +
9456                        authorization_section_bytes + parameter_section_bytes;
9457  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9458  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
9459                                            serialized_command->size());
9460  return TPM_RC_SUCCESS;
9461}
9462
9463TPM_RC Tpm::ParseResponse_PolicyRestart(
9464    const std::string& response,
9465    AuthorizationDelegate* authorization_delegate) {
9466  VLOG(3) << __func__;
9467  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9468  TPM_RC rc = TPM_RC_SUCCESS;
9469  std::string buffer(response);
9470  TPM_ST tag;
9471  std::string tag_bytes;
9472  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9473  if (rc != TPM_RC_SUCCESS) {
9474    return rc;
9475  }
9476  UINT32 response_size;
9477  std::string response_size_bytes;
9478  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9479  if (rc != TPM_RC_SUCCESS) {
9480    return rc;
9481  }
9482  TPM_RC response_code;
9483  std::string response_code_bytes;
9484  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9485  if (rc != TPM_RC_SUCCESS) {
9486    return rc;
9487  }
9488  if (response_size != response.size()) {
9489    return TPM_RC_SIZE;
9490  }
9491  if (response_code != TPM_RC_SUCCESS) {
9492    return response_code;
9493  }
9494  TPM_CC command_code = TPM_CC_PolicyRestart;
9495  std::string command_code_bytes;
9496  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9497  if (rc != TPM_RC_SUCCESS) {
9498    return rc;
9499  }
9500  std::string authorization_section_bytes;
9501  if (tag == TPM_ST_SESSIONS) {
9502    UINT32 parameter_section_size = buffer.size();
9503    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9504    if (rc != TPM_RC_SUCCESS) {
9505      return rc;
9506    }
9507    if (parameter_section_size > buffer.size()) {
9508      return TPM_RC_INSUFFICIENT;
9509    }
9510    authorization_section_bytes = buffer.substr(parameter_section_size);
9511    // Keep the parameter section in |buffer|.
9512    buffer.erase(parameter_section_size);
9513  }
9514  std::unique_ptr<crypto::SecureHash> hash(
9515      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9516  hash->Update(response_code_bytes.data(), response_code_bytes.size());
9517  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9518  hash->Update(buffer.data(), buffer.size());
9519  std::string response_hash(32, 0);
9520  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
9521  if (tag == TPM_ST_SESSIONS) {
9522    CHECK(authorization_delegate) << "Authorization delegate missing!";
9523    if (!authorization_delegate->CheckResponseAuthorization(
9524            response_hash, authorization_section_bytes)) {
9525      return TRUNKS_RC_AUTHORIZATION_FAILED;
9526    }
9527  }
9528  return TPM_RC_SUCCESS;
9529}
9530
9531void PolicyRestartErrorCallback(const Tpm::PolicyRestartResponse& callback,
9532                                TPM_RC response_code) {
9533  VLOG(1) << __func__;
9534  callback.Run(response_code);
9535}
9536
9537void PolicyRestartResponseParser(const Tpm::PolicyRestartResponse& callback,
9538                                 AuthorizationDelegate* authorization_delegate,
9539                                 const std::string& response) {
9540  VLOG(1) << __func__;
9541  base::Callback<void(TPM_RC)> error_reporter =
9542      base::Bind(PolicyRestartErrorCallback, callback);
9543  TPM_RC rc =
9544      Tpm::ParseResponse_PolicyRestart(response, authorization_delegate);
9545  if (rc != TPM_RC_SUCCESS) {
9546    error_reporter.Run(rc);
9547    return;
9548  }
9549  callback.Run(rc);
9550}
9551
9552void Tpm::PolicyRestart(const TPMI_SH_POLICY& session_handle,
9553                        const std::string& session_handle_name,
9554                        AuthorizationDelegate* authorization_delegate,
9555                        const PolicyRestartResponse& callback) {
9556  VLOG(1) << __func__;
9557  base::Callback<void(TPM_RC)> error_reporter =
9558      base::Bind(PolicyRestartErrorCallback, callback);
9559  base::Callback<void(const std::string&)> parser =
9560      base::Bind(PolicyRestartResponseParser, callback, authorization_delegate);
9561  std::string command;
9562  TPM_RC rc = SerializeCommand_PolicyRestart(
9563      session_handle, session_handle_name, &command, authorization_delegate);
9564  if (rc != TPM_RC_SUCCESS) {
9565    error_reporter.Run(rc);
9566    return;
9567  }
9568  transceiver_->SendCommand(command, parser);
9569}
9570
9571TPM_RC Tpm::PolicyRestartSync(const TPMI_SH_POLICY& session_handle,
9572                              const std::string& session_handle_name,
9573                              AuthorizationDelegate* authorization_delegate) {
9574  VLOG(1) << __func__;
9575  std::string command;
9576  TPM_RC rc = SerializeCommand_PolicyRestart(
9577      session_handle, session_handle_name, &command, authorization_delegate);
9578  if (rc != TPM_RC_SUCCESS) {
9579    return rc;
9580  }
9581  std::string response = transceiver_->SendCommandAndWait(command);
9582  rc = ParseResponse_PolicyRestart(response, authorization_delegate);
9583  return rc;
9584}
9585
9586TPM_RC Tpm::SerializeCommand_Create(
9587    const TPMI_DH_OBJECT& parent_handle,
9588    const std::string& parent_handle_name,
9589    const TPM2B_SENSITIVE_CREATE& in_sensitive,
9590    const TPM2B_PUBLIC& in_public,
9591    const TPM2B_DATA& outside_info,
9592    const TPML_PCR_SELECTION& creation_pcr,
9593    std::string* serialized_command,
9594    AuthorizationDelegate* authorization_delegate) {
9595  VLOG(3) << __func__;
9596  TPM_RC rc = TPM_RC_SUCCESS;
9597  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9598  UINT32 command_size = 10;  // Header size.
9599  std::string handle_section_bytes;
9600  std::string parameter_section_bytes;
9601  TPM_CC command_code = TPM_CC_Create;
9602  bool is_command_parameter_encryption_possible = true;
9603  bool is_response_parameter_encryption_possible = true;
9604  std::string command_code_bytes;
9605  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9606  if (rc != TPM_RC_SUCCESS) {
9607    return rc;
9608  }
9609  std::string parent_handle_bytes;
9610  rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9611  if (rc != TPM_RC_SUCCESS) {
9612    return rc;
9613  }
9614  std::string in_sensitive_bytes;
9615  rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
9616  if (rc != TPM_RC_SUCCESS) {
9617    return rc;
9618  }
9619  std::string in_public_bytes;
9620  rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9621  if (rc != TPM_RC_SUCCESS) {
9622    return rc;
9623  }
9624  std::string outside_info_bytes;
9625  rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
9626  if (rc != TPM_RC_SUCCESS) {
9627    return rc;
9628  }
9629  std::string creation_pcr_bytes;
9630  rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
9631  if (rc != TPM_RC_SUCCESS) {
9632    return rc;
9633  }
9634  if (authorization_delegate) {
9635    // Encrypt just the parameter data, not the size.
9636    std::string tmp = in_sensitive_bytes.substr(2);
9637    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9638      return TRUNKS_RC_ENCRYPTION_FAILED;
9639    }
9640    in_sensitive_bytes.replace(2, std::string::npos, tmp);
9641  }
9642  std::unique_ptr<crypto::SecureHash> hash(
9643      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9644  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9645  hash->Update(parent_handle_name.data(), parent_handle_name.size());
9646  handle_section_bytes += parent_handle_bytes;
9647  command_size += parent_handle_bytes.size();
9648  hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
9649  parameter_section_bytes += in_sensitive_bytes;
9650  command_size += in_sensitive_bytes.size();
9651  hash->Update(in_public_bytes.data(), in_public_bytes.size());
9652  parameter_section_bytes += in_public_bytes;
9653  command_size += in_public_bytes.size();
9654  hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
9655  parameter_section_bytes += outside_info_bytes;
9656  command_size += outside_info_bytes.size();
9657  hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
9658  parameter_section_bytes += creation_pcr_bytes;
9659  command_size += creation_pcr_bytes.size();
9660  std::string command_hash(32, 0);
9661  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
9662  std::string authorization_section_bytes;
9663  std::string authorization_size_bytes;
9664  if (authorization_delegate) {
9665    if (!authorization_delegate->GetCommandAuthorization(
9666            command_hash, is_command_parameter_encryption_possible,
9667            is_response_parameter_encryption_possible,
9668            &authorization_section_bytes)) {
9669      return TRUNKS_RC_AUTHORIZATION_FAILED;
9670    }
9671    if (!authorization_section_bytes.empty()) {
9672      tag = TPM_ST_SESSIONS;
9673      std::string tmp;
9674      rc = Serialize_UINT32(authorization_section_bytes.size(),
9675                            &authorization_size_bytes);
9676      if (rc != TPM_RC_SUCCESS) {
9677        return rc;
9678      }
9679      command_size +=
9680          authorization_size_bytes.size() + authorization_section_bytes.size();
9681    }
9682  }
9683  std::string tag_bytes;
9684  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9685  if (rc != TPM_RC_SUCCESS) {
9686    return rc;
9687  }
9688  std::string command_size_bytes;
9689  rc = Serialize_UINT32(command_size, &command_size_bytes);
9690  if (rc != TPM_RC_SUCCESS) {
9691    return rc;
9692  }
9693  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9694                        handle_section_bytes + authorization_size_bytes +
9695                        authorization_section_bytes + parameter_section_bytes;
9696  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9697  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
9698                                            serialized_command->size());
9699  return TPM_RC_SUCCESS;
9700}
9701
9702TPM_RC Tpm::ParseResponse_Create(
9703    const std::string& response,
9704    TPM2B_PRIVATE* out_private,
9705    TPM2B_PUBLIC* out_public,
9706    TPM2B_CREATION_DATA* creation_data,
9707    TPM2B_DIGEST* creation_hash,
9708    TPMT_TK_CREATION* creation_ticket,
9709    AuthorizationDelegate* authorization_delegate) {
9710  VLOG(3) << __func__;
9711  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9712  TPM_RC rc = TPM_RC_SUCCESS;
9713  std::string buffer(response);
9714  TPM_ST tag;
9715  std::string tag_bytes;
9716  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9717  if (rc != TPM_RC_SUCCESS) {
9718    return rc;
9719  }
9720  UINT32 response_size;
9721  std::string response_size_bytes;
9722  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9723  if (rc != TPM_RC_SUCCESS) {
9724    return rc;
9725  }
9726  TPM_RC response_code;
9727  std::string response_code_bytes;
9728  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9729  if (rc != TPM_RC_SUCCESS) {
9730    return rc;
9731  }
9732  if (response_size != response.size()) {
9733    return TPM_RC_SIZE;
9734  }
9735  if (response_code != TPM_RC_SUCCESS) {
9736    return response_code;
9737  }
9738  TPM_CC command_code = TPM_CC_Create;
9739  std::string command_code_bytes;
9740  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9741  if (rc != TPM_RC_SUCCESS) {
9742    return rc;
9743  }
9744  std::string authorization_section_bytes;
9745  if (tag == TPM_ST_SESSIONS) {
9746    UINT32 parameter_section_size = buffer.size();
9747    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9748    if (rc != TPM_RC_SUCCESS) {
9749      return rc;
9750    }
9751    if (parameter_section_size > buffer.size()) {
9752      return TPM_RC_INSUFFICIENT;
9753    }
9754    authorization_section_bytes = buffer.substr(parameter_section_size);
9755    // Keep the parameter section in |buffer|.
9756    buffer.erase(parameter_section_size);
9757  }
9758  std::unique_ptr<crypto::SecureHash> hash(
9759      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9760  hash->Update(response_code_bytes.data(), response_code_bytes.size());
9761  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9762  hash->Update(buffer.data(), buffer.size());
9763  std::string response_hash(32, 0);
9764  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
9765  if (tag == TPM_ST_SESSIONS) {
9766    CHECK(authorization_delegate) << "Authorization delegate missing!";
9767    if (!authorization_delegate->CheckResponseAuthorization(
9768            response_hash, authorization_section_bytes)) {
9769      return TRUNKS_RC_AUTHORIZATION_FAILED;
9770    }
9771  }
9772  std::string out_private_bytes;
9773  rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
9774  if (rc != TPM_RC_SUCCESS) {
9775    return rc;
9776  }
9777  std::string out_public_bytes;
9778  rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
9779  if (rc != TPM_RC_SUCCESS) {
9780    return rc;
9781  }
9782  std::string creation_data_bytes;
9783  rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
9784  if (rc != TPM_RC_SUCCESS) {
9785    return rc;
9786  }
9787  std::string creation_hash_bytes;
9788  rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
9789  if (rc != TPM_RC_SUCCESS) {
9790    return rc;
9791  }
9792  std::string creation_ticket_bytes;
9793  rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
9794  if (rc != TPM_RC_SUCCESS) {
9795    return rc;
9796  }
9797  if (tag == TPM_ST_SESSIONS) {
9798    CHECK(authorization_delegate) << "Authorization delegate missing!";
9799    // Decrypt just the parameter data, not the size.
9800    std::string tmp = out_private_bytes.substr(2);
9801    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
9802      return TRUNKS_RC_ENCRYPTION_FAILED;
9803    }
9804    out_private_bytes.replace(2, std::string::npos, tmp);
9805    rc = Parse_TPM2B_PRIVATE(&out_private_bytes, out_private, nullptr);
9806    if (rc != TPM_RC_SUCCESS) {
9807      return rc;
9808    }
9809  }
9810  return TPM_RC_SUCCESS;
9811}
9812
9813void CreateErrorCallback(const Tpm::CreateResponse& callback,
9814                         TPM_RC response_code) {
9815  VLOG(1) << __func__;
9816  callback.Run(response_code, TPM2B_PRIVATE(), TPM2B_PUBLIC(),
9817               TPM2B_CREATION_DATA(), TPM2B_DIGEST(), TPMT_TK_CREATION());
9818}
9819
9820void CreateResponseParser(const Tpm::CreateResponse& callback,
9821                          AuthorizationDelegate* authorization_delegate,
9822                          const std::string& response) {
9823  VLOG(1) << __func__;
9824  base::Callback<void(TPM_RC)> error_reporter =
9825      base::Bind(CreateErrorCallback, callback);
9826  TPM2B_PRIVATE out_private;
9827  TPM2B_PUBLIC out_public;
9828  TPM2B_CREATION_DATA creation_data;
9829  TPM2B_DIGEST creation_hash;
9830  TPMT_TK_CREATION creation_ticket;
9831  TPM_RC rc = Tpm::ParseResponse_Create(
9832      response, &out_private, &out_public, &creation_data, &creation_hash,
9833      &creation_ticket, authorization_delegate);
9834  if (rc != TPM_RC_SUCCESS) {
9835    error_reporter.Run(rc);
9836    return;
9837  }
9838  callback.Run(rc, out_private, out_public, creation_data, creation_hash,
9839               creation_ticket);
9840}
9841
9842void Tpm::Create(const TPMI_DH_OBJECT& parent_handle,
9843                 const std::string& parent_handle_name,
9844                 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9845                 const TPM2B_PUBLIC& in_public,
9846                 const TPM2B_DATA& outside_info,
9847                 const TPML_PCR_SELECTION& creation_pcr,
9848                 AuthorizationDelegate* authorization_delegate,
9849                 const CreateResponse& callback) {
9850  VLOG(1) << __func__;
9851  base::Callback<void(TPM_RC)> error_reporter =
9852      base::Bind(CreateErrorCallback, callback);
9853  base::Callback<void(const std::string&)> parser =
9854      base::Bind(CreateResponseParser, callback, authorization_delegate);
9855  std::string command;
9856  TPM_RC rc = SerializeCommand_Create(
9857      parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9858      creation_pcr, &command, authorization_delegate);
9859  if (rc != TPM_RC_SUCCESS) {
9860    error_reporter.Run(rc);
9861    return;
9862  }
9863  transceiver_->SendCommand(command, parser);
9864}
9865
9866TPM_RC Tpm::CreateSync(const TPMI_DH_OBJECT& parent_handle,
9867                       const std::string& parent_handle_name,
9868                       const TPM2B_SENSITIVE_CREATE& in_sensitive,
9869                       const TPM2B_PUBLIC& in_public,
9870                       const TPM2B_DATA& outside_info,
9871                       const TPML_PCR_SELECTION& creation_pcr,
9872                       TPM2B_PRIVATE* out_private,
9873                       TPM2B_PUBLIC* out_public,
9874                       TPM2B_CREATION_DATA* creation_data,
9875                       TPM2B_DIGEST* creation_hash,
9876                       TPMT_TK_CREATION* creation_ticket,
9877                       AuthorizationDelegate* authorization_delegate) {
9878  VLOG(1) << __func__;
9879  std::string command;
9880  TPM_RC rc = SerializeCommand_Create(
9881      parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9882      creation_pcr, &command, authorization_delegate);
9883  if (rc != TPM_RC_SUCCESS) {
9884    return rc;
9885  }
9886  std::string response = transceiver_->SendCommandAndWait(command);
9887  rc = ParseResponse_Create(response, out_private, out_public, creation_data,
9888                            creation_hash, creation_ticket,
9889                            authorization_delegate);
9890  return rc;
9891}
9892
9893TPM_RC Tpm::SerializeCommand_Load(
9894    const TPMI_DH_OBJECT& parent_handle,
9895    const std::string& parent_handle_name,
9896    const TPM2B_PRIVATE& in_private,
9897    const TPM2B_PUBLIC& in_public,
9898    std::string* serialized_command,
9899    AuthorizationDelegate* authorization_delegate) {
9900  VLOG(3) << __func__;
9901  TPM_RC rc = TPM_RC_SUCCESS;
9902  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9903  UINT32 command_size = 10;  // Header size.
9904  std::string handle_section_bytes;
9905  std::string parameter_section_bytes;
9906  TPM_CC command_code = TPM_CC_Load;
9907  bool is_command_parameter_encryption_possible = true;
9908  bool is_response_parameter_encryption_possible = true;
9909  std::string command_code_bytes;
9910  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9911  if (rc != TPM_RC_SUCCESS) {
9912    return rc;
9913  }
9914  std::string parent_handle_bytes;
9915  rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9916  if (rc != TPM_RC_SUCCESS) {
9917    return rc;
9918  }
9919  std::string in_private_bytes;
9920  rc = Serialize_TPM2B_PRIVATE(in_private, &in_private_bytes);
9921  if (rc != TPM_RC_SUCCESS) {
9922    return rc;
9923  }
9924  std::string in_public_bytes;
9925  rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9926  if (rc != TPM_RC_SUCCESS) {
9927    return rc;
9928  }
9929  if (authorization_delegate) {
9930    // Encrypt just the parameter data, not the size.
9931    std::string tmp = in_private_bytes.substr(2);
9932    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9933      return TRUNKS_RC_ENCRYPTION_FAILED;
9934    }
9935    in_private_bytes.replace(2, std::string::npos, tmp);
9936  }
9937  std::unique_ptr<crypto::SecureHash> hash(
9938      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9939  hash->Update(command_code_bytes.data(), command_code_bytes.size());
9940  hash->Update(parent_handle_name.data(), parent_handle_name.size());
9941  handle_section_bytes += parent_handle_bytes;
9942  command_size += parent_handle_bytes.size();
9943  hash->Update(in_private_bytes.data(), in_private_bytes.size());
9944  parameter_section_bytes += in_private_bytes;
9945  command_size += in_private_bytes.size();
9946  hash->Update(in_public_bytes.data(), in_public_bytes.size());
9947  parameter_section_bytes += in_public_bytes;
9948  command_size += in_public_bytes.size();
9949  std::string command_hash(32, 0);
9950  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
9951  std::string authorization_section_bytes;
9952  std::string authorization_size_bytes;
9953  if (authorization_delegate) {
9954    if (!authorization_delegate->GetCommandAuthorization(
9955            command_hash, is_command_parameter_encryption_possible,
9956            is_response_parameter_encryption_possible,
9957            &authorization_section_bytes)) {
9958      return TRUNKS_RC_AUTHORIZATION_FAILED;
9959    }
9960    if (!authorization_section_bytes.empty()) {
9961      tag = TPM_ST_SESSIONS;
9962      std::string tmp;
9963      rc = Serialize_UINT32(authorization_section_bytes.size(),
9964                            &authorization_size_bytes);
9965      if (rc != TPM_RC_SUCCESS) {
9966        return rc;
9967      }
9968      command_size +=
9969          authorization_size_bytes.size() + authorization_section_bytes.size();
9970    }
9971  }
9972  std::string tag_bytes;
9973  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9974  if (rc != TPM_RC_SUCCESS) {
9975    return rc;
9976  }
9977  std::string command_size_bytes;
9978  rc = Serialize_UINT32(command_size, &command_size_bytes);
9979  if (rc != TPM_RC_SUCCESS) {
9980    return rc;
9981  }
9982  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9983                        handle_section_bytes + authorization_size_bytes +
9984                        authorization_section_bytes + parameter_section_bytes;
9985  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9986  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
9987                                            serialized_command->size());
9988  return TPM_RC_SUCCESS;
9989}
9990
9991TPM_RC Tpm::ParseResponse_Load(const std::string& response,
9992                               TPM_HANDLE* object_handle,
9993                               TPM2B_NAME* name,
9994                               AuthorizationDelegate* authorization_delegate) {
9995  VLOG(3) << __func__;
9996  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9997  TPM_RC rc = TPM_RC_SUCCESS;
9998  std::string buffer(response);
9999  TPM_ST tag;
10000  std::string tag_bytes;
10001  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10002  if (rc != TPM_RC_SUCCESS) {
10003    return rc;
10004  }
10005  UINT32 response_size;
10006  std::string response_size_bytes;
10007  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10008  if (rc != TPM_RC_SUCCESS) {
10009    return rc;
10010  }
10011  TPM_RC response_code;
10012  std::string response_code_bytes;
10013  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10014  if (rc != TPM_RC_SUCCESS) {
10015    return rc;
10016  }
10017  if (response_size != response.size()) {
10018    return TPM_RC_SIZE;
10019  }
10020  if (response_code != TPM_RC_SUCCESS) {
10021    return response_code;
10022  }
10023  std::string object_handle_bytes;
10024  rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10025  if (rc != TPM_RC_SUCCESS) {
10026    return rc;
10027  }
10028  TPM_CC command_code = TPM_CC_Load;
10029  std::string command_code_bytes;
10030  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10031  if (rc != TPM_RC_SUCCESS) {
10032    return rc;
10033  }
10034  std::string authorization_section_bytes;
10035  if (tag == TPM_ST_SESSIONS) {
10036    UINT32 parameter_section_size = buffer.size();
10037    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10038    if (rc != TPM_RC_SUCCESS) {
10039      return rc;
10040    }
10041    if (parameter_section_size > buffer.size()) {
10042      return TPM_RC_INSUFFICIENT;
10043    }
10044    authorization_section_bytes = buffer.substr(parameter_section_size);
10045    // Keep the parameter section in |buffer|.
10046    buffer.erase(parameter_section_size);
10047  }
10048  std::unique_ptr<crypto::SecureHash> hash(
10049      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10050  hash->Update(response_code_bytes.data(), response_code_bytes.size());
10051  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10052  hash->Update(buffer.data(), buffer.size());
10053  std::string response_hash(32, 0);
10054  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
10055  if (tag == TPM_ST_SESSIONS) {
10056    CHECK(authorization_delegate) << "Authorization delegate missing!";
10057    if (!authorization_delegate->CheckResponseAuthorization(
10058            response_hash, authorization_section_bytes)) {
10059      return TRUNKS_RC_AUTHORIZATION_FAILED;
10060    }
10061  }
10062  std::string name_bytes;
10063  rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10064  if (rc != TPM_RC_SUCCESS) {
10065    return rc;
10066  }
10067  if (tag == TPM_ST_SESSIONS) {
10068    CHECK(authorization_delegate) << "Authorization delegate missing!";
10069    // Decrypt just the parameter data, not the size.
10070    std::string tmp = name_bytes.substr(2);
10071    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
10072      return TRUNKS_RC_ENCRYPTION_FAILED;
10073    }
10074    name_bytes.replace(2, std::string::npos, tmp);
10075    rc = Parse_TPM2B_NAME(&name_bytes, name, nullptr);
10076    if (rc != TPM_RC_SUCCESS) {
10077      return rc;
10078    }
10079  }
10080  return TPM_RC_SUCCESS;
10081}
10082
10083void LoadErrorCallback(const Tpm::LoadResponse& callback,
10084                       TPM_RC response_code) {
10085  VLOG(1) << __func__;
10086  callback.Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10087}
10088
10089void LoadResponseParser(const Tpm::LoadResponse& callback,
10090                        AuthorizationDelegate* authorization_delegate,
10091                        const std::string& response) {
10092  VLOG(1) << __func__;
10093  base::Callback<void(TPM_RC)> error_reporter =
10094      base::Bind(LoadErrorCallback, callback);
10095  TPM_HANDLE object_handle;
10096  TPM2B_NAME name;
10097  TPM_RC rc = Tpm::ParseResponse_Load(response, &object_handle, &name,
10098                                      authorization_delegate);
10099  if (rc != TPM_RC_SUCCESS) {
10100    error_reporter.Run(rc);
10101    return;
10102  }
10103  callback.Run(rc, object_handle, name);
10104}
10105
10106void Tpm::Load(const TPMI_DH_OBJECT& parent_handle,
10107               const std::string& parent_handle_name,
10108               const TPM2B_PRIVATE& in_private,
10109               const TPM2B_PUBLIC& in_public,
10110               AuthorizationDelegate* authorization_delegate,
10111               const LoadResponse& callback) {
10112  VLOG(1) << __func__;
10113  base::Callback<void(TPM_RC)> error_reporter =
10114      base::Bind(LoadErrorCallback, callback);
10115  base::Callback<void(const std::string&)> parser =
10116      base::Bind(LoadResponseParser, callback, authorization_delegate);
10117  std::string command;
10118  TPM_RC rc =
10119      SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10120                            in_public, &command, authorization_delegate);
10121  if (rc != TPM_RC_SUCCESS) {
10122    error_reporter.Run(rc);
10123    return;
10124  }
10125  transceiver_->SendCommand(command, parser);
10126}
10127
10128TPM_RC Tpm::LoadSync(const TPMI_DH_OBJECT& parent_handle,
10129                     const std::string& parent_handle_name,
10130                     const TPM2B_PRIVATE& in_private,
10131                     const TPM2B_PUBLIC& in_public,
10132                     TPM_HANDLE* object_handle,
10133                     TPM2B_NAME* name,
10134                     AuthorizationDelegate* authorization_delegate) {
10135  VLOG(1) << __func__;
10136  std::string command;
10137  TPM_RC rc =
10138      SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10139                            in_public, &command, authorization_delegate);
10140  if (rc != TPM_RC_SUCCESS) {
10141    return rc;
10142  }
10143  std::string response = transceiver_->SendCommandAndWait(command);
10144  rc =
10145      ParseResponse_Load(response, object_handle, name, authorization_delegate);
10146  return rc;
10147}
10148
10149TPM_RC Tpm::SerializeCommand_LoadExternal(
10150    const TPM2B_SENSITIVE& in_private,
10151    const TPM2B_PUBLIC& in_public,
10152    const TPMI_RH_HIERARCHY& hierarchy,
10153    std::string* serialized_command,
10154    AuthorizationDelegate* authorization_delegate) {
10155  VLOG(3) << __func__;
10156  TPM_RC rc = TPM_RC_SUCCESS;
10157  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10158  UINT32 command_size = 10;  // Header size.
10159  std::string handle_section_bytes;
10160  std::string parameter_section_bytes;
10161  TPM_CC command_code = TPM_CC_LoadExternal;
10162  bool is_command_parameter_encryption_possible = true;
10163  bool is_response_parameter_encryption_possible = true;
10164  std::string command_code_bytes;
10165  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10166  if (rc != TPM_RC_SUCCESS) {
10167    return rc;
10168  }
10169  std::string in_private_bytes;
10170  rc = Serialize_TPM2B_SENSITIVE(in_private, &in_private_bytes);
10171  if (rc != TPM_RC_SUCCESS) {
10172    return rc;
10173  }
10174  std::string in_public_bytes;
10175  rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
10176  if (rc != TPM_RC_SUCCESS) {
10177    return rc;
10178  }
10179  std::string hierarchy_bytes;
10180  rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
10181  if (rc != TPM_RC_SUCCESS) {
10182    return rc;
10183  }
10184  if (authorization_delegate) {
10185    // Encrypt just the parameter data, not the size.
10186    std::string tmp = in_private_bytes.substr(2);
10187    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10188      return TRUNKS_RC_ENCRYPTION_FAILED;
10189    }
10190    in_private_bytes.replace(2, std::string::npos, tmp);
10191  }
10192  std::unique_ptr<crypto::SecureHash> hash(
10193      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10194  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10195  hash->Update(in_private_bytes.data(), in_private_bytes.size());
10196  parameter_section_bytes += in_private_bytes;
10197  command_size += in_private_bytes.size();
10198  hash->Update(in_public_bytes.data(), in_public_bytes.size());
10199  parameter_section_bytes += in_public_bytes;
10200  command_size += in_public_bytes.size();
10201  hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
10202  parameter_section_bytes += hierarchy_bytes;
10203  command_size += hierarchy_bytes.size();
10204  std::string command_hash(32, 0);
10205  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
10206  std::string authorization_section_bytes;
10207  std::string authorization_size_bytes;
10208  if (authorization_delegate) {
10209    if (!authorization_delegate->GetCommandAuthorization(
10210            command_hash, is_command_parameter_encryption_possible,
10211            is_response_parameter_encryption_possible,
10212            &authorization_section_bytes)) {
10213      return TRUNKS_RC_AUTHORIZATION_FAILED;
10214    }
10215    if (!authorization_section_bytes.empty()) {
10216      tag = TPM_ST_SESSIONS;
10217      std::string tmp;
10218      rc = Serialize_UINT32(authorization_section_bytes.size(),
10219                            &authorization_size_bytes);
10220      if (rc != TPM_RC_SUCCESS) {
10221        return rc;
10222      }
10223      command_size +=
10224          authorization_size_bytes.size() + authorization_section_bytes.size();
10225    }
10226  }
10227  std::string tag_bytes;
10228  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10229  if (rc != TPM_RC_SUCCESS) {
10230    return rc;
10231  }
10232  std::string command_size_bytes;
10233  rc = Serialize_UINT32(command_size, &command_size_bytes);
10234  if (rc != TPM_RC_SUCCESS) {
10235    return rc;
10236  }
10237  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10238                        handle_section_bytes + authorization_size_bytes +
10239                        authorization_section_bytes + parameter_section_bytes;
10240  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10241  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
10242                                            serialized_command->size());
10243  return TPM_RC_SUCCESS;
10244}
10245
10246TPM_RC Tpm::ParseResponse_LoadExternal(
10247    const std::string& response,
10248    TPM_HANDLE* object_handle,
10249    TPM2B_NAME* name,
10250    AuthorizationDelegate* authorization_delegate) {
10251  VLOG(3) << __func__;
10252  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10253  TPM_RC rc = TPM_RC_SUCCESS;
10254  std::string buffer(response);
10255  TPM_ST tag;
10256  std::string tag_bytes;
10257  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10258  if (rc != TPM_RC_SUCCESS) {
10259    return rc;
10260  }
10261  UINT32 response_size;
10262  std::string response_size_bytes;
10263  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10264  if (rc != TPM_RC_SUCCESS) {
10265    return rc;
10266  }
10267  TPM_RC response_code;
10268  std::string response_code_bytes;
10269  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10270  if (rc != TPM_RC_SUCCESS) {
10271    return rc;
10272  }
10273  if (response_size != response.size()) {
10274    return TPM_RC_SIZE;
10275  }
10276  if (response_code != TPM_RC_SUCCESS) {
10277    return response_code;
10278  }
10279  std::string object_handle_bytes;
10280  rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10281  if (rc != TPM_RC_SUCCESS) {
10282    return rc;
10283  }
10284  TPM_CC command_code = TPM_CC_LoadExternal;
10285  std::string command_code_bytes;
10286  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10287  if (rc != TPM_RC_SUCCESS) {
10288    return rc;
10289  }
10290  std::string authorization_section_bytes;
10291  if (tag == TPM_ST_SESSIONS) {
10292    UINT32 parameter_section_size = buffer.size();
10293    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10294    if (rc != TPM_RC_SUCCESS) {
10295      return rc;
10296    }
10297    if (parameter_section_size > buffer.size()) {
10298      return TPM_RC_INSUFFICIENT;
10299    }
10300    authorization_section_bytes = buffer.substr(parameter_section_size);
10301    // Keep the parameter section in |buffer|.
10302    buffer.erase(parameter_section_size);
10303  }
10304  std::unique_ptr<crypto::SecureHash> hash(
10305      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10306  hash->Update(response_code_bytes.data(), response_code_bytes.size());
10307  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10308  hash->Update(buffer.data(), buffer.size());
10309  std::string response_hash(32, 0);
10310  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
10311  if (tag == TPM_ST_SESSIONS) {
10312    CHECK(authorization_delegate) << "Authorization delegate missing!";
10313    if (!authorization_delegate->CheckResponseAuthorization(
10314            response_hash, authorization_section_bytes)) {
10315      return TRUNKS_RC_AUTHORIZATION_FAILED;
10316    }
10317  }
10318  std::string name_bytes;
10319  rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10320  if (rc != TPM_RC_SUCCESS) {
10321    return rc;
10322  }
10323  if (tag == TPM_ST_SESSIONS) {
10324    CHECK(authorization_delegate) << "Authorization delegate missing!";
10325    // Decrypt just the parameter data, not the size.
10326    std::string tmp = name_bytes.substr(2);
10327    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
10328      return TRUNKS_RC_ENCRYPTION_FAILED;
10329    }
10330    name_bytes.replace(2, std::string::npos, tmp);
10331    rc = Parse_TPM2B_NAME(&name_bytes, name, nullptr);
10332    if (rc != TPM_RC_SUCCESS) {
10333      return rc;
10334    }
10335  }
10336  return TPM_RC_SUCCESS;
10337}
10338
10339void LoadExternalErrorCallback(const Tpm::LoadExternalResponse& callback,
10340                               TPM_RC response_code) {
10341  VLOG(1) << __func__;
10342  callback.Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10343}
10344
10345void LoadExternalResponseParser(const Tpm::LoadExternalResponse& callback,
10346                                AuthorizationDelegate* authorization_delegate,
10347                                const std::string& response) {
10348  VLOG(1) << __func__;
10349  base::Callback<void(TPM_RC)> error_reporter =
10350      base::Bind(LoadExternalErrorCallback, callback);
10351  TPM_HANDLE object_handle;
10352  TPM2B_NAME name;
10353  TPM_RC rc = Tpm::ParseResponse_LoadExternal(response, &object_handle, &name,
10354                                              authorization_delegate);
10355  if (rc != TPM_RC_SUCCESS) {
10356    error_reporter.Run(rc);
10357    return;
10358  }
10359  callback.Run(rc, object_handle, name);
10360}
10361
10362void Tpm::LoadExternal(const TPM2B_SENSITIVE& in_private,
10363                       const TPM2B_PUBLIC& in_public,
10364                       const TPMI_RH_HIERARCHY& hierarchy,
10365                       AuthorizationDelegate* authorization_delegate,
10366                       const LoadExternalResponse& callback) {
10367  VLOG(1) << __func__;
10368  base::Callback<void(TPM_RC)> error_reporter =
10369      base::Bind(LoadExternalErrorCallback, callback);
10370  base::Callback<void(const std::string&)> parser =
10371      base::Bind(LoadExternalResponseParser, callback, authorization_delegate);
10372  std::string command;
10373  TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10374                                            &command, authorization_delegate);
10375  if (rc != TPM_RC_SUCCESS) {
10376    error_reporter.Run(rc);
10377    return;
10378  }
10379  transceiver_->SendCommand(command, parser);
10380}
10381
10382TPM_RC Tpm::LoadExternalSync(const TPM2B_SENSITIVE& in_private,
10383                             const TPM2B_PUBLIC& in_public,
10384                             const TPMI_RH_HIERARCHY& hierarchy,
10385                             TPM_HANDLE* object_handle,
10386                             TPM2B_NAME* name,
10387                             AuthorizationDelegate* authorization_delegate) {
10388  VLOG(1) << __func__;
10389  std::string command;
10390  TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10391                                            &command, authorization_delegate);
10392  if (rc != TPM_RC_SUCCESS) {
10393    return rc;
10394  }
10395  std::string response = transceiver_->SendCommandAndWait(command);
10396  rc = ParseResponse_LoadExternal(response, object_handle, name,
10397                                  authorization_delegate);
10398  return rc;
10399}
10400
10401TPM_RC Tpm::SerializeCommand_ReadPublic(
10402    const TPMI_DH_OBJECT& object_handle,
10403    const std::string& object_handle_name,
10404    std::string* serialized_command,
10405    AuthorizationDelegate* authorization_delegate) {
10406  VLOG(3) << __func__;
10407  TPM_RC rc = TPM_RC_SUCCESS;
10408  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10409  UINT32 command_size = 10;  // Header size.
10410  std::string handle_section_bytes;
10411  std::string parameter_section_bytes;
10412  TPM_CC command_code = TPM_CC_ReadPublic;
10413  bool is_command_parameter_encryption_possible = false;
10414  bool is_response_parameter_encryption_possible = true;
10415  std::string command_code_bytes;
10416  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10417  if (rc != TPM_RC_SUCCESS) {
10418    return rc;
10419  }
10420  std::string object_handle_bytes;
10421  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
10422  if (rc != TPM_RC_SUCCESS) {
10423    return rc;
10424  }
10425  std::unique_ptr<crypto::SecureHash> hash(
10426      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10427  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10428  hash->Update(object_handle_name.data(), object_handle_name.size());
10429  handle_section_bytes += object_handle_bytes;
10430  command_size += object_handle_bytes.size();
10431  std::string command_hash(32, 0);
10432  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
10433  std::string authorization_section_bytes;
10434  std::string authorization_size_bytes;
10435  if (authorization_delegate) {
10436    if (!authorization_delegate->GetCommandAuthorization(
10437            command_hash, is_command_parameter_encryption_possible,
10438            is_response_parameter_encryption_possible,
10439            &authorization_section_bytes)) {
10440      return TRUNKS_RC_AUTHORIZATION_FAILED;
10441    }
10442    if (!authorization_section_bytes.empty()) {
10443      tag = TPM_ST_SESSIONS;
10444      std::string tmp;
10445      rc = Serialize_UINT32(authorization_section_bytes.size(),
10446                            &authorization_size_bytes);
10447      if (rc != TPM_RC_SUCCESS) {
10448        return rc;
10449      }
10450      command_size +=
10451          authorization_size_bytes.size() + authorization_section_bytes.size();
10452    }
10453  }
10454  std::string tag_bytes;
10455  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10456  if (rc != TPM_RC_SUCCESS) {
10457    return rc;
10458  }
10459  std::string command_size_bytes;
10460  rc = Serialize_UINT32(command_size, &command_size_bytes);
10461  if (rc != TPM_RC_SUCCESS) {
10462    return rc;
10463  }
10464  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10465                        handle_section_bytes + authorization_size_bytes +
10466                        authorization_section_bytes + parameter_section_bytes;
10467  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10468  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
10469                                            serialized_command->size());
10470  return TPM_RC_SUCCESS;
10471}
10472
10473TPM_RC Tpm::ParseResponse_ReadPublic(
10474    const std::string& response,
10475    TPM2B_PUBLIC* out_public,
10476    TPM2B_NAME* name,
10477    TPM2B_NAME* qualified_name,
10478    AuthorizationDelegate* authorization_delegate) {
10479  VLOG(3) << __func__;
10480  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10481  TPM_RC rc = TPM_RC_SUCCESS;
10482  std::string buffer(response);
10483  TPM_ST tag;
10484  std::string tag_bytes;
10485  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10486  if (rc != TPM_RC_SUCCESS) {
10487    return rc;
10488  }
10489  UINT32 response_size;
10490  std::string response_size_bytes;
10491  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10492  if (rc != TPM_RC_SUCCESS) {
10493    return rc;
10494  }
10495  TPM_RC response_code;
10496  std::string response_code_bytes;
10497  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10498  if (rc != TPM_RC_SUCCESS) {
10499    return rc;
10500  }
10501  if (response_size != response.size()) {
10502    return TPM_RC_SIZE;
10503  }
10504  if (response_code != TPM_RC_SUCCESS) {
10505    return response_code;
10506  }
10507  TPM_CC command_code = TPM_CC_ReadPublic;
10508  std::string command_code_bytes;
10509  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10510  if (rc != TPM_RC_SUCCESS) {
10511    return rc;
10512  }
10513  std::string authorization_section_bytes;
10514  if (tag == TPM_ST_SESSIONS) {
10515    UINT32 parameter_section_size = buffer.size();
10516    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10517    if (rc != TPM_RC_SUCCESS) {
10518      return rc;
10519    }
10520    if (parameter_section_size > buffer.size()) {
10521      return TPM_RC_INSUFFICIENT;
10522    }
10523    authorization_section_bytes = buffer.substr(parameter_section_size);
10524    // Keep the parameter section in |buffer|.
10525    buffer.erase(parameter_section_size);
10526  }
10527  std::unique_ptr<crypto::SecureHash> hash(
10528      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10529  hash->Update(response_code_bytes.data(), response_code_bytes.size());
10530  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10531  hash->Update(buffer.data(), buffer.size());
10532  std::string response_hash(32, 0);
10533  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
10534  if (tag == TPM_ST_SESSIONS) {
10535    CHECK(authorization_delegate) << "Authorization delegate missing!";
10536    if (!authorization_delegate->CheckResponseAuthorization(
10537            response_hash, authorization_section_bytes)) {
10538      return TRUNKS_RC_AUTHORIZATION_FAILED;
10539    }
10540  }
10541  std::string out_public_bytes;
10542  rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
10543  if (rc != TPM_RC_SUCCESS) {
10544    return rc;
10545  }
10546  std::string name_bytes;
10547  rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10548  if (rc != TPM_RC_SUCCESS) {
10549    return rc;
10550  }
10551  std::string qualified_name_bytes;
10552  rc = Parse_TPM2B_NAME(&buffer, qualified_name, &qualified_name_bytes);
10553  if (rc != TPM_RC_SUCCESS) {
10554    return rc;
10555  }
10556  if (tag == TPM_ST_SESSIONS) {
10557    CHECK(authorization_delegate) << "Authorization delegate missing!";
10558    // Decrypt just the parameter data, not the size.
10559    std::string tmp = out_public_bytes.substr(2);
10560    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
10561      return TRUNKS_RC_ENCRYPTION_FAILED;
10562    }
10563    out_public_bytes.replace(2, std::string::npos, tmp);
10564    rc = Parse_TPM2B_PUBLIC(&out_public_bytes, out_public, nullptr);
10565    if (rc != TPM_RC_SUCCESS) {
10566      return rc;
10567    }
10568  }
10569  return TPM_RC_SUCCESS;
10570}
10571
10572void ReadPublicErrorCallback(const Tpm::ReadPublicResponse& callback,
10573                             TPM_RC response_code) {
10574  VLOG(1) << __func__;
10575  callback.Run(response_code, TPM2B_PUBLIC(), TPM2B_NAME(), TPM2B_NAME());
10576}
10577
10578void ReadPublicResponseParser(const Tpm::ReadPublicResponse& callback,
10579                              AuthorizationDelegate* authorization_delegate,
10580                              const std::string& response) {
10581  VLOG(1) << __func__;
10582  base::Callback<void(TPM_RC)> error_reporter =
10583      base::Bind(ReadPublicErrorCallback, callback);
10584  TPM2B_PUBLIC out_public;
10585  TPM2B_NAME name;
10586  TPM2B_NAME qualified_name;
10587  TPM_RC rc = Tpm::ParseResponse_ReadPublic(
10588      response, &out_public, &name, &qualified_name, authorization_delegate);
10589  if (rc != TPM_RC_SUCCESS) {
10590    error_reporter.Run(rc);
10591    return;
10592  }
10593  callback.Run(rc, out_public, name, qualified_name);
10594}
10595
10596void Tpm::ReadPublic(const TPMI_DH_OBJECT& object_handle,
10597                     const std::string& object_handle_name,
10598                     AuthorizationDelegate* authorization_delegate,
10599                     const ReadPublicResponse& callback) {
10600  VLOG(1) << __func__;
10601  base::Callback<void(TPM_RC)> error_reporter =
10602      base::Bind(ReadPublicErrorCallback, callback);
10603  base::Callback<void(const std::string&)> parser =
10604      base::Bind(ReadPublicResponseParser, callback, authorization_delegate);
10605  std::string command;
10606  TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10607                                          &command, authorization_delegate);
10608  if (rc != TPM_RC_SUCCESS) {
10609    error_reporter.Run(rc);
10610    return;
10611  }
10612  transceiver_->SendCommand(command, parser);
10613}
10614
10615TPM_RC Tpm::ReadPublicSync(const TPMI_DH_OBJECT& object_handle,
10616                           const std::string& object_handle_name,
10617                           TPM2B_PUBLIC* out_public,
10618                           TPM2B_NAME* name,
10619                           TPM2B_NAME* qualified_name,
10620                           AuthorizationDelegate* authorization_delegate) {
10621  VLOG(1) << __func__;
10622  std::string command;
10623  TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10624                                          &command, authorization_delegate);
10625  if (rc != TPM_RC_SUCCESS) {
10626    return rc;
10627  }
10628  std::string response = transceiver_->SendCommandAndWait(command);
10629  rc = ParseResponse_ReadPublic(response, out_public, name, qualified_name,
10630                                authorization_delegate);
10631  return rc;
10632}
10633
10634TPM_RC Tpm::SerializeCommand_ActivateCredential(
10635    const TPMI_DH_OBJECT& activate_handle,
10636    const std::string& activate_handle_name,
10637    const TPMI_DH_OBJECT& key_handle,
10638    const std::string& key_handle_name,
10639    const TPM2B_ID_OBJECT& credential_blob,
10640    const TPM2B_ENCRYPTED_SECRET& secret,
10641    std::string* serialized_command,
10642    AuthorizationDelegate* authorization_delegate) {
10643  VLOG(3) << __func__;
10644  TPM_RC rc = TPM_RC_SUCCESS;
10645  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10646  UINT32 command_size = 10;  // Header size.
10647  std::string handle_section_bytes;
10648  std::string parameter_section_bytes;
10649  TPM_CC command_code = TPM_CC_ActivateCredential;
10650  bool is_command_parameter_encryption_possible = true;
10651  bool is_response_parameter_encryption_possible = true;
10652  std::string command_code_bytes;
10653  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10654  if (rc != TPM_RC_SUCCESS) {
10655    return rc;
10656  }
10657  std::string activate_handle_bytes;
10658  rc = Serialize_TPMI_DH_OBJECT(activate_handle, &activate_handle_bytes);
10659  if (rc != TPM_RC_SUCCESS) {
10660    return rc;
10661  }
10662  std::string key_handle_bytes;
10663  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
10664  if (rc != TPM_RC_SUCCESS) {
10665    return rc;
10666  }
10667  std::string credential_blob_bytes;
10668  rc = Serialize_TPM2B_ID_OBJECT(credential_blob, &credential_blob_bytes);
10669  if (rc != TPM_RC_SUCCESS) {
10670    return rc;
10671  }
10672  std::string secret_bytes;
10673  rc = Serialize_TPM2B_ENCRYPTED_SECRET(secret, &secret_bytes);
10674  if (rc != TPM_RC_SUCCESS) {
10675    return rc;
10676  }
10677  if (authorization_delegate) {
10678    // Encrypt just the parameter data, not the size.
10679    std::string tmp = credential_blob_bytes.substr(2);
10680    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10681      return TRUNKS_RC_ENCRYPTION_FAILED;
10682    }
10683    credential_blob_bytes.replace(2, std::string::npos, tmp);
10684  }
10685  std::unique_ptr<crypto::SecureHash> hash(
10686      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10687  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10688  hash->Update(activate_handle_name.data(), activate_handle_name.size());
10689  handle_section_bytes += activate_handle_bytes;
10690  command_size += activate_handle_bytes.size();
10691  hash->Update(key_handle_name.data(), key_handle_name.size());
10692  handle_section_bytes += key_handle_bytes;
10693  command_size += key_handle_bytes.size();
10694  hash->Update(credential_blob_bytes.data(), credential_blob_bytes.size());
10695  parameter_section_bytes += credential_blob_bytes;
10696  command_size += credential_blob_bytes.size();
10697  hash->Update(secret_bytes.data(), secret_bytes.size());
10698  parameter_section_bytes += secret_bytes;
10699  command_size += secret_bytes.size();
10700  std::string command_hash(32, 0);
10701  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
10702  std::string authorization_section_bytes;
10703  std::string authorization_size_bytes;
10704  if (authorization_delegate) {
10705    if (!authorization_delegate->GetCommandAuthorization(
10706            command_hash, is_command_parameter_encryption_possible,
10707            is_response_parameter_encryption_possible,
10708            &authorization_section_bytes)) {
10709      return TRUNKS_RC_AUTHORIZATION_FAILED;
10710    }
10711    if (!authorization_section_bytes.empty()) {
10712      tag = TPM_ST_SESSIONS;
10713      std::string tmp;
10714      rc = Serialize_UINT32(authorization_section_bytes.size(),
10715                            &authorization_size_bytes);
10716      if (rc != TPM_RC_SUCCESS) {
10717        return rc;
10718      }
10719      command_size +=
10720          authorization_size_bytes.size() + authorization_section_bytes.size();
10721    }
10722  }
10723  std::string tag_bytes;
10724  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10725  if (rc != TPM_RC_SUCCESS) {
10726    return rc;
10727  }
10728  std::string command_size_bytes;
10729  rc = Serialize_UINT32(command_size, &command_size_bytes);
10730  if (rc != TPM_RC_SUCCESS) {
10731    return rc;
10732  }
10733  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10734                        handle_section_bytes + authorization_size_bytes +
10735                        authorization_section_bytes + parameter_section_bytes;
10736  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10737  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
10738                                            serialized_command->size());
10739  return TPM_RC_SUCCESS;
10740}
10741
10742TPM_RC Tpm::ParseResponse_ActivateCredential(
10743    const std::string& response,
10744    TPM2B_DIGEST* cert_info,
10745    AuthorizationDelegate* authorization_delegate) {
10746  VLOG(3) << __func__;
10747  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10748  TPM_RC rc = TPM_RC_SUCCESS;
10749  std::string buffer(response);
10750  TPM_ST tag;
10751  std::string tag_bytes;
10752  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10753  if (rc != TPM_RC_SUCCESS) {
10754    return rc;
10755  }
10756  UINT32 response_size;
10757  std::string response_size_bytes;
10758  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10759  if (rc != TPM_RC_SUCCESS) {
10760    return rc;
10761  }
10762  TPM_RC response_code;
10763  std::string response_code_bytes;
10764  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10765  if (rc != TPM_RC_SUCCESS) {
10766    return rc;
10767  }
10768  if (response_size != response.size()) {
10769    return TPM_RC_SIZE;
10770  }
10771  if (response_code != TPM_RC_SUCCESS) {
10772    return response_code;
10773  }
10774  TPM_CC command_code = TPM_CC_ActivateCredential;
10775  std::string command_code_bytes;
10776  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10777  if (rc != TPM_RC_SUCCESS) {
10778    return rc;
10779  }
10780  std::string authorization_section_bytes;
10781  if (tag == TPM_ST_SESSIONS) {
10782    UINT32 parameter_section_size = buffer.size();
10783    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10784    if (rc != TPM_RC_SUCCESS) {
10785      return rc;
10786    }
10787    if (parameter_section_size > buffer.size()) {
10788      return TPM_RC_INSUFFICIENT;
10789    }
10790    authorization_section_bytes = buffer.substr(parameter_section_size);
10791    // Keep the parameter section in |buffer|.
10792    buffer.erase(parameter_section_size);
10793  }
10794  std::unique_ptr<crypto::SecureHash> hash(
10795      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10796  hash->Update(response_code_bytes.data(), response_code_bytes.size());
10797  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10798  hash->Update(buffer.data(), buffer.size());
10799  std::string response_hash(32, 0);
10800  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
10801  if (tag == TPM_ST_SESSIONS) {
10802    CHECK(authorization_delegate) << "Authorization delegate missing!";
10803    if (!authorization_delegate->CheckResponseAuthorization(
10804            response_hash, authorization_section_bytes)) {
10805      return TRUNKS_RC_AUTHORIZATION_FAILED;
10806    }
10807  }
10808  std::string cert_info_bytes;
10809  rc = Parse_TPM2B_DIGEST(&buffer, cert_info, &cert_info_bytes);
10810  if (rc != TPM_RC_SUCCESS) {
10811    return rc;
10812  }
10813  if (tag == TPM_ST_SESSIONS) {
10814    CHECK(authorization_delegate) << "Authorization delegate missing!";
10815    // Decrypt just the parameter data, not the size.
10816    std::string tmp = cert_info_bytes.substr(2);
10817    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
10818      return TRUNKS_RC_ENCRYPTION_FAILED;
10819    }
10820    cert_info_bytes.replace(2, std::string::npos, tmp);
10821    rc = Parse_TPM2B_DIGEST(&cert_info_bytes, cert_info, nullptr);
10822    if (rc != TPM_RC_SUCCESS) {
10823      return rc;
10824    }
10825  }
10826  return TPM_RC_SUCCESS;
10827}
10828
10829void ActivateCredentialErrorCallback(
10830    const Tpm::ActivateCredentialResponse& callback,
10831    TPM_RC response_code) {
10832  VLOG(1) << __func__;
10833  callback.Run(response_code, TPM2B_DIGEST());
10834}
10835
10836void ActivateCredentialResponseParser(
10837    const Tpm::ActivateCredentialResponse& callback,
10838    AuthorizationDelegate* authorization_delegate,
10839    const std::string& response) {
10840  VLOG(1) << __func__;
10841  base::Callback<void(TPM_RC)> error_reporter =
10842      base::Bind(ActivateCredentialErrorCallback, callback);
10843  TPM2B_DIGEST cert_info;
10844  TPM_RC rc = Tpm::ParseResponse_ActivateCredential(response, &cert_info,
10845                                                    authorization_delegate);
10846  if (rc != TPM_RC_SUCCESS) {
10847    error_reporter.Run(rc);
10848    return;
10849  }
10850  callback.Run(rc, cert_info);
10851}
10852
10853void Tpm::ActivateCredential(const TPMI_DH_OBJECT& activate_handle,
10854                             const std::string& activate_handle_name,
10855                             const TPMI_DH_OBJECT& key_handle,
10856                             const std::string& key_handle_name,
10857                             const TPM2B_ID_OBJECT& credential_blob,
10858                             const TPM2B_ENCRYPTED_SECRET& secret,
10859                             AuthorizationDelegate* authorization_delegate,
10860                             const ActivateCredentialResponse& callback) {
10861  VLOG(1) << __func__;
10862  base::Callback<void(TPM_RC)> error_reporter =
10863      base::Bind(ActivateCredentialErrorCallback, callback);
10864  base::Callback<void(const std::string&)> parser = base::Bind(
10865      ActivateCredentialResponseParser, callback, authorization_delegate);
10866  std::string command;
10867  TPM_RC rc = SerializeCommand_ActivateCredential(
10868      activate_handle, activate_handle_name, key_handle, key_handle_name,
10869      credential_blob, secret, &command, authorization_delegate);
10870  if (rc != TPM_RC_SUCCESS) {
10871    error_reporter.Run(rc);
10872    return;
10873  }
10874  transceiver_->SendCommand(command, parser);
10875}
10876
10877TPM_RC Tpm::ActivateCredentialSync(
10878    const TPMI_DH_OBJECT& activate_handle,
10879    const std::string& activate_handle_name,
10880    const TPMI_DH_OBJECT& key_handle,
10881    const std::string& key_handle_name,
10882    const TPM2B_ID_OBJECT& credential_blob,
10883    const TPM2B_ENCRYPTED_SECRET& secret,
10884    TPM2B_DIGEST* cert_info,
10885    AuthorizationDelegate* authorization_delegate) {
10886  VLOG(1) << __func__;
10887  std::string command;
10888  TPM_RC rc = SerializeCommand_ActivateCredential(
10889      activate_handle, activate_handle_name, key_handle, key_handle_name,
10890      credential_blob, secret, &command, authorization_delegate);
10891  if (rc != TPM_RC_SUCCESS) {
10892    return rc;
10893  }
10894  std::string response = transceiver_->SendCommandAndWait(command);
10895  rc = ParseResponse_ActivateCredential(response, cert_info,
10896                                        authorization_delegate);
10897  return rc;
10898}
10899
10900TPM_RC Tpm::SerializeCommand_MakeCredential(
10901    const TPMI_DH_OBJECT& handle,
10902    const std::string& handle_name,
10903    const TPM2B_DIGEST& credential,
10904    const TPM2B_NAME& object_name,
10905    std::string* serialized_command,
10906    AuthorizationDelegate* authorization_delegate) {
10907  VLOG(3) << __func__;
10908  TPM_RC rc = TPM_RC_SUCCESS;
10909  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10910  UINT32 command_size = 10;  // Header size.
10911  std::string handle_section_bytes;
10912  std::string parameter_section_bytes;
10913  TPM_CC command_code = TPM_CC_MakeCredential;
10914  bool is_command_parameter_encryption_possible = true;
10915  bool is_response_parameter_encryption_possible = true;
10916  std::string command_code_bytes;
10917  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10918  if (rc != TPM_RC_SUCCESS) {
10919    return rc;
10920  }
10921  std::string handle_bytes;
10922  rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
10923  if (rc != TPM_RC_SUCCESS) {
10924    return rc;
10925  }
10926  std::string credential_bytes;
10927  rc = Serialize_TPM2B_DIGEST(credential, &credential_bytes);
10928  if (rc != TPM_RC_SUCCESS) {
10929    return rc;
10930  }
10931  std::string object_name_bytes;
10932  rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
10933  if (rc != TPM_RC_SUCCESS) {
10934    return rc;
10935  }
10936  if (authorization_delegate) {
10937    // Encrypt just the parameter data, not the size.
10938    std::string tmp = credential_bytes.substr(2);
10939    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10940      return TRUNKS_RC_ENCRYPTION_FAILED;
10941    }
10942    credential_bytes.replace(2, std::string::npos, tmp);
10943  }
10944  std::unique_ptr<crypto::SecureHash> hash(
10945      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10946  hash->Update(command_code_bytes.data(), command_code_bytes.size());
10947  hash->Update(handle_name.data(), handle_name.size());
10948  handle_section_bytes += handle_bytes;
10949  command_size += handle_bytes.size();
10950  hash->Update(credential_bytes.data(), credential_bytes.size());
10951  parameter_section_bytes += credential_bytes;
10952  command_size += credential_bytes.size();
10953  hash->Update(object_name_bytes.data(), object_name_bytes.size());
10954  parameter_section_bytes += object_name_bytes;
10955  command_size += object_name_bytes.size();
10956  std::string command_hash(32, 0);
10957  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
10958  std::string authorization_section_bytes;
10959  std::string authorization_size_bytes;
10960  if (authorization_delegate) {
10961    if (!authorization_delegate->GetCommandAuthorization(
10962            command_hash, is_command_parameter_encryption_possible,
10963            is_response_parameter_encryption_possible,
10964            &authorization_section_bytes)) {
10965      return TRUNKS_RC_AUTHORIZATION_FAILED;
10966    }
10967    if (!authorization_section_bytes.empty()) {
10968      tag = TPM_ST_SESSIONS;
10969      std::string tmp;
10970      rc = Serialize_UINT32(authorization_section_bytes.size(),
10971                            &authorization_size_bytes);
10972      if (rc != TPM_RC_SUCCESS) {
10973        return rc;
10974      }
10975      command_size +=
10976          authorization_size_bytes.size() + authorization_section_bytes.size();
10977    }
10978  }
10979  std::string tag_bytes;
10980  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10981  if (rc != TPM_RC_SUCCESS) {
10982    return rc;
10983  }
10984  std::string command_size_bytes;
10985  rc = Serialize_UINT32(command_size, &command_size_bytes);
10986  if (rc != TPM_RC_SUCCESS) {
10987    return rc;
10988  }
10989  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10990                        handle_section_bytes + authorization_size_bytes +
10991                        authorization_section_bytes + parameter_section_bytes;
10992  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10993  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
10994                                            serialized_command->size());
10995  return TPM_RC_SUCCESS;
10996}
10997
10998TPM_RC Tpm::ParseResponse_MakeCredential(
10999    const std::string& response,
11000    TPM2B_ID_OBJECT* credential_blob,
11001    TPM2B_ENCRYPTED_SECRET* secret,
11002    AuthorizationDelegate* authorization_delegate) {
11003  VLOG(3) << __func__;
11004  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11005  TPM_RC rc = TPM_RC_SUCCESS;
11006  std::string buffer(response);
11007  TPM_ST tag;
11008  std::string tag_bytes;
11009  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11010  if (rc != TPM_RC_SUCCESS) {
11011    return rc;
11012  }
11013  UINT32 response_size;
11014  std::string response_size_bytes;
11015  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11016  if (rc != TPM_RC_SUCCESS) {
11017    return rc;
11018  }
11019  TPM_RC response_code;
11020  std::string response_code_bytes;
11021  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11022  if (rc != TPM_RC_SUCCESS) {
11023    return rc;
11024  }
11025  if (response_size != response.size()) {
11026    return TPM_RC_SIZE;
11027  }
11028  if (response_code != TPM_RC_SUCCESS) {
11029    return response_code;
11030  }
11031  TPM_CC command_code = TPM_CC_MakeCredential;
11032  std::string command_code_bytes;
11033  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11034  if (rc != TPM_RC_SUCCESS) {
11035    return rc;
11036  }
11037  std::string authorization_section_bytes;
11038  if (tag == TPM_ST_SESSIONS) {
11039    UINT32 parameter_section_size = buffer.size();
11040    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11041    if (rc != TPM_RC_SUCCESS) {
11042      return rc;
11043    }
11044    if (parameter_section_size > buffer.size()) {
11045      return TPM_RC_INSUFFICIENT;
11046    }
11047    authorization_section_bytes = buffer.substr(parameter_section_size);
11048    // Keep the parameter section in |buffer|.
11049    buffer.erase(parameter_section_size);
11050  }
11051  std::unique_ptr<crypto::SecureHash> hash(
11052      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11053  hash->Update(response_code_bytes.data(), response_code_bytes.size());
11054  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11055  hash->Update(buffer.data(), buffer.size());
11056  std::string response_hash(32, 0);
11057  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
11058  if (tag == TPM_ST_SESSIONS) {
11059    CHECK(authorization_delegate) << "Authorization delegate missing!";
11060    if (!authorization_delegate->CheckResponseAuthorization(
11061            response_hash, authorization_section_bytes)) {
11062      return TRUNKS_RC_AUTHORIZATION_FAILED;
11063    }
11064  }
11065  std::string credential_blob_bytes;
11066  rc = Parse_TPM2B_ID_OBJECT(&buffer, credential_blob, &credential_blob_bytes);
11067  if (rc != TPM_RC_SUCCESS) {
11068    return rc;
11069  }
11070  std::string secret_bytes;
11071  rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, secret, &secret_bytes);
11072  if (rc != TPM_RC_SUCCESS) {
11073    return rc;
11074  }
11075  if (tag == TPM_ST_SESSIONS) {
11076    CHECK(authorization_delegate) << "Authorization delegate missing!";
11077    // Decrypt just the parameter data, not the size.
11078    std::string tmp = credential_blob_bytes.substr(2);
11079    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
11080      return TRUNKS_RC_ENCRYPTION_FAILED;
11081    }
11082    credential_blob_bytes.replace(2, std::string::npos, tmp);
11083    rc =
11084        Parse_TPM2B_ID_OBJECT(&credential_blob_bytes, credential_blob, nullptr);
11085    if (rc != TPM_RC_SUCCESS) {
11086      return rc;
11087    }
11088  }
11089  return TPM_RC_SUCCESS;
11090}
11091
11092void MakeCredentialErrorCallback(const Tpm::MakeCredentialResponse& callback,
11093                                 TPM_RC response_code) {
11094  VLOG(1) << __func__;
11095  callback.Run(response_code, TPM2B_ID_OBJECT(), TPM2B_ENCRYPTED_SECRET());
11096}
11097
11098void MakeCredentialResponseParser(const Tpm::MakeCredentialResponse& callback,
11099                                  AuthorizationDelegate* authorization_delegate,
11100                                  const std::string& response) {
11101  VLOG(1) << __func__;
11102  base::Callback<void(TPM_RC)> error_reporter =
11103      base::Bind(MakeCredentialErrorCallback, callback);
11104  TPM2B_ID_OBJECT credential_blob;
11105  TPM2B_ENCRYPTED_SECRET secret;
11106  TPM_RC rc = Tpm::ParseResponse_MakeCredential(
11107      response, &credential_blob, &secret, authorization_delegate);
11108  if (rc != TPM_RC_SUCCESS) {
11109    error_reporter.Run(rc);
11110    return;
11111  }
11112  callback.Run(rc, credential_blob, secret);
11113}
11114
11115void Tpm::MakeCredential(const TPMI_DH_OBJECT& handle,
11116                         const std::string& handle_name,
11117                         const TPM2B_DIGEST& credential,
11118                         const TPM2B_NAME& object_name,
11119                         AuthorizationDelegate* authorization_delegate,
11120                         const MakeCredentialResponse& callback) {
11121  VLOG(1) << __func__;
11122  base::Callback<void(TPM_RC)> error_reporter =
11123      base::Bind(MakeCredentialErrorCallback, callback);
11124  base::Callback<void(const std::string&)> parser = base::Bind(
11125      MakeCredentialResponseParser, callback, authorization_delegate);
11126  std::string command;
11127  TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11128                                              object_name, &command,
11129                                              authorization_delegate);
11130  if (rc != TPM_RC_SUCCESS) {
11131    error_reporter.Run(rc);
11132    return;
11133  }
11134  transceiver_->SendCommand(command, parser);
11135}
11136
11137TPM_RC Tpm::MakeCredentialSync(const TPMI_DH_OBJECT& handle,
11138                               const std::string& handle_name,
11139                               const TPM2B_DIGEST& credential,
11140                               const TPM2B_NAME& object_name,
11141                               TPM2B_ID_OBJECT* credential_blob,
11142                               TPM2B_ENCRYPTED_SECRET* secret,
11143                               AuthorizationDelegate* authorization_delegate) {
11144  VLOG(1) << __func__;
11145  std::string command;
11146  TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11147                                              object_name, &command,
11148                                              authorization_delegate);
11149  if (rc != TPM_RC_SUCCESS) {
11150    return rc;
11151  }
11152  std::string response = transceiver_->SendCommandAndWait(command);
11153  rc = ParseResponse_MakeCredential(response, credential_blob, secret,
11154                                    authorization_delegate);
11155  return rc;
11156}
11157
11158TPM_RC Tpm::SerializeCommand_Unseal(
11159    const TPMI_DH_OBJECT& item_handle,
11160    const std::string& item_handle_name,
11161    std::string* serialized_command,
11162    AuthorizationDelegate* authorization_delegate) {
11163  VLOG(3) << __func__;
11164  TPM_RC rc = TPM_RC_SUCCESS;
11165  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11166  UINT32 command_size = 10;  // Header size.
11167  std::string handle_section_bytes;
11168  std::string parameter_section_bytes;
11169  TPM_CC command_code = TPM_CC_Unseal;
11170  bool is_command_parameter_encryption_possible = false;
11171  bool is_response_parameter_encryption_possible = true;
11172  std::string command_code_bytes;
11173  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11174  if (rc != TPM_RC_SUCCESS) {
11175    return rc;
11176  }
11177  std::string item_handle_bytes;
11178  rc = Serialize_TPMI_DH_OBJECT(item_handle, &item_handle_bytes);
11179  if (rc != TPM_RC_SUCCESS) {
11180    return rc;
11181  }
11182  std::unique_ptr<crypto::SecureHash> hash(
11183      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11184  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11185  hash->Update(item_handle_name.data(), item_handle_name.size());
11186  handle_section_bytes += item_handle_bytes;
11187  command_size += item_handle_bytes.size();
11188  std::string command_hash(32, 0);
11189  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
11190  std::string authorization_section_bytes;
11191  std::string authorization_size_bytes;
11192  if (authorization_delegate) {
11193    if (!authorization_delegate->GetCommandAuthorization(
11194            command_hash, is_command_parameter_encryption_possible,
11195            is_response_parameter_encryption_possible,
11196            &authorization_section_bytes)) {
11197      return TRUNKS_RC_AUTHORIZATION_FAILED;
11198    }
11199    if (!authorization_section_bytes.empty()) {
11200      tag = TPM_ST_SESSIONS;
11201      std::string tmp;
11202      rc = Serialize_UINT32(authorization_section_bytes.size(),
11203                            &authorization_size_bytes);
11204      if (rc != TPM_RC_SUCCESS) {
11205        return rc;
11206      }
11207      command_size +=
11208          authorization_size_bytes.size() + authorization_section_bytes.size();
11209    }
11210  }
11211  std::string tag_bytes;
11212  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11213  if (rc != TPM_RC_SUCCESS) {
11214    return rc;
11215  }
11216  std::string command_size_bytes;
11217  rc = Serialize_UINT32(command_size, &command_size_bytes);
11218  if (rc != TPM_RC_SUCCESS) {
11219    return rc;
11220  }
11221  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11222                        handle_section_bytes + authorization_size_bytes +
11223                        authorization_section_bytes + parameter_section_bytes;
11224  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11225  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
11226                                            serialized_command->size());
11227  return TPM_RC_SUCCESS;
11228}
11229
11230TPM_RC Tpm::ParseResponse_Unseal(
11231    const std::string& response,
11232    TPM2B_SENSITIVE_DATA* out_data,
11233    AuthorizationDelegate* authorization_delegate) {
11234  VLOG(3) << __func__;
11235  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11236  TPM_RC rc = TPM_RC_SUCCESS;
11237  std::string buffer(response);
11238  TPM_ST tag;
11239  std::string tag_bytes;
11240  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11241  if (rc != TPM_RC_SUCCESS) {
11242    return rc;
11243  }
11244  UINT32 response_size;
11245  std::string response_size_bytes;
11246  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11247  if (rc != TPM_RC_SUCCESS) {
11248    return rc;
11249  }
11250  TPM_RC response_code;
11251  std::string response_code_bytes;
11252  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11253  if (rc != TPM_RC_SUCCESS) {
11254    return rc;
11255  }
11256  if (response_size != response.size()) {
11257    return TPM_RC_SIZE;
11258  }
11259  if (response_code != TPM_RC_SUCCESS) {
11260    return response_code;
11261  }
11262  TPM_CC command_code = TPM_CC_Unseal;
11263  std::string command_code_bytes;
11264  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11265  if (rc != TPM_RC_SUCCESS) {
11266    return rc;
11267  }
11268  std::string authorization_section_bytes;
11269  if (tag == TPM_ST_SESSIONS) {
11270    UINT32 parameter_section_size = buffer.size();
11271    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11272    if (rc != TPM_RC_SUCCESS) {
11273      return rc;
11274    }
11275    if (parameter_section_size > buffer.size()) {
11276      return TPM_RC_INSUFFICIENT;
11277    }
11278    authorization_section_bytes = buffer.substr(parameter_section_size);
11279    // Keep the parameter section in |buffer|.
11280    buffer.erase(parameter_section_size);
11281  }
11282  std::unique_ptr<crypto::SecureHash> hash(
11283      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11284  hash->Update(response_code_bytes.data(), response_code_bytes.size());
11285  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11286  hash->Update(buffer.data(), buffer.size());
11287  std::string response_hash(32, 0);
11288  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
11289  if (tag == TPM_ST_SESSIONS) {
11290    CHECK(authorization_delegate) << "Authorization delegate missing!";
11291    if (!authorization_delegate->CheckResponseAuthorization(
11292            response_hash, authorization_section_bytes)) {
11293      return TRUNKS_RC_AUTHORIZATION_FAILED;
11294    }
11295  }
11296  std::string out_data_bytes;
11297  rc = Parse_TPM2B_SENSITIVE_DATA(&buffer, out_data, &out_data_bytes);
11298  if (rc != TPM_RC_SUCCESS) {
11299    return rc;
11300  }
11301  if (tag == TPM_ST_SESSIONS) {
11302    CHECK(authorization_delegate) << "Authorization delegate missing!";
11303    // Decrypt just the parameter data, not the size.
11304    std::string tmp = out_data_bytes.substr(2);
11305    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
11306      return TRUNKS_RC_ENCRYPTION_FAILED;
11307    }
11308    out_data_bytes.replace(2, std::string::npos, tmp);
11309    rc = Parse_TPM2B_SENSITIVE_DATA(&out_data_bytes, out_data, nullptr);
11310    if (rc != TPM_RC_SUCCESS) {
11311      return rc;
11312    }
11313  }
11314  return TPM_RC_SUCCESS;
11315}
11316
11317void UnsealErrorCallback(const Tpm::UnsealResponse& callback,
11318                         TPM_RC response_code) {
11319  VLOG(1) << __func__;
11320  callback.Run(response_code, TPM2B_SENSITIVE_DATA());
11321}
11322
11323void UnsealResponseParser(const Tpm::UnsealResponse& callback,
11324                          AuthorizationDelegate* authorization_delegate,
11325                          const std::string& response) {
11326  VLOG(1) << __func__;
11327  base::Callback<void(TPM_RC)> error_reporter =
11328      base::Bind(UnsealErrorCallback, callback);
11329  TPM2B_SENSITIVE_DATA out_data;
11330  TPM_RC rc =
11331      Tpm::ParseResponse_Unseal(response, &out_data, authorization_delegate);
11332  if (rc != TPM_RC_SUCCESS) {
11333    error_reporter.Run(rc);
11334    return;
11335  }
11336  callback.Run(rc, out_data);
11337}
11338
11339void Tpm::Unseal(const TPMI_DH_OBJECT& item_handle,
11340                 const std::string& item_handle_name,
11341                 AuthorizationDelegate* authorization_delegate,
11342                 const UnsealResponse& callback) {
11343  VLOG(1) << __func__;
11344  base::Callback<void(TPM_RC)> error_reporter =
11345      base::Bind(UnsealErrorCallback, callback);
11346  base::Callback<void(const std::string&)> parser =
11347      base::Bind(UnsealResponseParser, callback, authorization_delegate);
11348  std::string command;
11349  TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11350                                      authorization_delegate);
11351  if (rc != TPM_RC_SUCCESS) {
11352    error_reporter.Run(rc);
11353    return;
11354  }
11355  transceiver_->SendCommand(command, parser);
11356}
11357
11358TPM_RC Tpm::UnsealSync(const TPMI_DH_OBJECT& item_handle,
11359                       const std::string& item_handle_name,
11360                       TPM2B_SENSITIVE_DATA* out_data,
11361                       AuthorizationDelegate* authorization_delegate) {
11362  VLOG(1) << __func__;
11363  std::string command;
11364  TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11365                                      authorization_delegate);
11366  if (rc != TPM_RC_SUCCESS) {
11367    return rc;
11368  }
11369  std::string response = transceiver_->SendCommandAndWait(command);
11370  rc = ParseResponse_Unseal(response, out_data, authorization_delegate);
11371  return rc;
11372}
11373
11374TPM_RC Tpm::SerializeCommand_ObjectChangeAuth(
11375    const TPMI_DH_OBJECT& object_handle,
11376    const std::string& object_handle_name,
11377    const TPMI_DH_OBJECT& parent_handle,
11378    const std::string& parent_handle_name,
11379    const TPM2B_AUTH& new_auth,
11380    std::string* serialized_command,
11381    AuthorizationDelegate* authorization_delegate) {
11382  VLOG(3) << __func__;
11383  TPM_RC rc = TPM_RC_SUCCESS;
11384  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11385  UINT32 command_size = 10;  // Header size.
11386  std::string handle_section_bytes;
11387  std::string parameter_section_bytes;
11388  TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11389  bool is_command_parameter_encryption_possible = true;
11390  bool is_response_parameter_encryption_possible = true;
11391  std::string command_code_bytes;
11392  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11393  if (rc != TPM_RC_SUCCESS) {
11394    return rc;
11395  }
11396  std::string object_handle_bytes;
11397  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11398  if (rc != TPM_RC_SUCCESS) {
11399    return rc;
11400  }
11401  std::string parent_handle_bytes;
11402  rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
11403  if (rc != TPM_RC_SUCCESS) {
11404    return rc;
11405  }
11406  std::string new_auth_bytes;
11407  rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
11408  if (rc != TPM_RC_SUCCESS) {
11409    return rc;
11410  }
11411  if (authorization_delegate) {
11412    // Encrypt just the parameter data, not the size.
11413    std::string tmp = new_auth_bytes.substr(2);
11414    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11415      return TRUNKS_RC_ENCRYPTION_FAILED;
11416    }
11417    new_auth_bytes.replace(2, std::string::npos, tmp);
11418  }
11419  std::unique_ptr<crypto::SecureHash> hash(
11420      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11421  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11422  hash->Update(object_handle_name.data(), object_handle_name.size());
11423  handle_section_bytes += object_handle_bytes;
11424  command_size += object_handle_bytes.size();
11425  hash->Update(parent_handle_name.data(), parent_handle_name.size());
11426  handle_section_bytes += parent_handle_bytes;
11427  command_size += parent_handle_bytes.size();
11428  hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
11429  parameter_section_bytes += new_auth_bytes;
11430  command_size += new_auth_bytes.size();
11431  std::string command_hash(32, 0);
11432  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
11433  std::string authorization_section_bytes;
11434  std::string authorization_size_bytes;
11435  if (authorization_delegate) {
11436    if (!authorization_delegate->GetCommandAuthorization(
11437            command_hash, is_command_parameter_encryption_possible,
11438            is_response_parameter_encryption_possible,
11439            &authorization_section_bytes)) {
11440      return TRUNKS_RC_AUTHORIZATION_FAILED;
11441    }
11442    if (!authorization_section_bytes.empty()) {
11443      tag = TPM_ST_SESSIONS;
11444      std::string tmp;
11445      rc = Serialize_UINT32(authorization_section_bytes.size(),
11446                            &authorization_size_bytes);
11447      if (rc != TPM_RC_SUCCESS) {
11448        return rc;
11449      }
11450      command_size +=
11451          authorization_size_bytes.size() + authorization_section_bytes.size();
11452    }
11453  }
11454  std::string tag_bytes;
11455  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11456  if (rc != TPM_RC_SUCCESS) {
11457    return rc;
11458  }
11459  std::string command_size_bytes;
11460  rc = Serialize_UINT32(command_size, &command_size_bytes);
11461  if (rc != TPM_RC_SUCCESS) {
11462    return rc;
11463  }
11464  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11465                        handle_section_bytes + authorization_size_bytes +
11466                        authorization_section_bytes + parameter_section_bytes;
11467  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11468  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
11469                                            serialized_command->size());
11470  return TPM_RC_SUCCESS;
11471}
11472
11473TPM_RC Tpm::ParseResponse_ObjectChangeAuth(
11474    const std::string& response,
11475    TPM2B_PRIVATE* out_private,
11476    AuthorizationDelegate* authorization_delegate) {
11477  VLOG(3) << __func__;
11478  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11479  TPM_RC rc = TPM_RC_SUCCESS;
11480  std::string buffer(response);
11481  TPM_ST tag;
11482  std::string tag_bytes;
11483  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11484  if (rc != TPM_RC_SUCCESS) {
11485    return rc;
11486  }
11487  UINT32 response_size;
11488  std::string response_size_bytes;
11489  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11490  if (rc != TPM_RC_SUCCESS) {
11491    return rc;
11492  }
11493  TPM_RC response_code;
11494  std::string response_code_bytes;
11495  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11496  if (rc != TPM_RC_SUCCESS) {
11497    return rc;
11498  }
11499  if (response_size != response.size()) {
11500    return TPM_RC_SIZE;
11501  }
11502  if (response_code != TPM_RC_SUCCESS) {
11503    return response_code;
11504  }
11505  TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11506  std::string command_code_bytes;
11507  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11508  if (rc != TPM_RC_SUCCESS) {
11509    return rc;
11510  }
11511  std::string authorization_section_bytes;
11512  if (tag == TPM_ST_SESSIONS) {
11513    UINT32 parameter_section_size = buffer.size();
11514    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11515    if (rc != TPM_RC_SUCCESS) {
11516      return rc;
11517    }
11518    if (parameter_section_size > buffer.size()) {
11519      return TPM_RC_INSUFFICIENT;
11520    }
11521    authorization_section_bytes = buffer.substr(parameter_section_size);
11522    // Keep the parameter section in |buffer|.
11523    buffer.erase(parameter_section_size);
11524  }
11525  std::unique_ptr<crypto::SecureHash> hash(
11526      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11527  hash->Update(response_code_bytes.data(), response_code_bytes.size());
11528  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11529  hash->Update(buffer.data(), buffer.size());
11530  std::string response_hash(32, 0);
11531  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
11532  if (tag == TPM_ST_SESSIONS) {
11533    CHECK(authorization_delegate) << "Authorization delegate missing!";
11534    if (!authorization_delegate->CheckResponseAuthorization(
11535            response_hash, authorization_section_bytes)) {
11536      return TRUNKS_RC_AUTHORIZATION_FAILED;
11537    }
11538  }
11539  std::string out_private_bytes;
11540  rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
11541  if (rc != TPM_RC_SUCCESS) {
11542    return rc;
11543  }
11544  if (tag == TPM_ST_SESSIONS) {
11545    CHECK(authorization_delegate) << "Authorization delegate missing!";
11546    // Decrypt just the parameter data, not the size.
11547    std::string tmp = out_private_bytes.substr(2);
11548    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
11549      return TRUNKS_RC_ENCRYPTION_FAILED;
11550    }
11551    out_private_bytes.replace(2, std::string::npos, tmp);
11552    rc = Parse_TPM2B_PRIVATE(&out_private_bytes, out_private, nullptr);
11553    if (rc != TPM_RC_SUCCESS) {
11554      return rc;
11555    }
11556  }
11557  return TPM_RC_SUCCESS;
11558}
11559
11560void ObjectChangeAuthErrorCallback(
11561    const Tpm::ObjectChangeAuthResponse& callback,
11562    TPM_RC response_code) {
11563  VLOG(1) << __func__;
11564  callback.Run(response_code, TPM2B_PRIVATE());
11565}
11566
11567void ObjectChangeAuthResponseParser(
11568    const Tpm::ObjectChangeAuthResponse& callback,
11569    AuthorizationDelegate* authorization_delegate,
11570    const std::string& response) {
11571  VLOG(1) << __func__;
11572  base::Callback<void(TPM_RC)> error_reporter =
11573      base::Bind(ObjectChangeAuthErrorCallback, callback);
11574  TPM2B_PRIVATE out_private;
11575  TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth(response, &out_private,
11576                                                  authorization_delegate);
11577  if (rc != TPM_RC_SUCCESS) {
11578    error_reporter.Run(rc);
11579    return;
11580  }
11581  callback.Run(rc, out_private);
11582}
11583
11584void Tpm::ObjectChangeAuth(const TPMI_DH_OBJECT& object_handle,
11585                           const std::string& object_handle_name,
11586                           const TPMI_DH_OBJECT& parent_handle,
11587                           const std::string& parent_handle_name,
11588                           const TPM2B_AUTH& new_auth,
11589                           AuthorizationDelegate* authorization_delegate,
11590                           const ObjectChangeAuthResponse& callback) {
11591  VLOG(1) << __func__;
11592  base::Callback<void(TPM_RC)> error_reporter =
11593      base::Bind(ObjectChangeAuthErrorCallback, callback);
11594  base::Callback<void(const std::string&)> parser = base::Bind(
11595      ObjectChangeAuthResponseParser, callback, authorization_delegate);
11596  std::string command;
11597  TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11598      object_handle, object_handle_name, parent_handle, parent_handle_name,
11599      new_auth, &command, authorization_delegate);
11600  if (rc != TPM_RC_SUCCESS) {
11601    error_reporter.Run(rc);
11602    return;
11603  }
11604  transceiver_->SendCommand(command, parser);
11605}
11606
11607TPM_RC Tpm::ObjectChangeAuthSync(
11608    const TPMI_DH_OBJECT& object_handle,
11609    const std::string& object_handle_name,
11610    const TPMI_DH_OBJECT& parent_handle,
11611    const std::string& parent_handle_name,
11612    const TPM2B_AUTH& new_auth,
11613    TPM2B_PRIVATE* out_private,
11614    AuthorizationDelegate* authorization_delegate) {
11615  VLOG(1) << __func__;
11616  std::string command;
11617  TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11618      object_handle, object_handle_name, parent_handle, parent_handle_name,
11619      new_auth, &command, authorization_delegate);
11620  if (rc != TPM_RC_SUCCESS) {
11621    return rc;
11622  }
11623  std::string response = transceiver_->SendCommandAndWait(command);
11624  rc = ParseResponse_ObjectChangeAuth(response, out_private,
11625                                      authorization_delegate);
11626  return rc;
11627}
11628
11629TPM_RC Tpm::SerializeCommand_Duplicate(
11630    const TPMI_DH_OBJECT& object_handle,
11631    const std::string& object_handle_name,
11632    const TPMI_DH_OBJECT& new_parent_handle,
11633    const std::string& new_parent_handle_name,
11634    const TPM2B_DATA& encryption_key_in,
11635    const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11636    std::string* serialized_command,
11637    AuthorizationDelegate* authorization_delegate) {
11638  VLOG(3) << __func__;
11639  TPM_RC rc = TPM_RC_SUCCESS;
11640  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11641  UINT32 command_size = 10;  // Header size.
11642  std::string handle_section_bytes;
11643  std::string parameter_section_bytes;
11644  TPM_CC command_code = TPM_CC_Duplicate;
11645  bool is_command_parameter_encryption_possible = true;
11646  bool is_response_parameter_encryption_possible = true;
11647  std::string command_code_bytes;
11648  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11649  if (rc != TPM_RC_SUCCESS) {
11650    return rc;
11651  }
11652  std::string object_handle_bytes;
11653  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11654  if (rc != TPM_RC_SUCCESS) {
11655    return rc;
11656  }
11657  std::string new_parent_handle_bytes;
11658  rc = Serialize_TPMI_DH_OBJECT(new_parent_handle, &new_parent_handle_bytes);
11659  if (rc != TPM_RC_SUCCESS) {
11660    return rc;
11661  }
11662  std::string encryption_key_in_bytes;
11663  rc = Serialize_TPM2B_DATA(encryption_key_in, &encryption_key_in_bytes);
11664  if (rc != TPM_RC_SUCCESS) {
11665    return rc;
11666  }
11667  std::string symmetric_alg_bytes;
11668  rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
11669  if (rc != TPM_RC_SUCCESS) {
11670    return rc;
11671  }
11672  if (authorization_delegate) {
11673    // Encrypt just the parameter data, not the size.
11674    std::string tmp = encryption_key_in_bytes.substr(2);
11675    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11676      return TRUNKS_RC_ENCRYPTION_FAILED;
11677    }
11678    encryption_key_in_bytes.replace(2, std::string::npos, tmp);
11679  }
11680  std::unique_ptr<crypto::SecureHash> hash(
11681      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11682  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11683  hash->Update(object_handle_name.data(), object_handle_name.size());
11684  handle_section_bytes += object_handle_bytes;
11685  command_size += object_handle_bytes.size();
11686  hash->Update(new_parent_handle_name.data(), new_parent_handle_name.size());
11687  handle_section_bytes += new_parent_handle_bytes;
11688  command_size += new_parent_handle_bytes.size();
11689  hash->Update(encryption_key_in_bytes.data(), encryption_key_in_bytes.size());
11690  parameter_section_bytes += encryption_key_in_bytes;
11691  command_size += encryption_key_in_bytes.size();
11692  hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
11693  parameter_section_bytes += symmetric_alg_bytes;
11694  command_size += symmetric_alg_bytes.size();
11695  std::string command_hash(32, 0);
11696  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
11697  std::string authorization_section_bytes;
11698  std::string authorization_size_bytes;
11699  if (authorization_delegate) {
11700    if (!authorization_delegate->GetCommandAuthorization(
11701            command_hash, is_command_parameter_encryption_possible,
11702            is_response_parameter_encryption_possible,
11703            &authorization_section_bytes)) {
11704      return TRUNKS_RC_AUTHORIZATION_FAILED;
11705    }
11706    if (!authorization_section_bytes.empty()) {
11707      tag = TPM_ST_SESSIONS;
11708      std::string tmp;
11709      rc = Serialize_UINT32(authorization_section_bytes.size(),
11710                            &authorization_size_bytes);
11711      if (rc != TPM_RC_SUCCESS) {
11712        return rc;
11713      }
11714      command_size +=
11715          authorization_size_bytes.size() + authorization_section_bytes.size();
11716    }
11717  }
11718  std::string tag_bytes;
11719  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11720  if (rc != TPM_RC_SUCCESS) {
11721    return rc;
11722  }
11723  std::string command_size_bytes;
11724  rc = Serialize_UINT32(command_size, &command_size_bytes);
11725  if (rc != TPM_RC_SUCCESS) {
11726    return rc;
11727  }
11728  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11729                        handle_section_bytes + authorization_size_bytes +
11730                        authorization_section_bytes + parameter_section_bytes;
11731  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11732  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
11733                                            serialized_command->size());
11734  return TPM_RC_SUCCESS;
11735}
11736
11737TPM_RC Tpm::ParseResponse_Duplicate(
11738    const std::string& response,
11739    TPM2B_DATA* encryption_key_out,
11740    TPM2B_PRIVATE* duplicate,
11741    TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11742    AuthorizationDelegate* authorization_delegate) {
11743  VLOG(3) << __func__;
11744  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11745  TPM_RC rc = TPM_RC_SUCCESS;
11746  std::string buffer(response);
11747  TPM_ST tag;
11748  std::string tag_bytes;
11749  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11750  if (rc != TPM_RC_SUCCESS) {
11751    return rc;
11752  }
11753  UINT32 response_size;
11754  std::string response_size_bytes;
11755  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11756  if (rc != TPM_RC_SUCCESS) {
11757    return rc;
11758  }
11759  TPM_RC response_code;
11760  std::string response_code_bytes;
11761  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11762  if (rc != TPM_RC_SUCCESS) {
11763    return rc;
11764  }
11765  if (response_size != response.size()) {
11766    return TPM_RC_SIZE;
11767  }
11768  if (response_code != TPM_RC_SUCCESS) {
11769    return response_code;
11770  }
11771  TPM_CC command_code = TPM_CC_Duplicate;
11772  std::string command_code_bytes;
11773  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11774  if (rc != TPM_RC_SUCCESS) {
11775    return rc;
11776  }
11777  std::string authorization_section_bytes;
11778  if (tag == TPM_ST_SESSIONS) {
11779    UINT32 parameter_section_size = buffer.size();
11780    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11781    if (rc != TPM_RC_SUCCESS) {
11782      return rc;
11783    }
11784    if (parameter_section_size > buffer.size()) {
11785      return TPM_RC_INSUFFICIENT;
11786    }
11787    authorization_section_bytes = buffer.substr(parameter_section_size);
11788    // Keep the parameter section in |buffer|.
11789    buffer.erase(parameter_section_size);
11790  }
11791  std::unique_ptr<crypto::SecureHash> hash(
11792      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11793  hash->Update(response_code_bytes.data(), response_code_bytes.size());
11794  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11795  hash->Update(buffer.data(), buffer.size());
11796  std::string response_hash(32, 0);
11797  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
11798  if (tag == TPM_ST_SESSIONS) {
11799    CHECK(authorization_delegate) << "Authorization delegate missing!";
11800    if (!authorization_delegate->CheckResponseAuthorization(
11801            response_hash, authorization_section_bytes)) {
11802      return TRUNKS_RC_AUTHORIZATION_FAILED;
11803    }
11804  }
11805  std::string encryption_key_out_bytes;
11806  rc = Parse_TPM2B_DATA(&buffer, encryption_key_out, &encryption_key_out_bytes);
11807  if (rc != TPM_RC_SUCCESS) {
11808    return rc;
11809  }
11810  std::string duplicate_bytes;
11811  rc = Parse_TPM2B_PRIVATE(&buffer, duplicate, &duplicate_bytes);
11812  if (rc != TPM_RC_SUCCESS) {
11813    return rc;
11814  }
11815  std::string out_sym_seed_bytes;
11816  rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
11817  if (rc != TPM_RC_SUCCESS) {
11818    return rc;
11819  }
11820  if (tag == TPM_ST_SESSIONS) {
11821    CHECK(authorization_delegate) << "Authorization delegate missing!";
11822    // Decrypt just the parameter data, not the size.
11823    std::string tmp = encryption_key_out_bytes.substr(2);
11824    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
11825      return TRUNKS_RC_ENCRYPTION_FAILED;
11826    }
11827    encryption_key_out_bytes.replace(2, std::string::npos, tmp);
11828    rc = Parse_TPM2B_DATA(&encryption_key_out_bytes, encryption_key_out,
11829                          nullptr);
11830    if (rc != TPM_RC_SUCCESS) {
11831      return rc;
11832    }
11833  }
11834  return TPM_RC_SUCCESS;
11835}
11836
11837void DuplicateErrorCallback(const Tpm::DuplicateResponse& callback,
11838                            TPM_RC response_code) {
11839  VLOG(1) << __func__;
11840  callback.Run(response_code, TPM2B_DATA(), TPM2B_PRIVATE(),
11841               TPM2B_ENCRYPTED_SECRET());
11842}
11843
11844void DuplicateResponseParser(const Tpm::DuplicateResponse& callback,
11845                             AuthorizationDelegate* authorization_delegate,
11846                             const std::string& response) {
11847  VLOG(1) << __func__;
11848  base::Callback<void(TPM_RC)> error_reporter =
11849      base::Bind(DuplicateErrorCallback, callback);
11850  TPM2B_DATA encryption_key_out;
11851  TPM2B_PRIVATE duplicate;
11852  TPM2B_ENCRYPTED_SECRET out_sym_seed;
11853  TPM_RC rc =
11854      Tpm::ParseResponse_Duplicate(response, &encryption_key_out, &duplicate,
11855                                   &out_sym_seed, authorization_delegate);
11856  if (rc != TPM_RC_SUCCESS) {
11857    error_reporter.Run(rc);
11858    return;
11859  }
11860  callback.Run(rc, encryption_key_out, duplicate, out_sym_seed);
11861}
11862
11863void Tpm::Duplicate(const TPMI_DH_OBJECT& object_handle,
11864                    const std::string& object_handle_name,
11865                    const TPMI_DH_OBJECT& new_parent_handle,
11866                    const std::string& new_parent_handle_name,
11867                    const TPM2B_DATA& encryption_key_in,
11868                    const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11869                    AuthorizationDelegate* authorization_delegate,
11870                    const DuplicateResponse& callback) {
11871  VLOG(1) << __func__;
11872  base::Callback<void(TPM_RC)> error_reporter =
11873      base::Bind(DuplicateErrorCallback, callback);
11874  base::Callback<void(const std::string&)> parser =
11875      base::Bind(DuplicateResponseParser, callback, authorization_delegate);
11876  std::string command;
11877  TPM_RC rc = SerializeCommand_Duplicate(
11878      object_handle, object_handle_name, new_parent_handle,
11879      new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11880      authorization_delegate);
11881  if (rc != TPM_RC_SUCCESS) {
11882    error_reporter.Run(rc);
11883    return;
11884  }
11885  transceiver_->SendCommand(command, parser);
11886}
11887
11888TPM_RC Tpm::DuplicateSync(const TPMI_DH_OBJECT& object_handle,
11889                          const std::string& object_handle_name,
11890                          const TPMI_DH_OBJECT& new_parent_handle,
11891                          const std::string& new_parent_handle_name,
11892                          const TPM2B_DATA& encryption_key_in,
11893                          const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11894                          TPM2B_DATA* encryption_key_out,
11895                          TPM2B_PRIVATE* duplicate,
11896                          TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11897                          AuthorizationDelegate* authorization_delegate) {
11898  VLOG(1) << __func__;
11899  std::string command;
11900  TPM_RC rc = SerializeCommand_Duplicate(
11901      object_handle, object_handle_name, new_parent_handle,
11902      new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11903      authorization_delegate);
11904  if (rc != TPM_RC_SUCCESS) {
11905    return rc;
11906  }
11907  std::string response = transceiver_->SendCommandAndWait(command);
11908  rc = ParseResponse_Duplicate(response, encryption_key_out, duplicate,
11909                               out_sym_seed, authorization_delegate);
11910  return rc;
11911}
11912
11913TPM_RC Tpm::SerializeCommand_Rewrap(
11914    const TPMI_DH_OBJECT& old_parent,
11915    const std::string& old_parent_name,
11916    const TPMI_DH_OBJECT& new_parent,
11917    const std::string& new_parent_name,
11918    const TPM2B_PRIVATE& in_duplicate,
11919    const TPM2B_NAME& name,
11920    const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
11921    std::string* serialized_command,
11922    AuthorizationDelegate* authorization_delegate) {
11923  VLOG(3) << __func__;
11924  TPM_RC rc = TPM_RC_SUCCESS;
11925  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11926  UINT32 command_size = 10;  // Header size.
11927  std::string handle_section_bytes;
11928  std::string parameter_section_bytes;
11929  TPM_CC command_code = TPM_CC_Rewrap;
11930  bool is_command_parameter_encryption_possible = true;
11931  bool is_response_parameter_encryption_possible = true;
11932  std::string command_code_bytes;
11933  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11934  if (rc != TPM_RC_SUCCESS) {
11935    return rc;
11936  }
11937  std::string old_parent_bytes;
11938  rc = Serialize_TPMI_DH_OBJECT(old_parent, &old_parent_bytes);
11939  if (rc != TPM_RC_SUCCESS) {
11940    return rc;
11941  }
11942  std::string new_parent_bytes;
11943  rc = Serialize_TPMI_DH_OBJECT(new_parent, &new_parent_bytes);
11944  if (rc != TPM_RC_SUCCESS) {
11945    return rc;
11946  }
11947  std::string in_duplicate_bytes;
11948  rc = Serialize_TPM2B_PRIVATE(in_duplicate, &in_duplicate_bytes);
11949  if (rc != TPM_RC_SUCCESS) {
11950    return rc;
11951  }
11952  std::string name_bytes;
11953  rc = Serialize_TPM2B_NAME(name, &name_bytes);
11954  if (rc != TPM_RC_SUCCESS) {
11955    return rc;
11956  }
11957  std::string in_sym_seed_bytes;
11958  rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
11959  if (rc != TPM_RC_SUCCESS) {
11960    return rc;
11961  }
11962  if (authorization_delegate) {
11963    // Encrypt just the parameter data, not the size.
11964    std::string tmp = in_duplicate_bytes.substr(2);
11965    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11966      return TRUNKS_RC_ENCRYPTION_FAILED;
11967    }
11968    in_duplicate_bytes.replace(2, std::string::npos, tmp);
11969  }
11970  std::unique_ptr<crypto::SecureHash> hash(
11971      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11972  hash->Update(command_code_bytes.data(), command_code_bytes.size());
11973  hash->Update(old_parent_name.data(), old_parent_name.size());
11974  handle_section_bytes += old_parent_bytes;
11975  command_size += old_parent_bytes.size();
11976  hash->Update(new_parent_name.data(), new_parent_name.size());
11977  handle_section_bytes += new_parent_bytes;
11978  command_size += new_parent_bytes.size();
11979  hash->Update(in_duplicate_bytes.data(), in_duplicate_bytes.size());
11980  parameter_section_bytes += in_duplicate_bytes;
11981  command_size += in_duplicate_bytes.size();
11982  hash->Update(name_bytes.data(), name_bytes.size());
11983  parameter_section_bytes += name_bytes;
11984  command_size += name_bytes.size();
11985  hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
11986  parameter_section_bytes += in_sym_seed_bytes;
11987  command_size += in_sym_seed_bytes.size();
11988  std::string command_hash(32, 0);
11989  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
11990  std::string authorization_section_bytes;
11991  std::string authorization_size_bytes;
11992  if (authorization_delegate) {
11993    if (!authorization_delegate->GetCommandAuthorization(
11994            command_hash, is_command_parameter_encryption_possible,
11995            is_response_parameter_encryption_possible,
11996            &authorization_section_bytes)) {
11997      return TRUNKS_RC_AUTHORIZATION_FAILED;
11998    }
11999    if (!authorization_section_bytes.empty()) {
12000      tag = TPM_ST_SESSIONS;
12001      std::string tmp;
12002      rc = Serialize_UINT32(authorization_section_bytes.size(),
12003                            &authorization_size_bytes);
12004      if (rc != TPM_RC_SUCCESS) {
12005        return rc;
12006      }
12007      command_size +=
12008          authorization_size_bytes.size() + authorization_section_bytes.size();
12009    }
12010  }
12011  std::string tag_bytes;
12012  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12013  if (rc != TPM_RC_SUCCESS) {
12014    return rc;
12015  }
12016  std::string command_size_bytes;
12017  rc = Serialize_UINT32(command_size, &command_size_bytes);
12018  if (rc != TPM_RC_SUCCESS) {
12019    return rc;
12020  }
12021  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12022                        handle_section_bytes + authorization_size_bytes +
12023                        authorization_section_bytes + parameter_section_bytes;
12024  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12025  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
12026                                            serialized_command->size());
12027  return TPM_RC_SUCCESS;
12028}
12029
12030TPM_RC Tpm::ParseResponse_Rewrap(
12031    const std::string& response,
12032    TPM2B_PRIVATE* out_duplicate,
12033    TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12034    AuthorizationDelegate* authorization_delegate) {
12035  VLOG(3) << __func__;
12036  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12037  TPM_RC rc = TPM_RC_SUCCESS;
12038  std::string buffer(response);
12039  TPM_ST tag;
12040  std::string tag_bytes;
12041  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12042  if (rc != TPM_RC_SUCCESS) {
12043    return rc;
12044  }
12045  UINT32 response_size;
12046  std::string response_size_bytes;
12047  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12048  if (rc != TPM_RC_SUCCESS) {
12049    return rc;
12050  }
12051  TPM_RC response_code;
12052  std::string response_code_bytes;
12053  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12054  if (rc != TPM_RC_SUCCESS) {
12055    return rc;
12056  }
12057  if (response_size != response.size()) {
12058    return TPM_RC_SIZE;
12059  }
12060  if (response_code != TPM_RC_SUCCESS) {
12061    return response_code;
12062  }
12063  TPM_CC command_code = TPM_CC_Rewrap;
12064  std::string command_code_bytes;
12065  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12066  if (rc != TPM_RC_SUCCESS) {
12067    return rc;
12068  }
12069  std::string authorization_section_bytes;
12070  if (tag == TPM_ST_SESSIONS) {
12071    UINT32 parameter_section_size = buffer.size();
12072    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12073    if (rc != TPM_RC_SUCCESS) {
12074      return rc;
12075    }
12076    if (parameter_section_size > buffer.size()) {
12077      return TPM_RC_INSUFFICIENT;
12078    }
12079    authorization_section_bytes = buffer.substr(parameter_section_size);
12080    // Keep the parameter section in |buffer|.
12081    buffer.erase(parameter_section_size);
12082  }
12083  std::unique_ptr<crypto::SecureHash> hash(
12084      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12085  hash->Update(response_code_bytes.data(), response_code_bytes.size());
12086  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12087  hash->Update(buffer.data(), buffer.size());
12088  std::string response_hash(32, 0);
12089  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
12090  if (tag == TPM_ST_SESSIONS) {
12091    CHECK(authorization_delegate) << "Authorization delegate missing!";
12092    if (!authorization_delegate->CheckResponseAuthorization(
12093            response_hash, authorization_section_bytes)) {
12094      return TRUNKS_RC_AUTHORIZATION_FAILED;
12095    }
12096  }
12097  std::string out_duplicate_bytes;
12098  rc = Parse_TPM2B_PRIVATE(&buffer, out_duplicate, &out_duplicate_bytes);
12099  if (rc != TPM_RC_SUCCESS) {
12100    return rc;
12101  }
12102  std::string out_sym_seed_bytes;
12103  rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
12104  if (rc != TPM_RC_SUCCESS) {
12105    return rc;
12106  }
12107  if (tag == TPM_ST_SESSIONS) {
12108    CHECK(authorization_delegate) << "Authorization delegate missing!";
12109    // Decrypt just the parameter data, not the size.
12110    std::string tmp = out_duplicate_bytes.substr(2);
12111    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
12112      return TRUNKS_RC_ENCRYPTION_FAILED;
12113    }
12114    out_duplicate_bytes.replace(2, std::string::npos, tmp);
12115    rc = Parse_TPM2B_PRIVATE(&out_duplicate_bytes, out_duplicate, nullptr);
12116    if (rc != TPM_RC_SUCCESS) {
12117      return rc;
12118    }
12119  }
12120  return TPM_RC_SUCCESS;
12121}
12122
12123void RewrapErrorCallback(const Tpm::RewrapResponse& callback,
12124                         TPM_RC response_code) {
12125  VLOG(1) << __func__;
12126  callback.Run(response_code, TPM2B_PRIVATE(), TPM2B_ENCRYPTED_SECRET());
12127}
12128
12129void RewrapResponseParser(const Tpm::RewrapResponse& callback,
12130                          AuthorizationDelegate* authorization_delegate,
12131                          const std::string& response) {
12132  VLOG(1) << __func__;
12133  base::Callback<void(TPM_RC)> error_reporter =
12134      base::Bind(RewrapErrorCallback, callback);
12135  TPM2B_PRIVATE out_duplicate;
12136  TPM2B_ENCRYPTED_SECRET out_sym_seed;
12137  TPM_RC rc = Tpm::ParseResponse_Rewrap(response, &out_duplicate, &out_sym_seed,
12138                                        authorization_delegate);
12139  if (rc != TPM_RC_SUCCESS) {
12140    error_reporter.Run(rc);
12141    return;
12142  }
12143  callback.Run(rc, out_duplicate, out_sym_seed);
12144}
12145
12146void Tpm::Rewrap(const TPMI_DH_OBJECT& old_parent,
12147                 const std::string& old_parent_name,
12148                 const TPMI_DH_OBJECT& new_parent,
12149                 const std::string& new_parent_name,
12150                 const TPM2B_PRIVATE& in_duplicate,
12151                 const TPM2B_NAME& name,
12152                 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12153                 AuthorizationDelegate* authorization_delegate,
12154                 const RewrapResponse& callback) {
12155  VLOG(1) << __func__;
12156  base::Callback<void(TPM_RC)> error_reporter =
12157      base::Bind(RewrapErrorCallback, callback);
12158  base::Callback<void(const std::string&)> parser =
12159      base::Bind(RewrapResponseParser, callback, authorization_delegate);
12160  std::string command;
12161  TPM_RC rc = SerializeCommand_Rewrap(
12162      old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12163      name, in_sym_seed, &command, authorization_delegate);
12164  if (rc != TPM_RC_SUCCESS) {
12165    error_reporter.Run(rc);
12166    return;
12167  }
12168  transceiver_->SendCommand(command, parser);
12169}
12170
12171TPM_RC Tpm::RewrapSync(const TPMI_DH_OBJECT& old_parent,
12172                       const std::string& old_parent_name,
12173                       const TPMI_DH_OBJECT& new_parent,
12174                       const std::string& new_parent_name,
12175                       const TPM2B_PRIVATE& in_duplicate,
12176                       const TPM2B_NAME& name,
12177                       const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12178                       TPM2B_PRIVATE* out_duplicate,
12179                       TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12180                       AuthorizationDelegate* authorization_delegate) {
12181  VLOG(1) << __func__;
12182  std::string command;
12183  TPM_RC rc = SerializeCommand_Rewrap(
12184      old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12185      name, in_sym_seed, &command, authorization_delegate);
12186  if (rc != TPM_RC_SUCCESS) {
12187    return rc;
12188  }
12189  std::string response = transceiver_->SendCommandAndWait(command);
12190  rc = ParseResponse_Rewrap(response, out_duplicate, out_sym_seed,
12191                            authorization_delegate);
12192  return rc;
12193}
12194
12195TPM_RC Tpm::SerializeCommand_Import(
12196    const TPMI_DH_OBJECT& parent_handle,
12197    const std::string& parent_handle_name,
12198    const TPM2B_DATA& encryption_key,
12199    const TPM2B_PUBLIC& object_public,
12200    const TPM2B_PRIVATE& duplicate,
12201    const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12202    const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12203    std::string* serialized_command,
12204    AuthorizationDelegate* authorization_delegate) {
12205  VLOG(3) << __func__;
12206  TPM_RC rc = TPM_RC_SUCCESS;
12207  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12208  UINT32 command_size = 10;  // Header size.
12209  std::string handle_section_bytes;
12210  std::string parameter_section_bytes;
12211  TPM_CC command_code = TPM_CC_Import;
12212  bool is_command_parameter_encryption_possible = true;
12213  bool is_response_parameter_encryption_possible = true;
12214  std::string command_code_bytes;
12215  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12216  if (rc != TPM_RC_SUCCESS) {
12217    return rc;
12218  }
12219  std::string parent_handle_bytes;
12220  rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
12221  if (rc != TPM_RC_SUCCESS) {
12222    return rc;
12223  }
12224  std::string encryption_key_bytes;
12225  rc = Serialize_TPM2B_DATA(encryption_key, &encryption_key_bytes);
12226  if (rc != TPM_RC_SUCCESS) {
12227    return rc;
12228  }
12229  std::string object_public_bytes;
12230  rc = Serialize_TPM2B_PUBLIC(object_public, &object_public_bytes);
12231  if (rc != TPM_RC_SUCCESS) {
12232    return rc;
12233  }
12234  std::string duplicate_bytes;
12235  rc = Serialize_TPM2B_PRIVATE(duplicate, &duplicate_bytes);
12236  if (rc != TPM_RC_SUCCESS) {
12237    return rc;
12238  }
12239  std::string in_sym_seed_bytes;
12240  rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12241  if (rc != TPM_RC_SUCCESS) {
12242    return rc;
12243  }
12244  std::string symmetric_alg_bytes;
12245  rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
12246  if (rc != TPM_RC_SUCCESS) {
12247    return rc;
12248  }
12249  if (authorization_delegate) {
12250    // Encrypt just the parameter data, not the size.
12251    std::string tmp = encryption_key_bytes.substr(2);
12252    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12253      return TRUNKS_RC_ENCRYPTION_FAILED;
12254    }
12255    encryption_key_bytes.replace(2, std::string::npos, tmp);
12256  }
12257  std::unique_ptr<crypto::SecureHash> hash(
12258      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12259  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12260  hash->Update(parent_handle_name.data(), parent_handle_name.size());
12261  handle_section_bytes += parent_handle_bytes;
12262  command_size += parent_handle_bytes.size();
12263  hash->Update(encryption_key_bytes.data(), encryption_key_bytes.size());
12264  parameter_section_bytes += encryption_key_bytes;
12265  command_size += encryption_key_bytes.size();
12266  hash->Update(object_public_bytes.data(), object_public_bytes.size());
12267  parameter_section_bytes += object_public_bytes;
12268  command_size += object_public_bytes.size();
12269  hash->Update(duplicate_bytes.data(), duplicate_bytes.size());
12270  parameter_section_bytes += duplicate_bytes;
12271  command_size += duplicate_bytes.size();
12272  hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12273  parameter_section_bytes += in_sym_seed_bytes;
12274  command_size += in_sym_seed_bytes.size();
12275  hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
12276  parameter_section_bytes += symmetric_alg_bytes;
12277  command_size += symmetric_alg_bytes.size();
12278  std::string command_hash(32, 0);
12279  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
12280  std::string authorization_section_bytes;
12281  std::string authorization_size_bytes;
12282  if (authorization_delegate) {
12283    if (!authorization_delegate->GetCommandAuthorization(
12284            command_hash, is_command_parameter_encryption_possible,
12285            is_response_parameter_encryption_possible,
12286            &authorization_section_bytes)) {
12287      return TRUNKS_RC_AUTHORIZATION_FAILED;
12288    }
12289    if (!authorization_section_bytes.empty()) {
12290      tag = TPM_ST_SESSIONS;
12291      std::string tmp;
12292      rc = Serialize_UINT32(authorization_section_bytes.size(),
12293                            &authorization_size_bytes);
12294      if (rc != TPM_RC_SUCCESS) {
12295        return rc;
12296      }
12297      command_size +=
12298          authorization_size_bytes.size() + authorization_section_bytes.size();
12299    }
12300  }
12301  std::string tag_bytes;
12302  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12303  if (rc != TPM_RC_SUCCESS) {
12304    return rc;
12305  }
12306  std::string command_size_bytes;
12307  rc = Serialize_UINT32(command_size, &command_size_bytes);
12308  if (rc != TPM_RC_SUCCESS) {
12309    return rc;
12310  }
12311  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12312                        handle_section_bytes + authorization_size_bytes +
12313                        authorization_section_bytes + parameter_section_bytes;
12314  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12315  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
12316                                            serialized_command->size());
12317  return TPM_RC_SUCCESS;
12318}
12319
12320TPM_RC Tpm::ParseResponse_Import(
12321    const std::string& response,
12322    TPM2B_PRIVATE* out_private,
12323    AuthorizationDelegate* authorization_delegate) {
12324  VLOG(3) << __func__;
12325  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12326  TPM_RC rc = TPM_RC_SUCCESS;
12327  std::string buffer(response);
12328  TPM_ST tag;
12329  std::string tag_bytes;
12330  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12331  if (rc != TPM_RC_SUCCESS) {
12332    return rc;
12333  }
12334  UINT32 response_size;
12335  std::string response_size_bytes;
12336  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12337  if (rc != TPM_RC_SUCCESS) {
12338    return rc;
12339  }
12340  TPM_RC response_code;
12341  std::string response_code_bytes;
12342  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12343  if (rc != TPM_RC_SUCCESS) {
12344    return rc;
12345  }
12346  if (response_size != response.size()) {
12347    return TPM_RC_SIZE;
12348  }
12349  if (response_code != TPM_RC_SUCCESS) {
12350    return response_code;
12351  }
12352  TPM_CC command_code = TPM_CC_Import;
12353  std::string command_code_bytes;
12354  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12355  if (rc != TPM_RC_SUCCESS) {
12356    return rc;
12357  }
12358  std::string authorization_section_bytes;
12359  if (tag == TPM_ST_SESSIONS) {
12360    UINT32 parameter_section_size = buffer.size();
12361    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12362    if (rc != TPM_RC_SUCCESS) {
12363      return rc;
12364    }
12365    if (parameter_section_size > buffer.size()) {
12366      return TPM_RC_INSUFFICIENT;
12367    }
12368    authorization_section_bytes = buffer.substr(parameter_section_size);
12369    // Keep the parameter section in |buffer|.
12370    buffer.erase(parameter_section_size);
12371  }
12372  std::unique_ptr<crypto::SecureHash> hash(
12373      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12374  hash->Update(response_code_bytes.data(), response_code_bytes.size());
12375  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12376  hash->Update(buffer.data(), buffer.size());
12377  std::string response_hash(32, 0);
12378  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
12379  if (tag == TPM_ST_SESSIONS) {
12380    CHECK(authorization_delegate) << "Authorization delegate missing!";
12381    if (!authorization_delegate->CheckResponseAuthorization(
12382            response_hash, authorization_section_bytes)) {
12383      return TRUNKS_RC_AUTHORIZATION_FAILED;
12384    }
12385  }
12386  std::string out_private_bytes;
12387  rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
12388  if (rc != TPM_RC_SUCCESS) {
12389    return rc;
12390  }
12391  if (tag == TPM_ST_SESSIONS) {
12392    CHECK(authorization_delegate) << "Authorization delegate missing!";
12393    // Decrypt just the parameter data, not the size.
12394    std::string tmp = out_private_bytes.substr(2);
12395    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
12396      return TRUNKS_RC_ENCRYPTION_FAILED;
12397    }
12398    out_private_bytes.replace(2, std::string::npos, tmp);
12399    rc = Parse_TPM2B_PRIVATE(&out_private_bytes, out_private, nullptr);
12400    if (rc != TPM_RC_SUCCESS) {
12401      return rc;
12402    }
12403  }
12404  return TPM_RC_SUCCESS;
12405}
12406
12407void ImportErrorCallback(const Tpm::ImportResponse& callback,
12408                         TPM_RC response_code) {
12409  VLOG(1) << __func__;
12410  callback.Run(response_code, TPM2B_PRIVATE());
12411}
12412
12413void ImportResponseParser(const Tpm::ImportResponse& callback,
12414                          AuthorizationDelegate* authorization_delegate,
12415                          const std::string& response) {
12416  VLOG(1) << __func__;
12417  base::Callback<void(TPM_RC)> error_reporter =
12418      base::Bind(ImportErrorCallback, callback);
12419  TPM2B_PRIVATE out_private;
12420  TPM_RC rc =
12421      Tpm::ParseResponse_Import(response, &out_private, authorization_delegate);
12422  if (rc != TPM_RC_SUCCESS) {
12423    error_reporter.Run(rc);
12424    return;
12425  }
12426  callback.Run(rc, out_private);
12427}
12428
12429void Tpm::Import(const TPMI_DH_OBJECT& parent_handle,
12430                 const std::string& parent_handle_name,
12431                 const TPM2B_DATA& encryption_key,
12432                 const TPM2B_PUBLIC& object_public,
12433                 const TPM2B_PRIVATE& duplicate,
12434                 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12435                 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12436                 AuthorizationDelegate* authorization_delegate,
12437                 const ImportResponse& callback) {
12438  VLOG(1) << __func__;
12439  base::Callback<void(TPM_RC)> error_reporter =
12440      base::Bind(ImportErrorCallback, callback);
12441  base::Callback<void(const std::string&)> parser =
12442      base::Bind(ImportResponseParser, callback, authorization_delegate);
12443  std::string command;
12444  TPM_RC rc = SerializeCommand_Import(
12445      parent_handle, parent_handle_name, encryption_key, object_public,
12446      duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12447  if (rc != TPM_RC_SUCCESS) {
12448    error_reporter.Run(rc);
12449    return;
12450  }
12451  transceiver_->SendCommand(command, parser);
12452}
12453
12454TPM_RC Tpm::ImportSync(const TPMI_DH_OBJECT& parent_handle,
12455                       const std::string& parent_handle_name,
12456                       const TPM2B_DATA& encryption_key,
12457                       const TPM2B_PUBLIC& object_public,
12458                       const TPM2B_PRIVATE& duplicate,
12459                       const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12460                       const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12461                       TPM2B_PRIVATE* out_private,
12462                       AuthorizationDelegate* authorization_delegate) {
12463  VLOG(1) << __func__;
12464  std::string command;
12465  TPM_RC rc = SerializeCommand_Import(
12466      parent_handle, parent_handle_name, encryption_key, object_public,
12467      duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12468  if (rc != TPM_RC_SUCCESS) {
12469    return rc;
12470  }
12471  std::string response = transceiver_->SendCommandAndWait(command);
12472  rc = ParseResponse_Import(response, out_private, authorization_delegate);
12473  return rc;
12474}
12475
12476TPM_RC Tpm::SerializeCommand_RSA_Encrypt(
12477    const TPMI_DH_OBJECT& key_handle,
12478    const std::string& key_handle_name,
12479    const TPM2B_PUBLIC_KEY_RSA& message,
12480    const TPMT_RSA_DECRYPT& in_scheme,
12481    const TPM2B_DATA& label,
12482    std::string* serialized_command,
12483    AuthorizationDelegate* authorization_delegate) {
12484  VLOG(3) << __func__;
12485  TPM_RC rc = TPM_RC_SUCCESS;
12486  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12487  UINT32 command_size = 10;  // Header size.
12488  std::string handle_section_bytes;
12489  std::string parameter_section_bytes;
12490  TPM_CC command_code = TPM_CC_RSA_Encrypt;
12491  bool is_command_parameter_encryption_possible = true;
12492  bool is_response_parameter_encryption_possible = true;
12493  std::string command_code_bytes;
12494  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12495  if (rc != TPM_RC_SUCCESS) {
12496    return rc;
12497  }
12498  std::string key_handle_bytes;
12499  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12500  if (rc != TPM_RC_SUCCESS) {
12501    return rc;
12502  }
12503  std::string message_bytes;
12504  rc = Serialize_TPM2B_PUBLIC_KEY_RSA(message, &message_bytes);
12505  if (rc != TPM_RC_SUCCESS) {
12506    return rc;
12507  }
12508  std::string in_scheme_bytes;
12509  rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12510  if (rc != TPM_RC_SUCCESS) {
12511    return rc;
12512  }
12513  std::string label_bytes;
12514  rc = Serialize_TPM2B_DATA(label, &label_bytes);
12515  if (rc != TPM_RC_SUCCESS) {
12516    return rc;
12517  }
12518  if (authorization_delegate) {
12519    // Encrypt just the parameter data, not the size.
12520    std::string tmp = message_bytes.substr(2);
12521    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12522      return TRUNKS_RC_ENCRYPTION_FAILED;
12523    }
12524    message_bytes.replace(2, std::string::npos, tmp);
12525  }
12526  std::unique_ptr<crypto::SecureHash> hash(
12527      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12528  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12529  hash->Update(key_handle_name.data(), key_handle_name.size());
12530  handle_section_bytes += key_handle_bytes;
12531  command_size += key_handle_bytes.size();
12532  hash->Update(message_bytes.data(), message_bytes.size());
12533  parameter_section_bytes += message_bytes;
12534  command_size += message_bytes.size();
12535  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12536  parameter_section_bytes += in_scheme_bytes;
12537  command_size += in_scheme_bytes.size();
12538  hash->Update(label_bytes.data(), label_bytes.size());
12539  parameter_section_bytes += label_bytes;
12540  command_size += label_bytes.size();
12541  std::string command_hash(32, 0);
12542  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
12543  std::string authorization_section_bytes;
12544  std::string authorization_size_bytes;
12545  if (authorization_delegate) {
12546    if (!authorization_delegate->GetCommandAuthorization(
12547            command_hash, is_command_parameter_encryption_possible,
12548            is_response_parameter_encryption_possible,
12549            &authorization_section_bytes)) {
12550      return TRUNKS_RC_AUTHORIZATION_FAILED;
12551    }
12552    if (!authorization_section_bytes.empty()) {
12553      tag = TPM_ST_SESSIONS;
12554      std::string tmp;
12555      rc = Serialize_UINT32(authorization_section_bytes.size(),
12556                            &authorization_size_bytes);
12557      if (rc != TPM_RC_SUCCESS) {
12558        return rc;
12559      }
12560      command_size +=
12561          authorization_size_bytes.size() + authorization_section_bytes.size();
12562    }
12563  }
12564  std::string tag_bytes;
12565  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12566  if (rc != TPM_RC_SUCCESS) {
12567    return rc;
12568  }
12569  std::string command_size_bytes;
12570  rc = Serialize_UINT32(command_size, &command_size_bytes);
12571  if (rc != TPM_RC_SUCCESS) {
12572    return rc;
12573  }
12574  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12575                        handle_section_bytes + authorization_size_bytes +
12576                        authorization_section_bytes + parameter_section_bytes;
12577  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12578  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
12579                                            serialized_command->size());
12580  return TPM_RC_SUCCESS;
12581}
12582
12583TPM_RC Tpm::ParseResponse_RSA_Encrypt(
12584    const std::string& response,
12585    TPM2B_PUBLIC_KEY_RSA* out_data,
12586    AuthorizationDelegate* authorization_delegate) {
12587  VLOG(3) << __func__;
12588  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12589  TPM_RC rc = TPM_RC_SUCCESS;
12590  std::string buffer(response);
12591  TPM_ST tag;
12592  std::string tag_bytes;
12593  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12594  if (rc != TPM_RC_SUCCESS) {
12595    return rc;
12596  }
12597  UINT32 response_size;
12598  std::string response_size_bytes;
12599  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12600  if (rc != TPM_RC_SUCCESS) {
12601    return rc;
12602  }
12603  TPM_RC response_code;
12604  std::string response_code_bytes;
12605  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12606  if (rc != TPM_RC_SUCCESS) {
12607    return rc;
12608  }
12609  if (response_size != response.size()) {
12610    return TPM_RC_SIZE;
12611  }
12612  if (response_code != TPM_RC_SUCCESS) {
12613    return response_code;
12614  }
12615  TPM_CC command_code = TPM_CC_RSA_Encrypt;
12616  std::string command_code_bytes;
12617  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12618  if (rc != TPM_RC_SUCCESS) {
12619    return rc;
12620  }
12621  std::string authorization_section_bytes;
12622  if (tag == TPM_ST_SESSIONS) {
12623    UINT32 parameter_section_size = buffer.size();
12624    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12625    if (rc != TPM_RC_SUCCESS) {
12626      return rc;
12627    }
12628    if (parameter_section_size > buffer.size()) {
12629      return TPM_RC_INSUFFICIENT;
12630    }
12631    authorization_section_bytes = buffer.substr(parameter_section_size);
12632    // Keep the parameter section in |buffer|.
12633    buffer.erase(parameter_section_size);
12634  }
12635  std::unique_ptr<crypto::SecureHash> hash(
12636      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12637  hash->Update(response_code_bytes.data(), response_code_bytes.size());
12638  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12639  hash->Update(buffer.data(), buffer.size());
12640  std::string response_hash(32, 0);
12641  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
12642  if (tag == TPM_ST_SESSIONS) {
12643    CHECK(authorization_delegate) << "Authorization delegate missing!";
12644    if (!authorization_delegate->CheckResponseAuthorization(
12645            response_hash, authorization_section_bytes)) {
12646      return TRUNKS_RC_AUTHORIZATION_FAILED;
12647    }
12648  }
12649  std::string out_data_bytes;
12650  rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, out_data, &out_data_bytes);
12651  if (rc != TPM_RC_SUCCESS) {
12652    return rc;
12653  }
12654  if (tag == TPM_ST_SESSIONS) {
12655    CHECK(authorization_delegate) << "Authorization delegate missing!";
12656    // Decrypt just the parameter data, not the size.
12657    std::string tmp = out_data_bytes.substr(2);
12658    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
12659      return TRUNKS_RC_ENCRYPTION_FAILED;
12660    }
12661    out_data_bytes.replace(2, std::string::npos, tmp);
12662    rc = Parse_TPM2B_PUBLIC_KEY_RSA(&out_data_bytes, out_data, nullptr);
12663    if (rc != TPM_RC_SUCCESS) {
12664      return rc;
12665    }
12666  }
12667  return TPM_RC_SUCCESS;
12668}
12669
12670void RSA_EncryptErrorCallback(const Tpm::RSA_EncryptResponse& callback,
12671                              TPM_RC response_code) {
12672  VLOG(1) << __func__;
12673  callback.Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12674}
12675
12676void RSA_EncryptResponseParser(const Tpm::RSA_EncryptResponse& callback,
12677                               AuthorizationDelegate* authorization_delegate,
12678                               const std::string& response) {
12679  VLOG(1) << __func__;
12680  base::Callback<void(TPM_RC)> error_reporter =
12681      base::Bind(RSA_EncryptErrorCallback, callback);
12682  TPM2B_PUBLIC_KEY_RSA out_data;
12683  TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt(response, &out_data,
12684                                             authorization_delegate);
12685  if (rc != TPM_RC_SUCCESS) {
12686    error_reporter.Run(rc);
12687    return;
12688  }
12689  callback.Run(rc, out_data);
12690}
12691
12692void Tpm::RSA_Encrypt(const TPMI_DH_OBJECT& key_handle,
12693                      const std::string& key_handle_name,
12694                      const TPM2B_PUBLIC_KEY_RSA& message,
12695                      const TPMT_RSA_DECRYPT& in_scheme,
12696                      const TPM2B_DATA& label,
12697                      AuthorizationDelegate* authorization_delegate,
12698                      const RSA_EncryptResponse& callback) {
12699  VLOG(1) << __func__;
12700  base::Callback<void(TPM_RC)> error_reporter =
12701      base::Bind(RSA_EncryptErrorCallback, callback);
12702  base::Callback<void(const std::string&)> parser =
12703      base::Bind(RSA_EncryptResponseParser, callback, authorization_delegate);
12704  std::string command;
12705  TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12706                                           in_scheme, label, &command,
12707                                           authorization_delegate);
12708  if (rc != TPM_RC_SUCCESS) {
12709    error_reporter.Run(rc);
12710    return;
12711  }
12712  transceiver_->SendCommand(command, parser);
12713}
12714
12715TPM_RC Tpm::RSA_EncryptSync(const TPMI_DH_OBJECT& key_handle,
12716                            const std::string& key_handle_name,
12717                            const TPM2B_PUBLIC_KEY_RSA& message,
12718                            const TPMT_RSA_DECRYPT& in_scheme,
12719                            const TPM2B_DATA& label,
12720                            TPM2B_PUBLIC_KEY_RSA* out_data,
12721                            AuthorizationDelegate* authorization_delegate) {
12722  VLOG(1) << __func__;
12723  std::string command;
12724  TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12725                                           in_scheme, label, &command,
12726                                           authorization_delegate);
12727  if (rc != TPM_RC_SUCCESS) {
12728    return rc;
12729  }
12730  std::string response = transceiver_->SendCommandAndWait(command);
12731  rc = ParseResponse_RSA_Encrypt(response, out_data, authorization_delegate);
12732  return rc;
12733}
12734
12735TPM_RC Tpm::SerializeCommand_RSA_Decrypt(
12736    const TPMI_DH_OBJECT& key_handle,
12737    const std::string& key_handle_name,
12738    const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12739    const TPMT_RSA_DECRYPT& in_scheme,
12740    const TPM2B_DATA& label,
12741    std::string* serialized_command,
12742    AuthorizationDelegate* authorization_delegate) {
12743  VLOG(3) << __func__;
12744  TPM_RC rc = TPM_RC_SUCCESS;
12745  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12746  UINT32 command_size = 10;  // Header size.
12747  std::string handle_section_bytes;
12748  std::string parameter_section_bytes;
12749  TPM_CC command_code = TPM_CC_RSA_Decrypt;
12750  bool is_command_parameter_encryption_possible = true;
12751  bool is_response_parameter_encryption_possible = true;
12752  std::string command_code_bytes;
12753  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12754  if (rc != TPM_RC_SUCCESS) {
12755    return rc;
12756  }
12757  std::string key_handle_bytes;
12758  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12759  if (rc != TPM_RC_SUCCESS) {
12760    return rc;
12761  }
12762  std::string cipher_text_bytes;
12763  rc = Serialize_TPM2B_PUBLIC_KEY_RSA(cipher_text, &cipher_text_bytes);
12764  if (rc != TPM_RC_SUCCESS) {
12765    return rc;
12766  }
12767  std::string in_scheme_bytes;
12768  rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12769  if (rc != TPM_RC_SUCCESS) {
12770    return rc;
12771  }
12772  std::string label_bytes;
12773  rc = Serialize_TPM2B_DATA(label, &label_bytes);
12774  if (rc != TPM_RC_SUCCESS) {
12775    return rc;
12776  }
12777  if (authorization_delegate) {
12778    // Encrypt just the parameter data, not the size.
12779    std::string tmp = cipher_text_bytes.substr(2);
12780    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12781      return TRUNKS_RC_ENCRYPTION_FAILED;
12782    }
12783    cipher_text_bytes.replace(2, std::string::npos, tmp);
12784  }
12785  std::unique_ptr<crypto::SecureHash> hash(
12786      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12787  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12788  hash->Update(key_handle_name.data(), key_handle_name.size());
12789  handle_section_bytes += key_handle_bytes;
12790  command_size += key_handle_bytes.size();
12791  hash->Update(cipher_text_bytes.data(), cipher_text_bytes.size());
12792  parameter_section_bytes += cipher_text_bytes;
12793  command_size += cipher_text_bytes.size();
12794  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12795  parameter_section_bytes += in_scheme_bytes;
12796  command_size += in_scheme_bytes.size();
12797  hash->Update(label_bytes.data(), label_bytes.size());
12798  parameter_section_bytes += label_bytes;
12799  command_size += label_bytes.size();
12800  std::string command_hash(32, 0);
12801  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
12802  std::string authorization_section_bytes;
12803  std::string authorization_size_bytes;
12804  if (authorization_delegate) {
12805    if (!authorization_delegate->GetCommandAuthorization(
12806            command_hash, is_command_parameter_encryption_possible,
12807            is_response_parameter_encryption_possible,
12808            &authorization_section_bytes)) {
12809      return TRUNKS_RC_AUTHORIZATION_FAILED;
12810    }
12811    if (!authorization_section_bytes.empty()) {
12812      tag = TPM_ST_SESSIONS;
12813      std::string tmp;
12814      rc = Serialize_UINT32(authorization_section_bytes.size(),
12815                            &authorization_size_bytes);
12816      if (rc != TPM_RC_SUCCESS) {
12817        return rc;
12818      }
12819      command_size +=
12820          authorization_size_bytes.size() + authorization_section_bytes.size();
12821    }
12822  }
12823  std::string tag_bytes;
12824  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12825  if (rc != TPM_RC_SUCCESS) {
12826    return rc;
12827  }
12828  std::string command_size_bytes;
12829  rc = Serialize_UINT32(command_size, &command_size_bytes);
12830  if (rc != TPM_RC_SUCCESS) {
12831    return rc;
12832  }
12833  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12834                        handle_section_bytes + authorization_size_bytes +
12835                        authorization_section_bytes + parameter_section_bytes;
12836  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12837  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
12838                                            serialized_command->size());
12839  return TPM_RC_SUCCESS;
12840}
12841
12842TPM_RC Tpm::ParseResponse_RSA_Decrypt(
12843    const std::string& response,
12844    TPM2B_PUBLIC_KEY_RSA* message,
12845    AuthorizationDelegate* authorization_delegate) {
12846  VLOG(3) << __func__;
12847  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12848  TPM_RC rc = TPM_RC_SUCCESS;
12849  std::string buffer(response);
12850  TPM_ST tag;
12851  std::string tag_bytes;
12852  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12853  if (rc != TPM_RC_SUCCESS) {
12854    return rc;
12855  }
12856  UINT32 response_size;
12857  std::string response_size_bytes;
12858  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12859  if (rc != TPM_RC_SUCCESS) {
12860    return rc;
12861  }
12862  TPM_RC response_code;
12863  std::string response_code_bytes;
12864  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12865  if (rc != TPM_RC_SUCCESS) {
12866    return rc;
12867  }
12868  if (response_size != response.size()) {
12869    return TPM_RC_SIZE;
12870  }
12871  if (response_code != TPM_RC_SUCCESS) {
12872    return response_code;
12873  }
12874  TPM_CC command_code = TPM_CC_RSA_Decrypt;
12875  std::string command_code_bytes;
12876  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12877  if (rc != TPM_RC_SUCCESS) {
12878    return rc;
12879  }
12880  std::string authorization_section_bytes;
12881  if (tag == TPM_ST_SESSIONS) {
12882    UINT32 parameter_section_size = buffer.size();
12883    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12884    if (rc != TPM_RC_SUCCESS) {
12885      return rc;
12886    }
12887    if (parameter_section_size > buffer.size()) {
12888      return TPM_RC_INSUFFICIENT;
12889    }
12890    authorization_section_bytes = buffer.substr(parameter_section_size);
12891    // Keep the parameter section in |buffer|.
12892    buffer.erase(parameter_section_size);
12893  }
12894  std::unique_ptr<crypto::SecureHash> hash(
12895      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12896  hash->Update(response_code_bytes.data(), response_code_bytes.size());
12897  hash->Update(command_code_bytes.data(), command_code_bytes.size());
12898  hash->Update(buffer.data(), buffer.size());
12899  std::string response_hash(32, 0);
12900  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
12901  if (tag == TPM_ST_SESSIONS) {
12902    CHECK(authorization_delegate) << "Authorization delegate missing!";
12903    if (!authorization_delegate->CheckResponseAuthorization(
12904            response_hash, authorization_section_bytes)) {
12905      return TRUNKS_RC_AUTHORIZATION_FAILED;
12906    }
12907  }
12908  std::string message_bytes;
12909  rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, message, &message_bytes);
12910  if (rc != TPM_RC_SUCCESS) {
12911    return rc;
12912  }
12913  if (tag == TPM_ST_SESSIONS) {
12914    CHECK(authorization_delegate) << "Authorization delegate missing!";
12915    // Decrypt just the parameter data, not the size.
12916    std::string tmp = message_bytes.substr(2);
12917    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
12918      return TRUNKS_RC_ENCRYPTION_FAILED;
12919    }
12920    message_bytes.replace(2, std::string::npos, tmp);
12921    rc = Parse_TPM2B_PUBLIC_KEY_RSA(&message_bytes, message, nullptr);
12922    if (rc != TPM_RC_SUCCESS) {
12923      return rc;
12924    }
12925  }
12926  return TPM_RC_SUCCESS;
12927}
12928
12929void RSA_DecryptErrorCallback(const Tpm::RSA_DecryptResponse& callback,
12930                              TPM_RC response_code) {
12931  VLOG(1) << __func__;
12932  callback.Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12933}
12934
12935void RSA_DecryptResponseParser(const Tpm::RSA_DecryptResponse& callback,
12936                               AuthorizationDelegate* authorization_delegate,
12937                               const std::string& response) {
12938  VLOG(1) << __func__;
12939  base::Callback<void(TPM_RC)> error_reporter =
12940      base::Bind(RSA_DecryptErrorCallback, callback);
12941  TPM2B_PUBLIC_KEY_RSA message;
12942  TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt(response, &message,
12943                                             authorization_delegate);
12944  if (rc != TPM_RC_SUCCESS) {
12945    error_reporter.Run(rc);
12946    return;
12947  }
12948  callback.Run(rc, message);
12949}
12950
12951void Tpm::RSA_Decrypt(const TPMI_DH_OBJECT& key_handle,
12952                      const std::string& key_handle_name,
12953                      const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12954                      const TPMT_RSA_DECRYPT& in_scheme,
12955                      const TPM2B_DATA& label,
12956                      AuthorizationDelegate* authorization_delegate,
12957                      const RSA_DecryptResponse& callback) {
12958  VLOG(1) << __func__;
12959  base::Callback<void(TPM_RC)> error_reporter =
12960      base::Bind(RSA_DecryptErrorCallback, callback);
12961  base::Callback<void(const std::string&)> parser =
12962      base::Bind(RSA_DecryptResponseParser, callback, authorization_delegate);
12963  std::string command;
12964  TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
12965                                           cipher_text, in_scheme, label,
12966                                           &command, authorization_delegate);
12967  if (rc != TPM_RC_SUCCESS) {
12968    error_reporter.Run(rc);
12969    return;
12970  }
12971  transceiver_->SendCommand(command, parser);
12972}
12973
12974TPM_RC Tpm::RSA_DecryptSync(const TPMI_DH_OBJECT& key_handle,
12975                            const std::string& key_handle_name,
12976                            const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12977                            const TPMT_RSA_DECRYPT& in_scheme,
12978                            const TPM2B_DATA& label,
12979                            TPM2B_PUBLIC_KEY_RSA* message,
12980                            AuthorizationDelegate* authorization_delegate) {
12981  VLOG(1) << __func__;
12982  std::string command;
12983  TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
12984                                           cipher_text, in_scheme, label,
12985                                           &command, authorization_delegate);
12986  if (rc != TPM_RC_SUCCESS) {
12987    return rc;
12988  }
12989  std::string response = transceiver_->SendCommandAndWait(command);
12990  rc = ParseResponse_RSA_Decrypt(response, message, authorization_delegate);
12991  return rc;
12992}
12993
12994TPM_RC Tpm::SerializeCommand_ECDH_KeyGen(
12995    const TPMI_DH_OBJECT& key_handle,
12996    const std::string& key_handle_name,
12997    std::string* serialized_command,
12998    AuthorizationDelegate* authorization_delegate) {
12999  VLOG(3) << __func__;
13000  TPM_RC rc = TPM_RC_SUCCESS;
13001  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13002  UINT32 command_size = 10;  // Header size.
13003  std::string handle_section_bytes;
13004  std::string parameter_section_bytes;
13005  TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13006  bool is_command_parameter_encryption_possible = false;
13007  bool is_response_parameter_encryption_possible = true;
13008  std::string command_code_bytes;
13009  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13010  if (rc != TPM_RC_SUCCESS) {
13011    return rc;
13012  }
13013  std::string key_handle_bytes;
13014  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13015  if (rc != TPM_RC_SUCCESS) {
13016    return rc;
13017  }
13018  std::unique_ptr<crypto::SecureHash> hash(
13019      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13020  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13021  hash->Update(key_handle_name.data(), key_handle_name.size());
13022  handle_section_bytes += key_handle_bytes;
13023  command_size += key_handle_bytes.size();
13024  std::string command_hash(32, 0);
13025  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
13026  std::string authorization_section_bytes;
13027  std::string authorization_size_bytes;
13028  if (authorization_delegate) {
13029    if (!authorization_delegate->GetCommandAuthorization(
13030            command_hash, is_command_parameter_encryption_possible,
13031            is_response_parameter_encryption_possible,
13032            &authorization_section_bytes)) {
13033      return TRUNKS_RC_AUTHORIZATION_FAILED;
13034    }
13035    if (!authorization_section_bytes.empty()) {
13036      tag = TPM_ST_SESSIONS;
13037      std::string tmp;
13038      rc = Serialize_UINT32(authorization_section_bytes.size(),
13039                            &authorization_size_bytes);
13040      if (rc != TPM_RC_SUCCESS) {
13041        return rc;
13042      }
13043      command_size +=
13044          authorization_size_bytes.size() + authorization_section_bytes.size();
13045    }
13046  }
13047  std::string tag_bytes;
13048  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13049  if (rc != TPM_RC_SUCCESS) {
13050    return rc;
13051  }
13052  std::string command_size_bytes;
13053  rc = Serialize_UINT32(command_size, &command_size_bytes);
13054  if (rc != TPM_RC_SUCCESS) {
13055    return rc;
13056  }
13057  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13058                        handle_section_bytes + authorization_size_bytes +
13059                        authorization_section_bytes + parameter_section_bytes;
13060  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13061  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
13062                                            serialized_command->size());
13063  return TPM_RC_SUCCESS;
13064}
13065
13066TPM_RC Tpm::ParseResponse_ECDH_KeyGen(
13067    const std::string& response,
13068    TPM2B_ECC_POINT* z_point,
13069    TPM2B_ECC_POINT* pub_point,
13070    AuthorizationDelegate* authorization_delegate) {
13071  VLOG(3) << __func__;
13072  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13073  TPM_RC rc = TPM_RC_SUCCESS;
13074  std::string buffer(response);
13075  TPM_ST tag;
13076  std::string tag_bytes;
13077  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13078  if (rc != TPM_RC_SUCCESS) {
13079    return rc;
13080  }
13081  UINT32 response_size;
13082  std::string response_size_bytes;
13083  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13084  if (rc != TPM_RC_SUCCESS) {
13085    return rc;
13086  }
13087  TPM_RC response_code;
13088  std::string response_code_bytes;
13089  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13090  if (rc != TPM_RC_SUCCESS) {
13091    return rc;
13092  }
13093  if (response_size != response.size()) {
13094    return TPM_RC_SIZE;
13095  }
13096  if (response_code != TPM_RC_SUCCESS) {
13097    return response_code;
13098  }
13099  TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13100  std::string command_code_bytes;
13101  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13102  if (rc != TPM_RC_SUCCESS) {
13103    return rc;
13104  }
13105  std::string authorization_section_bytes;
13106  if (tag == TPM_ST_SESSIONS) {
13107    UINT32 parameter_section_size = buffer.size();
13108    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13109    if (rc != TPM_RC_SUCCESS) {
13110      return rc;
13111    }
13112    if (parameter_section_size > buffer.size()) {
13113      return TPM_RC_INSUFFICIENT;
13114    }
13115    authorization_section_bytes = buffer.substr(parameter_section_size);
13116    // Keep the parameter section in |buffer|.
13117    buffer.erase(parameter_section_size);
13118  }
13119  std::unique_ptr<crypto::SecureHash> hash(
13120      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13121  hash->Update(response_code_bytes.data(), response_code_bytes.size());
13122  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13123  hash->Update(buffer.data(), buffer.size());
13124  std::string response_hash(32, 0);
13125  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
13126  if (tag == TPM_ST_SESSIONS) {
13127    CHECK(authorization_delegate) << "Authorization delegate missing!";
13128    if (!authorization_delegate->CheckResponseAuthorization(
13129            response_hash, authorization_section_bytes)) {
13130      return TRUNKS_RC_AUTHORIZATION_FAILED;
13131    }
13132  }
13133  std::string z_point_bytes;
13134  rc = Parse_TPM2B_ECC_POINT(&buffer, z_point, &z_point_bytes);
13135  if (rc != TPM_RC_SUCCESS) {
13136    return rc;
13137  }
13138  std::string pub_point_bytes;
13139  rc = Parse_TPM2B_ECC_POINT(&buffer, pub_point, &pub_point_bytes);
13140  if (rc != TPM_RC_SUCCESS) {
13141    return rc;
13142  }
13143  if (tag == TPM_ST_SESSIONS) {
13144    CHECK(authorization_delegate) << "Authorization delegate missing!";
13145    // Decrypt just the parameter data, not the size.
13146    std::string tmp = z_point_bytes.substr(2);
13147    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
13148      return TRUNKS_RC_ENCRYPTION_FAILED;
13149    }
13150    z_point_bytes.replace(2, std::string::npos, tmp);
13151    rc = Parse_TPM2B_ECC_POINT(&z_point_bytes, z_point, nullptr);
13152    if (rc != TPM_RC_SUCCESS) {
13153      return rc;
13154    }
13155  }
13156  return TPM_RC_SUCCESS;
13157}
13158
13159void ECDH_KeyGenErrorCallback(const Tpm::ECDH_KeyGenResponse& callback,
13160                              TPM_RC response_code) {
13161  VLOG(1) << __func__;
13162  callback.Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13163}
13164
13165void ECDH_KeyGenResponseParser(const Tpm::ECDH_KeyGenResponse& callback,
13166                               AuthorizationDelegate* authorization_delegate,
13167                               const std::string& response) {
13168  VLOG(1) << __func__;
13169  base::Callback<void(TPM_RC)> error_reporter =
13170      base::Bind(ECDH_KeyGenErrorCallback, callback);
13171  TPM2B_ECC_POINT z_point;
13172  TPM2B_ECC_POINT pub_point;
13173  TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen(response, &z_point, &pub_point,
13174                                             authorization_delegate);
13175  if (rc != TPM_RC_SUCCESS) {
13176    error_reporter.Run(rc);
13177    return;
13178  }
13179  callback.Run(rc, z_point, pub_point);
13180}
13181
13182void Tpm::ECDH_KeyGen(const TPMI_DH_OBJECT& key_handle,
13183                      const std::string& key_handle_name,
13184                      AuthorizationDelegate* authorization_delegate,
13185                      const ECDH_KeyGenResponse& callback) {
13186  VLOG(1) << __func__;
13187  base::Callback<void(TPM_RC)> error_reporter =
13188      base::Bind(ECDH_KeyGenErrorCallback, callback);
13189  base::Callback<void(const std::string&)> parser =
13190      base::Bind(ECDH_KeyGenResponseParser, callback, authorization_delegate);
13191  std::string command;
13192  TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13193                                           &command, authorization_delegate);
13194  if (rc != TPM_RC_SUCCESS) {
13195    error_reporter.Run(rc);
13196    return;
13197  }
13198  transceiver_->SendCommand(command, parser);
13199}
13200
13201TPM_RC Tpm::ECDH_KeyGenSync(const TPMI_DH_OBJECT& key_handle,
13202                            const std::string& key_handle_name,
13203                            TPM2B_ECC_POINT* z_point,
13204                            TPM2B_ECC_POINT* pub_point,
13205                            AuthorizationDelegate* authorization_delegate) {
13206  VLOG(1) << __func__;
13207  std::string command;
13208  TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13209                                           &command, authorization_delegate);
13210  if (rc != TPM_RC_SUCCESS) {
13211    return rc;
13212  }
13213  std::string response = transceiver_->SendCommandAndWait(command);
13214  rc = ParseResponse_ECDH_KeyGen(response, z_point, pub_point,
13215                                 authorization_delegate);
13216  return rc;
13217}
13218
13219TPM_RC Tpm::SerializeCommand_ECDH_ZGen(
13220    const TPMI_DH_OBJECT& key_handle,
13221    const std::string& key_handle_name,
13222    const TPM2B_ECC_POINT& in_point,
13223    std::string* serialized_command,
13224    AuthorizationDelegate* authorization_delegate) {
13225  VLOG(3) << __func__;
13226  TPM_RC rc = TPM_RC_SUCCESS;
13227  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13228  UINT32 command_size = 10;  // Header size.
13229  std::string handle_section_bytes;
13230  std::string parameter_section_bytes;
13231  TPM_CC command_code = TPM_CC_ECDH_ZGen;
13232  bool is_command_parameter_encryption_possible = true;
13233  bool is_response_parameter_encryption_possible = true;
13234  std::string command_code_bytes;
13235  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13236  if (rc != TPM_RC_SUCCESS) {
13237    return rc;
13238  }
13239  std::string key_handle_bytes;
13240  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13241  if (rc != TPM_RC_SUCCESS) {
13242    return rc;
13243  }
13244  std::string in_point_bytes;
13245  rc = Serialize_TPM2B_ECC_POINT(in_point, &in_point_bytes);
13246  if (rc != TPM_RC_SUCCESS) {
13247    return rc;
13248  }
13249  if (authorization_delegate) {
13250    // Encrypt just the parameter data, not the size.
13251    std::string tmp = in_point_bytes.substr(2);
13252    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13253      return TRUNKS_RC_ENCRYPTION_FAILED;
13254    }
13255    in_point_bytes.replace(2, std::string::npos, tmp);
13256  }
13257  std::unique_ptr<crypto::SecureHash> hash(
13258      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13259  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13260  hash->Update(key_handle_name.data(), key_handle_name.size());
13261  handle_section_bytes += key_handle_bytes;
13262  command_size += key_handle_bytes.size();
13263  hash->Update(in_point_bytes.data(), in_point_bytes.size());
13264  parameter_section_bytes += in_point_bytes;
13265  command_size += in_point_bytes.size();
13266  std::string command_hash(32, 0);
13267  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
13268  std::string authorization_section_bytes;
13269  std::string authorization_size_bytes;
13270  if (authorization_delegate) {
13271    if (!authorization_delegate->GetCommandAuthorization(
13272            command_hash, is_command_parameter_encryption_possible,
13273            is_response_parameter_encryption_possible,
13274            &authorization_section_bytes)) {
13275      return TRUNKS_RC_AUTHORIZATION_FAILED;
13276    }
13277    if (!authorization_section_bytes.empty()) {
13278      tag = TPM_ST_SESSIONS;
13279      std::string tmp;
13280      rc = Serialize_UINT32(authorization_section_bytes.size(),
13281                            &authorization_size_bytes);
13282      if (rc != TPM_RC_SUCCESS) {
13283        return rc;
13284      }
13285      command_size +=
13286          authorization_size_bytes.size() + authorization_section_bytes.size();
13287    }
13288  }
13289  std::string tag_bytes;
13290  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13291  if (rc != TPM_RC_SUCCESS) {
13292    return rc;
13293  }
13294  std::string command_size_bytes;
13295  rc = Serialize_UINT32(command_size, &command_size_bytes);
13296  if (rc != TPM_RC_SUCCESS) {
13297    return rc;
13298  }
13299  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13300                        handle_section_bytes + authorization_size_bytes +
13301                        authorization_section_bytes + parameter_section_bytes;
13302  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13303  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
13304                                            serialized_command->size());
13305  return TPM_RC_SUCCESS;
13306}
13307
13308TPM_RC Tpm::ParseResponse_ECDH_ZGen(
13309    const std::string& response,
13310    TPM2B_ECC_POINT* out_point,
13311    AuthorizationDelegate* authorization_delegate) {
13312  VLOG(3) << __func__;
13313  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13314  TPM_RC rc = TPM_RC_SUCCESS;
13315  std::string buffer(response);
13316  TPM_ST tag;
13317  std::string tag_bytes;
13318  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13319  if (rc != TPM_RC_SUCCESS) {
13320    return rc;
13321  }
13322  UINT32 response_size;
13323  std::string response_size_bytes;
13324  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13325  if (rc != TPM_RC_SUCCESS) {
13326    return rc;
13327  }
13328  TPM_RC response_code;
13329  std::string response_code_bytes;
13330  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13331  if (rc != TPM_RC_SUCCESS) {
13332    return rc;
13333  }
13334  if (response_size != response.size()) {
13335    return TPM_RC_SIZE;
13336  }
13337  if (response_code != TPM_RC_SUCCESS) {
13338    return response_code;
13339  }
13340  TPM_CC command_code = TPM_CC_ECDH_ZGen;
13341  std::string command_code_bytes;
13342  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13343  if (rc != TPM_RC_SUCCESS) {
13344    return rc;
13345  }
13346  std::string authorization_section_bytes;
13347  if (tag == TPM_ST_SESSIONS) {
13348    UINT32 parameter_section_size = buffer.size();
13349    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13350    if (rc != TPM_RC_SUCCESS) {
13351      return rc;
13352    }
13353    if (parameter_section_size > buffer.size()) {
13354      return TPM_RC_INSUFFICIENT;
13355    }
13356    authorization_section_bytes = buffer.substr(parameter_section_size);
13357    // Keep the parameter section in |buffer|.
13358    buffer.erase(parameter_section_size);
13359  }
13360  std::unique_ptr<crypto::SecureHash> hash(
13361      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13362  hash->Update(response_code_bytes.data(), response_code_bytes.size());
13363  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13364  hash->Update(buffer.data(), buffer.size());
13365  std::string response_hash(32, 0);
13366  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
13367  if (tag == TPM_ST_SESSIONS) {
13368    CHECK(authorization_delegate) << "Authorization delegate missing!";
13369    if (!authorization_delegate->CheckResponseAuthorization(
13370            response_hash, authorization_section_bytes)) {
13371      return TRUNKS_RC_AUTHORIZATION_FAILED;
13372    }
13373  }
13374  std::string out_point_bytes;
13375  rc = Parse_TPM2B_ECC_POINT(&buffer, out_point, &out_point_bytes);
13376  if (rc != TPM_RC_SUCCESS) {
13377    return rc;
13378  }
13379  if (tag == TPM_ST_SESSIONS) {
13380    CHECK(authorization_delegate) << "Authorization delegate missing!";
13381    // Decrypt just the parameter data, not the size.
13382    std::string tmp = out_point_bytes.substr(2);
13383    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
13384      return TRUNKS_RC_ENCRYPTION_FAILED;
13385    }
13386    out_point_bytes.replace(2, std::string::npos, tmp);
13387    rc = Parse_TPM2B_ECC_POINT(&out_point_bytes, out_point, nullptr);
13388    if (rc != TPM_RC_SUCCESS) {
13389      return rc;
13390    }
13391  }
13392  return TPM_RC_SUCCESS;
13393}
13394
13395void ECDH_ZGenErrorCallback(const Tpm::ECDH_ZGenResponse& callback,
13396                            TPM_RC response_code) {
13397  VLOG(1) << __func__;
13398  callback.Run(response_code, TPM2B_ECC_POINT());
13399}
13400
13401void ECDH_ZGenResponseParser(const Tpm::ECDH_ZGenResponse& callback,
13402                             AuthorizationDelegate* authorization_delegate,
13403                             const std::string& response) {
13404  VLOG(1) << __func__;
13405  base::Callback<void(TPM_RC)> error_reporter =
13406      base::Bind(ECDH_ZGenErrorCallback, callback);
13407  TPM2B_ECC_POINT out_point;
13408  TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen(response, &out_point,
13409                                           authorization_delegate);
13410  if (rc != TPM_RC_SUCCESS) {
13411    error_reporter.Run(rc);
13412    return;
13413  }
13414  callback.Run(rc, out_point);
13415}
13416
13417void Tpm::ECDH_ZGen(const TPMI_DH_OBJECT& key_handle,
13418                    const std::string& key_handle_name,
13419                    const TPM2B_ECC_POINT& in_point,
13420                    AuthorizationDelegate* authorization_delegate,
13421                    const ECDH_ZGenResponse& callback) {
13422  VLOG(1) << __func__;
13423  base::Callback<void(TPM_RC)> error_reporter =
13424      base::Bind(ECDH_ZGenErrorCallback, callback);
13425  base::Callback<void(const std::string&)> parser =
13426      base::Bind(ECDH_ZGenResponseParser, callback, authorization_delegate);
13427  std::string command;
13428  TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13429                                         &command, authorization_delegate);
13430  if (rc != TPM_RC_SUCCESS) {
13431    error_reporter.Run(rc);
13432    return;
13433  }
13434  transceiver_->SendCommand(command, parser);
13435}
13436
13437TPM_RC Tpm::ECDH_ZGenSync(const TPMI_DH_OBJECT& key_handle,
13438                          const std::string& key_handle_name,
13439                          const TPM2B_ECC_POINT& in_point,
13440                          TPM2B_ECC_POINT* out_point,
13441                          AuthorizationDelegate* authorization_delegate) {
13442  VLOG(1) << __func__;
13443  std::string command;
13444  TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13445                                         &command, authorization_delegate);
13446  if (rc != TPM_RC_SUCCESS) {
13447    return rc;
13448  }
13449  std::string response = transceiver_->SendCommandAndWait(command);
13450  rc = ParseResponse_ECDH_ZGen(response, out_point, authorization_delegate);
13451  return rc;
13452}
13453
13454TPM_RC Tpm::SerializeCommand_ECC_Parameters(
13455    const TPMI_ECC_CURVE& curve_id,
13456    std::string* serialized_command,
13457    AuthorizationDelegate* authorization_delegate) {
13458  VLOG(3) << __func__;
13459  TPM_RC rc = TPM_RC_SUCCESS;
13460  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13461  UINT32 command_size = 10;  // Header size.
13462  std::string handle_section_bytes;
13463  std::string parameter_section_bytes;
13464  TPM_CC command_code = TPM_CC_ECC_Parameters;
13465  bool is_command_parameter_encryption_possible = false;
13466  bool is_response_parameter_encryption_possible = false;
13467  std::string command_code_bytes;
13468  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13469  if (rc != TPM_RC_SUCCESS) {
13470    return rc;
13471  }
13472  std::string curve_id_bytes;
13473  rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
13474  if (rc != TPM_RC_SUCCESS) {
13475    return rc;
13476  }
13477  std::unique_ptr<crypto::SecureHash> hash(
13478      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13479  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13480  hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
13481  parameter_section_bytes += curve_id_bytes;
13482  command_size += curve_id_bytes.size();
13483  std::string command_hash(32, 0);
13484  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
13485  std::string authorization_section_bytes;
13486  std::string authorization_size_bytes;
13487  if (authorization_delegate) {
13488    if (!authorization_delegate->GetCommandAuthorization(
13489            command_hash, is_command_parameter_encryption_possible,
13490            is_response_parameter_encryption_possible,
13491            &authorization_section_bytes)) {
13492      return TRUNKS_RC_AUTHORIZATION_FAILED;
13493    }
13494    if (!authorization_section_bytes.empty()) {
13495      tag = TPM_ST_SESSIONS;
13496      std::string tmp;
13497      rc = Serialize_UINT32(authorization_section_bytes.size(),
13498                            &authorization_size_bytes);
13499      if (rc != TPM_RC_SUCCESS) {
13500        return rc;
13501      }
13502      command_size +=
13503          authorization_size_bytes.size() + authorization_section_bytes.size();
13504    }
13505  }
13506  std::string tag_bytes;
13507  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13508  if (rc != TPM_RC_SUCCESS) {
13509    return rc;
13510  }
13511  std::string command_size_bytes;
13512  rc = Serialize_UINT32(command_size, &command_size_bytes);
13513  if (rc != TPM_RC_SUCCESS) {
13514    return rc;
13515  }
13516  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13517                        handle_section_bytes + authorization_size_bytes +
13518                        authorization_section_bytes + parameter_section_bytes;
13519  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13520  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
13521                                            serialized_command->size());
13522  return TPM_RC_SUCCESS;
13523}
13524
13525TPM_RC Tpm::ParseResponse_ECC_Parameters(
13526    const std::string& response,
13527    TPMS_ALGORITHM_DETAIL_ECC* parameters,
13528    AuthorizationDelegate* authorization_delegate) {
13529  VLOG(3) << __func__;
13530  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13531  TPM_RC rc = TPM_RC_SUCCESS;
13532  std::string buffer(response);
13533  TPM_ST tag;
13534  std::string tag_bytes;
13535  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13536  if (rc != TPM_RC_SUCCESS) {
13537    return rc;
13538  }
13539  UINT32 response_size;
13540  std::string response_size_bytes;
13541  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13542  if (rc != TPM_RC_SUCCESS) {
13543    return rc;
13544  }
13545  TPM_RC response_code;
13546  std::string response_code_bytes;
13547  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13548  if (rc != TPM_RC_SUCCESS) {
13549    return rc;
13550  }
13551  if (response_size != response.size()) {
13552    return TPM_RC_SIZE;
13553  }
13554  if (response_code != TPM_RC_SUCCESS) {
13555    return response_code;
13556  }
13557  TPM_CC command_code = TPM_CC_ECC_Parameters;
13558  std::string command_code_bytes;
13559  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13560  if (rc != TPM_RC_SUCCESS) {
13561    return rc;
13562  }
13563  std::string authorization_section_bytes;
13564  if (tag == TPM_ST_SESSIONS) {
13565    UINT32 parameter_section_size = buffer.size();
13566    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13567    if (rc != TPM_RC_SUCCESS) {
13568      return rc;
13569    }
13570    if (parameter_section_size > buffer.size()) {
13571      return TPM_RC_INSUFFICIENT;
13572    }
13573    authorization_section_bytes = buffer.substr(parameter_section_size);
13574    // Keep the parameter section in |buffer|.
13575    buffer.erase(parameter_section_size);
13576  }
13577  std::unique_ptr<crypto::SecureHash> hash(
13578      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13579  hash->Update(response_code_bytes.data(), response_code_bytes.size());
13580  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13581  hash->Update(buffer.data(), buffer.size());
13582  std::string response_hash(32, 0);
13583  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
13584  if (tag == TPM_ST_SESSIONS) {
13585    CHECK(authorization_delegate) << "Authorization delegate missing!";
13586    if (!authorization_delegate->CheckResponseAuthorization(
13587            response_hash, authorization_section_bytes)) {
13588      return TRUNKS_RC_AUTHORIZATION_FAILED;
13589    }
13590  }
13591  std::string parameters_bytes;
13592  rc = Parse_TPMS_ALGORITHM_DETAIL_ECC(&buffer, parameters, &parameters_bytes);
13593  if (rc != TPM_RC_SUCCESS) {
13594    return rc;
13595  }
13596  return TPM_RC_SUCCESS;
13597}
13598
13599void ECC_ParametersErrorCallback(const Tpm::ECC_ParametersResponse& callback,
13600                                 TPM_RC response_code) {
13601  VLOG(1) << __func__;
13602  callback.Run(response_code, TPMS_ALGORITHM_DETAIL_ECC());
13603}
13604
13605void ECC_ParametersResponseParser(const Tpm::ECC_ParametersResponse& callback,
13606                                  AuthorizationDelegate* authorization_delegate,
13607                                  const std::string& response) {
13608  VLOG(1) << __func__;
13609  base::Callback<void(TPM_RC)> error_reporter =
13610      base::Bind(ECC_ParametersErrorCallback, callback);
13611  TPMS_ALGORITHM_DETAIL_ECC parameters;
13612  TPM_RC rc = Tpm::ParseResponse_ECC_Parameters(response, &parameters,
13613                                                authorization_delegate);
13614  if (rc != TPM_RC_SUCCESS) {
13615    error_reporter.Run(rc);
13616    return;
13617  }
13618  callback.Run(rc, parameters);
13619}
13620
13621void Tpm::ECC_Parameters(const TPMI_ECC_CURVE& curve_id,
13622                         AuthorizationDelegate* authorization_delegate,
13623                         const ECC_ParametersResponse& callback) {
13624  VLOG(1) << __func__;
13625  base::Callback<void(TPM_RC)> error_reporter =
13626      base::Bind(ECC_ParametersErrorCallback, callback);
13627  base::Callback<void(const std::string&)> parser = base::Bind(
13628      ECC_ParametersResponseParser, callback, authorization_delegate);
13629  std::string command;
13630  TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13631                                              authorization_delegate);
13632  if (rc != TPM_RC_SUCCESS) {
13633    error_reporter.Run(rc);
13634    return;
13635  }
13636  transceiver_->SendCommand(command, parser);
13637}
13638
13639TPM_RC Tpm::ECC_ParametersSync(const TPMI_ECC_CURVE& curve_id,
13640                               TPMS_ALGORITHM_DETAIL_ECC* parameters,
13641                               AuthorizationDelegate* authorization_delegate) {
13642  VLOG(1) << __func__;
13643  std::string command;
13644  TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13645                                              authorization_delegate);
13646  if (rc != TPM_RC_SUCCESS) {
13647    return rc;
13648  }
13649  std::string response = transceiver_->SendCommandAndWait(command);
13650  rc = ParseResponse_ECC_Parameters(response, parameters,
13651                                    authorization_delegate);
13652  return rc;
13653}
13654
13655TPM_RC Tpm::SerializeCommand_ZGen_2Phase(
13656    const TPMI_DH_OBJECT& key_a,
13657    const std::string& key_a_name,
13658    const TPM2B_ECC_POINT& in_qs_b,
13659    const TPM2B_ECC_POINT& in_qe_b,
13660    const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13661    const UINT16& counter,
13662    std::string* serialized_command,
13663    AuthorizationDelegate* authorization_delegate) {
13664  VLOG(3) << __func__;
13665  TPM_RC rc = TPM_RC_SUCCESS;
13666  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13667  UINT32 command_size = 10;  // Header size.
13668  std::string handle_section_bytes;
13669  std::string parameter_section_bytes;
13670  TPM_CC command_code = TPM_CC_ZGen_2Phase;
13671  bool is_command_parameter_encryption_possible = true;
13672  bool is_response_parameter_encryption_possible = true;
13673  std::string command_code_bytes;
13674  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13675  if (rc != TPM_RC_SUCCESS) {
13676    return rc;
13677  }
13678  std::string key_a_bytes;
13679  rc = Serialize_TPMI_DH_OBJECT(key_a, &key_a_bytes);
13680  if (rc != TPM_RC_SUCCESS) {
13681    return rc;
13682  }
13683  std::string in_qs_b_bytes;
13684  rc = Serialize_TPM2B_ECC_POINT(in_qs_b, &in_qs_b_bytes);
13685  if (rc != TPM_RC_SUCCESS) {
13686    return rc;
13687  }
13688  std::string in_qe_b_bytes;
13689  rc = Serialize_TPM2B_ECC_POINT(in_qe_b, &in_qe_b_bytes);
13690  if (rc != TPM_RC_SUCCESS) {
13691    return rc;
13692  }
13693  std::string in_scheme_bytes;
13694  rc = Serialize_TPMI_ECC_KEY_EXCHANGE(in_scheme, &in_scheme_bytes);
13695  if (rc != TPM_RC_SUCCESS) {
13696    return rc;
13697  }
13698  std::string counter_bytes;
13699  rc = Serialize_UINT16(counter, &counter_bytes);
13700  if (rc != TPM_RC_SUCCESS) {
13701    return rc;
13702  }
13703  if (authorization_delegate) {
13704    // Encrypt just the parameter data, not the size.
13705    std::string tmp = in_qs_b_bytes.substr(2);
13706    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13707      return TRUNKS_RC_ENCRYPTION_FAILED;
13708    }
13709    in_qs_b_bytes.replace(2, std::string::npos, tmp);
13710  }
13711  std::unique_ptr<crypto::SecureHash> hash(
13712      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13713  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13714  hash->Update(key_a_name.data(), key_a_name.size());
13715  handle_section_bytes += key_a_bytes;
13716  command_size += key_a_bytes.size();
13717  hash->Update(in_qs_b_bytes.data(), in_qs_b_bytes.size());
13718  parameter_section_bytes += in_qs_b_bytes;
13719  command_size += in_qs_b_bytes.size();
13720  hash->Update(in_qe_b_bytes.data(), in_qe_b_bytes.size());
13721  parameter_section_bytes += in_qe_b_bytes;
13722  command_size += in_qe_b_bytes.size();
13723  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
13724  parameter_section_bytes += in_scheme_bytes;
13725  command_size += in_scheme_bytes.size();
13726  hash->Update(counter_bytes.data(), counter_bytes.size());
13727  parameter_section_bytes += counter_bytes;
13728  command_size += counter_bytes.size();
13729  std::string command_hash(32, 0);
13730  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
13731  std::string authorization_section_bytes;
13732  std::string authorization_size_bytes;
13733  if (authorization_delegate) {
13734    if (!authorization_delegate->GetCommandAuthorization(
13735            command_hash, is_command_parameter_encryption_possible,
13736            is_response_parameter_encryption_possible,
13737            &authorization_section_bytes)) {
13738      return TRUNKS_RC_AUTHORIZATION_FAILED;
13739    }
13740    if (!authorization_section_bytes.empty()) {
13741      tag = TPM_ST_SESSIONS;
13742      std::string tmp;
13743      rc = Serialize_UINT32(authorization_section_bytes.size(),
13744                            &authorization_size_bytes);
13745      if (rc != TPM_RC_SUCCESS) {
13746        return rc;
13747      }
13748      command_size +=
13749          authorization_size_bytes.size() + authorization_section_bytes.size();
13750    }
13751  }
13752  std::string tag_bytes;
13753  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13754  if (rc != TPM_RC_SUCCESS) {
13755    return rc;
13756  }
13757  std::string command_size_bytes;
13758  rc = Serialize_UINT32(command_size, &command_size_bytes);
13759  if (rc != TPM_RC_SUCCESS) {
13760    return rc;
13761  }
13762  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13763                        handle_section_bytes + authorization_size_bytes +
13764                        authorization_section_bytes + parameter_section_bytes;
13765  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13766  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
13767                                            serialized_command->size());
13768  return TPM_RC_SUCCESS;
13769}
13770
13771TPM_RC Tpm::ParseResponse_ZGen_2Phase(
13772    const std::string& response,
13773    TPM2B_ECC_POINT* out_z1,
13774    TPM2B_ECC_POINT* out_z2,
13775    AuthorizationDelegate* authorization_delegate) {
13776  VLOG(3) << __func__;
13777  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13778  TPM_RC rc = TPM_RC_SUCCESS;
13779  std::string buffer(response);
13780  TPM_ST tag;
13781  std::string tag_bytes;
13782  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13783  if (rc != TPM_RC_SUCCESS) {
13784    return rc;
13785  }
13786  UINT32 response_size;
13787  std::string response_size_bytes;
13788  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13789  if (rc != TPM_RC_SUCCESS) {
13790    return rc;
13791  }
13792  TPM_RC response_code;
13793  std::string response_code_bytes;
13794  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13795  if (rc != TPM_RC_SUCCESS) {
13796    return rc;
13797  }
13798  if (response_size != response.size()) {
13799    return TPM_RC_SIZE;
13800  }
13801  if (response_code != TPM_RC_SUCCESS) {
13802    return response_code;
13803  }
13804  TPM_CC command_code = TPM_CC_ZGen_2Phase;
13805  std::string command_code_bytes;
13806  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13807  if (rc != TPM_RC_SUCCESS) {
13808    return rc;
13809  }
13810  std::string authorization_section_bytes;
13811  if (tag == TPM_ST_SESSIONS) {
13812    UINT32 parameter_section_size = buffer.size();
13813    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13814    if (rc != TPM_RC_SUCCESS) {
13815      return rc;
13816    }
13817    if (parameter_section_size > buffer.size()) {
13818      return TPM_RC_INSUFFICIENT;
13819    }
13820    authorization_section_bytes = buffer.substr(parameter_section_size);
13821    // Keep the parameter section in |buffer|.
13822    buffer.erase(parameter_section_size);
13823  }
13824  std::unique_ptr<crypto::SecureHash> hash(
13825      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13826  hash->Update(response_code_bytes.data(), response_code_bytes.size());
13827  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13828  hash->Update(buffer.data(), buffer.size());
13829  std::string response_hash(32, 0);
13830  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
13831  if (tag == TPM_ST_SESSIONS) {
13832    CHECK(authorization_delegate) << "Authorization delegate missing!";
13833    if (!authorization_delegate->CheckResponseAuthorization(
13834            response_hash, authorization_section_bytes)) {
13835      return TRUNKS_RC_AUTHORIZATION_FAILED;
13836    }
13837  }
13838  std::string out_z1_bytes;
13839  rc = Parse_TPM2B_ECC_POINT(&buffer, out_z1, &out_z1_bytes);
13840  if (rc != TPM_RC_SUCCESS) {
13841    return rc;
13842  }
13843  std::string out_z2_bytes;
13844  rc = Parse_TPM2B_ECC_POINT(&buffer, out_z2, &out_z2_bytes);
13845  if (rc != TPM_RC_SUCCESS) {
13846    return rc;
13847  }
13848  if (tag == TPM_ST_SESSIONS) {
13849    CHECK(authorization_delegate) << "Authorization delegate missing!";
13850    // Decrypt just the parameter data, not the size.
13851    std::string tmp = out_z1_bytes.substr(2);
13852    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
13853      return TRUNKS_RC_ENCRYPTION_FAILED;
13854    }
13855    out_z1_bytes.replace(2, std::string::npos, tmp);
13856    rc = Parse_TPM2B_ECC_POINT(&out_z1_bytes, out_z1, nullptr);
13857    if (rc != TPM_RC_SUCCESS) {
13858      return rc;
13859    }
13860  }
13861  return TPM_RC_SUCCESS;
13862}
13863
13864void ZGen_2PhaseErrorCallback(const Tpm::ZGen_2PhaseResponse& callback,
13865                              TPM_RC response_code) {
13866  VLOG(1) << __func__;
13867  callback.Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13868}
13869
13870void ZGen_2PhaseResponseParser(const Tpm::ZGen_2PhaseResponse& callback,
13871                               AuthorizationDelegate* authorization_delegate,
13872                               const std::string& response) {
13873  VLOG(1) << __func__;
13874  base::Callback<void(TPM_RC)> error_reporter =
13875      base::Bind(ZGen_2PhaseErrorCallback, callback);
13876  TPM2B_ECC_POINT out_z1;
13877  TPM2B_ECC_POINT out_z2;
13878  TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase(response, &out_z1, &out_z2,
13879                                             authorization_delegate);
13880  if (rc != TPM_RC_SUCCESS) {
13881    error_reporter.Run(rc);
13882    return;
13883  }
13884  callback.Run(rc, out_z1, out_z2);
13885}
13886
13887void Tpm::ZGen_2Phase(const TPMI_DH_OBJECT& key_a,
13888                      const std::string& key_a_name,
13889                      const TPM2B_ECC_POINT& in_qs_b,
13890                      const TPM2B_ECC_POINT& in_qe_b,
13891                      const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13892                      const UINT16& counter,
13893                      AuthorizationDelegate* authorization_delegate,
13894                      const ZGen_2PhaseResponse& callback) {
13895  VLOG(1) << __func__;
13896  base::Callback<void(TPM_RC)> error_reporter =
13897      base::Bind(ZGen_2PhaseErrorCallback, callback);
13898  base::Callback<void(const std::string&)> parser =
13899      base::Bind(ZGen_2PhaseResponseParser, callback, authorization_delegate);
13900  std::string command;
13901  TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
13902                                           in_scheme, counter, &command,
13903                                           authorization_delegate);
13904  if (rc != TPM_RC_SUCCESS) {
13905    error_reporter.Run(rc);
13906    return;
13907  }
13908  transceiver_->SendCommand(command, parser);
13909}
13910
13911TPM_RC Tpm::ZGen_2PhaseSync(const TPMI_DH_OBJECT& key_a,
13912                            const std::string& key_a_name,
13913                            const TPM2B_ECC_POINT& in_qs_b,
13914                            const TPM2B_ECC_POINT& in_qe_b,
13915                            const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13916                            const UINT16& counter,
13917                            TPM2B_ECC_POINT* out_z1,
13918                            TPM2B_ECC_POINT* out_z2,
13919                            AuthorizationDelegate* authorization_delegate) {
13920  VLOG(1) << __func__;
13921  std::string command;
13922  TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
13923                                           in_scheme, counter, &command,
13924                                           authorization_delegate);
13925  if (rc != TPM_RC_SUCCESS) {
13926    return rc;
13927  }
13928  std::string response = transceiver_->SendCommandAndWait(command);
13929  rc = ParseResponse_ZGen_2Phase(response, out_z1, out_z2,
13930                                 authorization_delegate);
13931  return rc;
13932}
13933
13934TPM_RC Tpm::SerializeCommand_EncryptDecrypt(
13935    const TPMI_DH_OBJECT& key_handle,
13936    const std::string& key_handle_name,
13937    const TPMI_YES_NO& decrypt,
13938    const TPMI_ALG_SYM_MODE& mode,
13939    const TPM2B_IV& iv_in,
13940    const TPM2B_MAX_BUFFER& in_data,
13941    std::string* serialized_command,
13942    AuthorizationDelegate* authorization_delegate) {
13943  VLOG(3) << __func__;
13944  TPM_RC rc = TPM_RC_SUCCESS;
13945  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13946  UINT32 command_size = 10;  // Header size.
13947  std::string handle_section_bytes;
13948  std::string parameter_section_bytes;
13949  TPM_CC command_code = TPM_CC_EncryptDecrypt;
13950  bool is_command_parameter_encryption_possible = false;
13951  bool is_response_parameter_encryption_possible = true;
13952  std::string command_code_bytes;
13953  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13954  if (rc != TPM_RC_SUCCESS) {
13955    return rc;
13956  }
13957  std::string key_handle_bytes;
13958  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13959  if (rc != TPM_RC_SUCCESS) {
13960    return rc;
13961  }
13962  std::string decrypt_bytes;
13963  rc = Serialize_TPMI_YES_NO(decrypt, &decrypt_bytes);
13964  if (rc != TPM_RC_SUCCESS) {
13965    return rc;
13966  }
13967  std::string mode_bytes;
13968  rc = Serialize_TPMI_ALG_SYM_MODE(mode, &mode_bytes);
13969  if (rc != TPM_RC_SUCCESS) {
13970    return rc;
13971  }
13972  std::string iv_in_bytes;
13973  rc = Serialize_TPM2B_IV(iv_in, &iv_in_bytes);
13974  if (rc != TPM_RC_SUCCESS) {
13975    return rc;
13976  }
13977  std::string in_data_bytes;
13978  rc = Serialize_TPM2B_MAX_BUFFER(in_data, &in_data_bytes);
13979  if (rc != TPM_RC_SUCCESS) {
13980    return rc;
13981  }
13982  std::unique_ptr<crypto::SecureHash> hash(
13983      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13984  hash->Update(command_code_bytes.data(), command_code_bytes.size());
13985  hash->Update(key_handle_name.data(), key_handle_name.size());
13986  handle_section_bytes += key_handle_bytes;
13987  command_size += key_handle_bytes.size();
13988  hash->Update(decrypt_bytes.data(), decrypt_bytes.size());
13989  parameter_section_bytes += decrypt_bytes;
13990  command_size += decrypt_bytes.size();
13991  hash->Update(mode_bytes.data(), mode_bytes.size());
13992  parameter_section_bytes += mode_bytes;
13993  command_size += mode_bytes.size();
13994  hash->Update(iv_in_bytes.data(), iv_in_bytes.size());
13995  parameter_section_bytes += iv_in_bytes;
13996  command_size += iv_in_bytes.size();
13997  hash->Update(in_data_bytes.data(), in_data_bytes.size());
13998  parameter_section_bytes += in_data_bytes;
13999  command_size += in_data_bytes.size();
14000  std::string command_hash(32, 0);
14001  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
14002  std::string authorization_section_bytes;
14003  std::string authorization_size_bytes;
14004  if (authorization_delegate) {
14005    if (!authorization_delegate->GetCommandAuthorization(
14006            command_hash, is_command_parameter_encryption_possible,
14007            is_response_parameter_encryption_possible,
14008            &authorization_section_bytes)) {
14009      return TRUNKS_RC_AUTHORIZATION_FAILED;
14010    }
14011    if (!authorization_section_bytes.empty()) {
14012      tag = TPM_ST_SESSIONS;
14013      std::string tmp;
14014      rc = Serialize_UINT32(authorization_section_bytes.size(),
14015                            &authorization_size_bytes);
14016      if (rc != TPM_RC_SUCCESS) {
14017        return rc;
14018      }
14019      command_size +=
14020          authorization_size_bytes.size() + authorization_section_bytes.size();
14021    }
14022  }
14023  std::string tag_bytes;
14024  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14025  if (rc != TPM_RC_SUCCESS) {
14026    return rc;
14027  }
14028  std::string command_size_bytes;
14029  rc = Serialize_UINT32(command_size, &command_size_bytes);
14030  if (rc != TPM_RC_SUCCESS) {
14031    return rc;
14032  }
14033  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14034                        handle_section_bytes + authorization_size_bytes +
14035                        authorization_section_bytes + parameter_section_bytes;
14036  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14037  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
14038                                            serialized_command->size());
14039  return TPM_RC_SUCCESS;
14040}
14041
14042TPM_RC Tpm::ParseResponse_EncryptDecrypt(
14043    const std::string& response,
14044    TPM2B_MAX_BUFFER* out_data,
14045    TPM2B_IV* iv_out,
14046    AuthorizationDelegate* authorization_delegate) {
14047  VLOG(3) << __func__;
14048  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14049  TPM_RC rc = TPM_RC_SUCCESS;
14050  std::string buffer(response);
14051  TPM_ST tag;
14052  std::string tag_bytes;
14053  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14054  if (rc != TPM_RC_SUCCESS) {
14055    return rc;
14056  }
14057  UINT32 response_size;
14058  std::string response_size_bytes;
14059  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14060  if (rc != TPM_RC_SUCCESS) {
14061    return rc;
14062  }
14063  TPM_RC response_code;
14064  std::string response_code_bytes;
14065  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14066  if (rc != TPM_RC_SUCCESS) {
14067    return rc;
14068  }
14069  if (response_size != response.size()) {
14070    return TPM_RC_SIZE;
14071  }
14072  if (response_code != TPM_RC_SUCCESS) {
14073    return response_code;
14074  }
14075  TPM_CC command_code = TPM_CC_EncryptDecrypt;
14076  std::string command_code_bytes;
14077  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14078  if (rc != TPM_RC_SUCCESS) {
14079    return rc;
14080  }
14081  std::string authorization_section_bytes;
14082  if (tag == TPM_ST_SESSIONS) {
14083    UINT32 parameter_section_size = buffer.size();
14084    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14085    if (rc != TPM_RC_SUCCESS) {
14086      return rc;
14087    }
14088    if (parameter_section_size > buffer.size()) {
14089      return TPM_RC_INSUFFICIENT;
14090    }
14091    authorization_section_bytes = buffer.substr(parameter_section_size);
14092    // Keep the parameter section in |buffer|.
14093    buffer.erase(parameter_section_size);
14094  }
14095  std::unique_ptr<crypto::SecureHash> hash(
14096      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14097  hash->Update(response_code_bytes.data(), response_code_bytes.size());
14098  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14099  hash->Update(buffer.data(), buffer.size());
14100  std::string response_hash(32, 0);
14101  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
14102  if (tag == TPM_ST_SESSIONS) {
14103    CHECK(authorization_delegate) << "Authorization delegate missing!";
14104    if (!authorization_delegate->CheckResponseAuthorization(
14105            response_hash, authorization_section_bytes)) {
14106      return TRUNKS_RC_AUTHORIZATION_FAILED;
14107    }
14108  }
14109  std::string out_data_bytes;
14110  rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
14111  if (rc != TPM_RC_SUCCESS) {
14112    return rc;
14113  }
14114  std::string iv_out_bytes;
14115  rc = Parse_TPM2B_IV(&buffer, iv_out, &iv_out_bytes);
14116  if (rc != TPM_RC_SUCCESS) {
14117    return rc;
14118  }
14119  if (tag == TPM_ST_SESSIONS) {
14120    CHECK(authorization_delegate) << "Authorization delegate missing!";
14121    // Decrypt just the parameter data, not the size.
14122    std::string tmp = out_data_bytes.substr(2);
14123    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
14124      return TRUNKS_RC_ENCRYPTION_FAILED;
14125    }
14126    out_data_bytes.replace(2, std::string::npos, tmp);
14127    rc = Parse_TPM2B_MAX_BUFFER(&out_data_bytes, out_data, nullptr);
14128    if (rc != TPM_RC_SUCCESS) {
14129      return rc;
14130    }
14131  }
14132  return TPM_RC_SUCCESS;
14133}
14134
14135void EncryptDecryptErrorCallback(const Tpm::EncryptDecryptResponse& callback,
14136                                 TPM_RC response_code) {
14137  VLOG(1) << __func__;
14138  callback.Run(response_code, TPM2B_MAX_BUFFER(), TPM2B_IV());
14139}
14140
14141void EncryptDecryptResponseParser(const Tpm::EncryptDecryptResponse& callback,
14142                                  AuthorizationDelegate* authorization_delegate,
14143                                  const std::string& response) {
14144  VLOG(1) << __func__;
14145  base::Callback<void(TPM_RC)> error_reporter =
14146      base::Bind(EncryptDecryptErrorCallback, callback);
14147  TPM2B_MAX_BUFFER out_data;
14148  TPM2B_IV iv_out;
14149  TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt(response, &out_data, &iv_out,
14150                                                authorization_delegate);
14151  if (rc != TPM_RC_SUCCESS) {
14152    error_reporter.Run(rc);
14153    return;
14154  }
14155  callback.Run(rc, out_data, iv_out);
14156}
14157
14158void Tpm::EncryptDecrypt(const TPMI_DH_OBJECT& key_handle,
14159                         const std::string& key_handle_name,
14160                         const TPMI_YES_NO& decrypt,
14161                         const TPMI_ALG_SYM_MODE& mode,
14162                         const TPM2B_IV& iv_in,
14163                         const TPM2B_MAX_BUFFER& in_data,
14164                         AuthorizationDelegate* authorization_delegate,
14165                         const EncryptDecryptResponse& callback) {
14166  VLOG(1) << __func__;
14167  base::Callback<void(TPM_RC)> error_reporter =
14168      base::Bind(EncryptDecryptErrorCallback, callback);
14169  base::Callback<void(const std::string&)> parser = base::Bind(
14170      EncryptDecryptResponseParser, callback, authorization_delegate);
14171  std::string command;
14172  TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14173                                              decrypt, mode, iv_in, in_data,
14174                                              &command, authorization_delegate);
14175  if (rc != TPM_RC_SUCCESS) {
14176    error_reporter.Run(rc);
14177    return;
14178  }
14179  transceiver_->SendCommand(command, parser);
14180}
14181
14182TPM_RC Tpm::EncryptDecryptSync(const TPMI_DH_OBJECT& key_handle,
14183                               const std::string& key_handle_name,
14184                               const TPMI_YES_NO& decrypt,
14185                               const TPMI_ALG_SYM_MODE& mode,
14186                               const TPM2B_IV& iv_in,
14187                               const TPM2B_MAX_BUFFER& in_data,
14188                               TPM2B_MAX_BUFFER* out_data,
14189                               TPM2B_IV* iv_out,
14190                               AuthorizationDelegate* authorization_delegate) {
14191  VLOG(1) << __func__;
14192  std::string command;
14193  TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14194                                              decrypt, mode, iv_in, in_data,
14195                                              &command, authorization_delegate);
14196  if (rc != TPM_RC_SUCCESS) {
14197    return rc;
14198  }
14199  std::string response = transceiver_->SendCommandAndWait(command);
14200  rc = ParseResponse_EncryptDecrypt(response, out_data, iv_out,
14201                                    authorization_delegate);
14202  return rc;
14203}
14204
14205TPM_RC Tpm::SerializeCommand_Hash(
14206    const TPM2B_MAX_BUFFER& data,
14207    const TPMI_ALG_HASH& hash_alg,
14208    const TPMI_RH_HIERARCHY& hierarchy,
14209    std::string* serialized_command,
14210    AuthorizationDelegate* authorization_delegate) {
14211  VLOG(3) << __func__;
14212  TPM_RC rc = TPM_RC_SUCCESS;
14213  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14214  UINT32 command_size = 10;  // Header size.
14215  std::string handle_section_bytes;
14216  std::string parameter_section_bytes;
14217  TPM_CC command_code = TPM_CC_Hash;
14218  bool is_command_parameter_encryption_possible = true;
14219  bool is_response_parameter_encryption_possible = true;
14220  std::string command_code_bytes;
14221  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14222  if (rc != TPM_RC_SUCCESS) {
14223    return rc;
14224  }
14225  std::string data_bytes;
14226  rc = Serialize_TPM2B_MAX_BUFFER(data, &data_bytes);
14227  if (rc != TPM_RC_SUCCESS) {
14228    return rc;
14229  }
14230  std::string hash_alg_bytes;
14231  rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14232  if (rc != TPM_RC_SUCCESS) {
14233    return rc;
14234  }
14235  std::string hierarchy_bytes;
14236  rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
14237  if (rc != TPM_RC_SUCCESS) {
14238    return rc;
14239  }
14240  if (authorization_delegate) {
14241    // Encrypt just the parameter data, not the size.
14242    std::string tmp = data_bytes.substr(2);
14243    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14244      return TRUNKS_RC_ENCRYPTION_FAILED;
14245    }
14246    data_bytes.replace(2, std::string::npos, tmp);
14247  }
14248  std::unique_ptr<crypto::SecureHash> hash(
14249      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14250  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14251  hash->Update(data_bytes.data(), data_bytes.size());
14252  parameter_section_bytes += data_bytes;
14253  command_size += data_bytes.size();
14254  hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14255  parameter_section_bytes += hash_alg_bytes;
14256  command_size += hash_alg_bytes.size();
14257  hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
14258  parameter_section_bytes += hierarchy_bytes;
14259  command_size += hierarchy_bytes.size();
14260  std::string command_hash(32, 0);
14261  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
14262  std::string authorization_section_bytes;
14263  std::string authorization_size_bytes;
14264  if (authorization_delegate) {
14265    if (!authorization_delegate->GetCommandAuthorization(
14266            command_hash, is_command_parameter_encryption_possible,
14267            is_response_parameter_encryption_possible,
14268            &authorization_section_bytes)) {
14269      return TRUNKS_RC_AUTHORIZATION_FAILED;
14270    }
14271    if (!authorization_section_bytes.empty()) {
14272      tag = TPM_ST_SESSIONS;
14273      std::string tmp;
14274      rc = Serialize_UINT32(authorization_section_bytes.size(),
14275                            &authorization_size_bytes);
14276      if (rc != TPM_RC_SUCCESS) {
14277        return rc;
14278      }
14279      command_size +=
14280          authorization_size_bytes.size() + authorization_section_bytes.size();
14281    }
14282  }
14283  std::string tag_bytes;
14284  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14285  if (rc != TPM_RC_SUCCESS) {
14286    return rc;
14287  }
14288  std::string command_size_bytes;
14289  rc = Serialize_UINT32(command_size, &command_size_bytes);
14290  if (rc != TPM_RC_SUCCESS) {
14291    return rc;
14292  }
14293  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14294                        handle_section_bytes + authorization_size_bytes +
14295                        authorization_section_bytes + parameter_section_bytes;
14296  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14297  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
14298                                            serialized_command->size());
14299  return TPM_RC_SUCCESS;
14300}
14301
14302TPM_RC Tpm::ParseResponse_Hash(const std::string& response,
14303                               TPM2B_DIGEST* out_hash,
14304                               TPMT_TK_HASHCHECK* validation,
14305                               AuthorizationDelegate* authorization_delegate) {
14306  VLOG(3) << __func__;
14307  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14308  TPM_RC rc = TPM_RC_SUCCESS;
14309  std::string buffer(response);
14310  TPM_ST tag;
14311  std::string tag_bytes;
14312  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14313  if (rc != TPM_RC_SUCCESS) {
14314    return rc;
14315  }
14316  UINT32 response_size;
14317  std::string response_size_bytes;
14318  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14319  if (rc != TPM_RC_SUCCESS) {
14320    return rc;
14321  }
14322  TPM_RC response_code;
14323  std::string response_code_bytes;
14324  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14325  if (rc != TPM_RC_SUCCESS) {
14326    return rc;
14327  }
14328  if (response_size != response.size()) {
14329    return TPM_RC_SIZE;
14330  }
14331  if (response_code != TPM_RC_SUCCESS) {
14332    return response_code;
14333  }
14334  TPM_CC command_code = TPM_CC_Hash;
14335  std::string command_code_bytes;
14336  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14337  if (rc != TPM_RC_SUCCESS) {
14338    return rc;
14339  }
14340  std::string authorization_section_bytes;
14341  if (tag == TPM_ST_SESSIONS) {
14342    UINT32 parameter_section_size = buffer.size();
14343    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14344    if (rc != TPM_RC_SUCCESS) {
14345      return rc;
14346    }
14347    if (parameter_section_size > buffer.size()) {
14348      return TPM_RC_INSUFFICIENT;
14349    }
14350    authorization_section_bytes = buffer.substr(parameter_section_size);
14351    // Keep the parameter section in |buffer|.
14352    buffer.erase(parameter_section_size);
14353  }
14354  std::unique_ptr<crypto::SecureHash> hash(
14355      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14356  hash->Update(response_code_bytes.data(), response_code_bytes.size());
14357  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14358  hash->Update(buffer.data(), buffer.size());
14359  std::string response_hash(32, 0);
14360  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
14361  if (tag == TPM_ST_SESSIONS) {
14362    CHECK(authorization_delegate) << "Authorization delegate missing!";
14363    if (!authorization_delegate->CheckResponseAuthorization(
14364            response_hash, authorization_section_bytes)) {
14365      return TRUNKS_RC_AUTHORIZATION_FAILED;
14366    }
14367  }
14368  std::string out_hash_bytes;
14369  rc = Parse_TPM2B_DIGEST(&buffer, out_hash, &out_hash_bytes);
14370  if (rc != TPM_RC_SUCCESS) {
14371    return rc;
14372  }
14373  std::string validation_bytes;
14374  rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
14375  if (rc != TPM_RC_SUCCESS) {
14376    return rc;
14377  }
14378  if (tag == TPM_ST_SESSIONS) {
14379    CHECK(authorization_delegate) << "Authorization delegate missing!";
14380    // Decrypt just the parameter data, not the size.
14381    std::string tmp = out_hash_bytes.substr(2);
14382    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
14383      return TRUNKS_RC_ENCRYPTION_FAILED;
14384    }
14385    out_hash_bytes.replace(2, std::string::npos, tmp);
14386    rc = Parse_TPM2B_DIGEST(&out_hash_bytes, out_hash, nullptr);
14387    if (rc != TPM_RC_SUCCESS) {
14388      return rc;
14389    }
14390  }
14391  return TPM_RC_SUCCESS;
14392}
14393
14394void HashErrorCallback(const Tpm::HashResponse& callback,
14395                       TPM_RC response_code) {
14396  VLOG(1) << __func__;
14397  callback.Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
14398}
14399
14400void HashResponseParser(const Tpm::HashResponse& callback,
14401                        AuthorizationDelegate* authorization_delegate,
14402                        const std::string& response) {
14403  VLOG(1) << __func__;
14404  base::Callback<void(TPM_RC)> error_reporter =
14405      base::Bind(HashErrorCallback, callback);
14406  TPM2B_DIGEST out_hash;
14407  TPMT_TK_HASHCHECK validation;
14408  TPM_RC rc = Tpm::ParseResponse_Hash(response, &out_hash, &validation,
14409                                      authorization_delegate);
14410  if (rc != TPM_RC_SUCCESS) {
14411    error_reporter.Run(rc);
14412    return;
14413  }
14414  callback.Run(rc, out_hash, validation);
14415}
14416
14417void Tpm::Hash(const TPM2B_MAX_BUFFER& data,
14418               const TPMI_ALG_HASH& hash_alg,
14419               const TPMI_RH_HIERARCHY& hierarchy,
14420               AuthorizationDelegate* authorization_delegate,
14421               const HashResponse& callback) {
14422  VLOG(1) << __func__;
14423  base::Callback<void(TPM_RC)> error_reporter =
14424      base::Bind(HashErrorCallback, callback);
14425  base::Callback<void(const std::string&)> parser =
14426      base::Bind(HashResponseParser, callback, authorization_delegate);
14427  std::string command;
14428  TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14429                                    authorization_delegate);
14430  if (rc != TPM_RC_SUCCESS) {
14431    error_reporter.Run(rc);
14432    return;
14433  }
14434  transceiver_->SendCommand(command, parser);
14435}
14436
14437TPM_RC Tpm::HashSync(const TPM2B_MAX_BUFFER& data,
14438                     const TPMI_ALG_HASH& hash_alg,
14439                     const TPMI_RH_HIERARCHY& hierarchy,
14440                     TPM2B_DIGEST* out_hash,
14441                     TPMT_TK_HASHCHECK* validation,
14442                     AuthorizationDelegate* authorization_delegate) {
14443  VLOG(1) << __func__;
14444  std::string command;
14445  TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14446                                    authorization_delegate);
14447  if (rc != TPM_RC_SUCCESS) {
14448    return rc;
14449  }
14450  std::string response = transceiver_->SendCommandAndWait(command);
14451  rc = ParseResponse_Hash(response, out_hash, validation,
14452                          authorization_delegate);
14453  return rc;
14454}
14455
14456TPM_RC Tpm::SerializeCommand_HMAC(
14457    const TPMI_DH_OBJECT& handle,
14458    const std::string& handle_name,
14459    const TPM2B_MAX_BUFFER& buffer,
14460    const TPMI_ALG_HASH& hash_alg,
14461    std::string* serialized_command,
14462    AuthorizationDelegate* authorization_delegate) {
14463  VLOG(3) << __func__;
14464  TPM_RC rc = TPM_RC_SUCCESS;
14465  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14466  UINT32 command_size = 10;  // Header size.
14467  std::string handle_section_bytes;
14468  std::string parameter_section_bytes;
14469  TPM_CC command_code = TPM_CC_HMAC;
14470  bool is_command_parameter_encryption_possible = true;
14471  bool is_response_parameter_encryption_possible = true;
14472  std::string command_code_bytes;
14473  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14474  if (rc != TPM_RC_SUCCESS) {
14475    return rc;
14476  }
14477  std::string handle_bytes;
14478  rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
14479  if (rc != TPM_RC_SUCCESS) {
14480    return rc;
14481  }
14482  std::string buffer_bytes;
14483  rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
14484  if (rc != TPM_RC_SUCCESS) {
14485    return rc;
14486  }
14487  std::string hash_alg_bytes;
14488  rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14489  if (rc != TPM_RC_SUCCESS) {
14490    return rc;
14491  }
14492  if (authorization_delegate) {
14493    // Encrypt just the parameter data, not the size.
14494    std::string tmp = buffer_bytes.substr(2);
14495    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14496      return TRUNKS_RC_ENCRYPTION_FAILED;
14497    }
14498    buffer_bytes.replace(2, std::string::npos, tmp);
14499  }
14500  std::unique_ptr<crypto::SecureHash> hash(
14501      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14502  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14503  hash->Update(handle_name.data(), handle_name.size());
14504  handle_section_bytes += handle_bytes;
14505  command_size += handle_bytes.size();
14506  hash->Update(buffer_bytes.data(), buffer_bytes.size());
14507  parameter_section_bytes += buffer_bytes;
14508  command_size += buffer_bytes.size();
14509  hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14510  parameter_section_bytes += hash_alg_bytes;
14511  command_size += hash_alg_bytes.size();
14512  std::string command_hash(32, 0);
14513  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
14514  std::string authorization_section_bytes;
14515  std::string authorization_size_bytes;
14516  if (authorization_delegate) {
14517    if (!authorization_delegate->GetCommandAuthorization(
14518            command_hash, is_command_parameter_encryption_possible,
14519            is_response_parameter_encryption_possible,
14520            &authorization_section_bytes)) {
14521      return TRUNKS_RC_AUTHORIZATION_FAILED;
14522    }
14523    if (!authorization_section_bytes.empty()) {
14524      tag = TPM_ST_SESSIONS;
14525      std::string tmp;
14526      rc = Serialize_UINT32(authorization_section_bytes.size(),
14527                            &authorization_size_bytes);
14528      if (rc != TPM_RC_SUCCESS) {
14529        return rc;
14530      }
14531      command_size +=
14532          authorization_size_bytes.size() + authorization_section_bytes.size();
14533    }
14534  }
14535  std::string tag_bytes;
14536  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14537  if (rc != TPM_RC_SUCCESS) {
14538    return rc;
14539  }
14540  std::string command_size_bytes;
14541  rc = Serialize_UINT32(command_size, &command_size_bytes);
14542  if (rc != TPM_RC_SUCCESS) {
14543    return rc;
14544  }
14545  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14546                        handle_section_bytes + authorization_size_bytes +
14547                        authorization_section_bytes + parameter_section_bytes;
14548  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14549  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
14550                                            serialized_command->size());
14551  return TPM_RC_SUCCESS;
14552}
14553
14554TPM_RC Tpm::ParseResponse_HMAC(const std::string& response,
14555                               TPM2B_DIGEST* out_hmac,
14556                               AuthorizationDelegate* authorization_delegate) {
14557  VLOG(3) << __func__;
14558  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14559  TPM_RC rc = TPM_RC_SUCCESS;
14560  std::string buffer(response);
14561  TPM_ST tag;
14562  std::string tag_bytes;
14563  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14564  if (rc != TPM_RC_SUCCESS) {
14565    return rc;
14566  }
14567  UINT32 response_size;
14568  std::string response_size_bytes;
14569  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14570  if (rc != TPM_RC_SUCCESS) {
14571    return rc;
14572  }
14573  TPM_RC response_code;
14574  std::string response_code_bytes;
14575  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14576  if (rc != TPM_RC_SUCCESS) {
14577    return rc;
14578  }
14579  if (response_size != response.size()) {
14580    return TPM_RC_SIZE;
14581  }
14582  if (response_code != TPM_RC_SUCCESS) {
14583    return response_code;
14584  }
14585  TPM_CC command_code = TPM_CC_HMAC;
14586  std::string command_code_bytes;
14587  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14588  if (rc != TPM_RC_SUCCESS) {
14589    return rc;
14590  }
14591  std::string authorization_section_bytes;
14592  if (tag == TPM_ST_SESSIONS) {
14593    UINT32 parameter_section_size = buffer.size();
14594    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14595    if (rc != TPM_RC_SUCCESS) {
14596      return rc;
14597    }
14598    if (parameter_section_size > buffer.size()) {
14599      return TPM_RC_INSUFFICIENT;
14600    }
14601    authorization_section_bytes = buffer.substr(parameter_section_size);
14602    // Keep the parameter section in |buffer|.
14603    buffer.erase(parameter_section_size);
14604  }
14605  std::unique_ptr<crypto::SecureHash> hash(
14606      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14607  hash->Update(response_code_bytes.data(), response_code_bytes.size());
14608  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14609  hash->Update(buffer.data(), buffer.size());
14610  std::string response_hash(32, 0);
14611  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
14612  if (tag == TPM_ST_SESSIONS) {
14613    CHECK(authorization_delegate) << "Authorization delegate missing!";
14614    if (!authorization_delegate->CheckResponseAuthorization(
14615            response_hash, authorization_section_bytes)) {
14616      return TRUNKS_RC_AUTHORIZATION_FAILED;
14617    }
14618  }
14619  std::string out_hmac_bytes;
14620  rc = Parse_TPM2B_DIGEST(&buffer, out_hmac, &out_hmac_bytes);
14621  if (rc != TPM_RC_SUCCESS) {
14622    return rc;
14623  }
14624  if (tag == TPM_ST_SESSIONS) {
14625    CHECK(authorization_delegate) << "Authorization delegate missing!";
14626    // Decrypt just the parameter data, not the size.
14627    std::string tmp = out_hmac_bytes.substr(2);
14628    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
14629      return TRUNKS_RC_ENCRYPTION_FAILED;
14630    }
14631    out_hmac_bytes.replace(2, std::string::npos, tmp);
14632    rc = Parse_TPM2B_DIGEST(&out_hmac_bytes, out_hmac, nullptr);
14633    if (rc != TPM_RC_SUCCESS) {
14634      return rc;
14635    }
14636  }
14637  return TPM_RC_SUCCESS;
14638}
14639
14640void HMACErrorCallback(const Tpm::HMACResponse& callback,
14641                       TPM_RC response_code) {
14642  VLOG(1) << __func__;
14643  callback.Run(response_code, TPM2B_DIGEST());
14644}
14645
14646void HMACResponseParser(const Tpm::HMACResponse& callback,
14647                        AuthorizationDelegate* authorization_delegate,
14648                        const std::string& response) {
14649  VLOG(1) << __func__;
14650  base::Callback<void(TPM_RC)> error_reporter =
14651      base::Bind(HMACErrorCallback, callback);
14652  TPM2B_DIGEST out_hmac;
14653  TPM_RC rc =
14654      Tpm::ParseResponse_HMAC(response, &out_hmac, authorization_delegate);
14655  if (rc != TPM_RC_SUCCESS) {
14656    error_reporter.Run(rc);
14657    return;
14658  }
14659  callback.Run(rc, out_hmac);
14660}
14661
14662void Tpm::HMAC(const TPMI_DH_OBJECT& handle,
14663               const std::string& handle_name,
14664               const TPM2B_MAX_BUFFER& buffer,
14665               const TPMI_ALG_HASH& hash_alg,
14666               AuthorizationDelegate* authorization_delegate,
14667               const HMACResponse& callback) {
14668  VLOG(1) << __func__;
14669  base::Callback<void(TPM_RC)> error_reporter =
14670      base::Bind(HMACErrorCallback, callback);
14671  base::Callback<void(const std::string&)> parser =
14672      base::Bind(HMACResponseParser, callback, authorization_delegate);
14673  std::string command;
14674  TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14675                                    &command, authorization_delegate);
14676  if (rc != TPM_RC_SUCCESS) {
14677    error_reporter.Run(rc);
14678    return;
14679  }
14680  transceiver_->SendCommand(command, parser);
14681}
14682
14683TPM_RC Tpm::HMACSync(const TPMI_DH_OBJECT& handle,
14684                     const std::string& handle_name,
14685                     const TPM2B_MAX_BUFFER& buffer,
14686                     const TPMI_ALG_HASH& hash_alg,
14687                     TPM2B_DIGEST* out_hmac,
14688                     AuthorizationDelegate* authorization_delegate) {
14689  VLOG(1) << __func__;
14690  std::string command;
14691  TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14692                                    &command, authorization_delegate);
14693  if (rc != TPM_RC_SUCCESS) {
14694    return rc;
14695  }
14696  std::string response = transceiver_->SendCommandAndWait(command);
14697  rc = ParseResponse_HMAC(response, out_hmac, authorization_delegate);
14698  return rc;
14699}
14700
14701TPM_RC Tpm::SerializeCommand_GetRandom(
14702    const UINT16& bytes_requested,
14703    std::string* serialized_command,
14704    AuthorizationDelegate* authorization_delegate) {
14705  VLOG(3) << __func__;
14706  TPM_RC rc = TPM_RC_SUCCESS;
14707  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14708  UINT32 command_size = 10;  // Header size.
14709  std::string handle_section_bytes;
14710  std::string parameter_section_bytes;
14711  TPM_CC command_code = TPM_CC_GetRandom;
14712  bool is_command_parameter_encryption_possible = false;
14713  bool is_response_parameter_encryption_possible = true;
14714  std::string command_code_bytes;
14715  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14716  if (rc != TPM_RC_SUCCESS) {
14717    return rc;
14718  }
14719  std::string bytes_requested_bytes;
14720  rc = Serialize_UINT16(bytes_requested, &bytes_requested_bytes);
14721  if (rc != TPM_RC_SUCCESS) {
14722    return rc;
14723  }
14724  std::unique_ptr<crypto::SecureHash> hash(
14725      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14726  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14727  hash->Update(bytes_requested_bytes.data(), bytes_requested_bytes.size());
14728  parameter_section_bytes += bytes_requested_bytes;
14729  command_size += bytes_requested_bytes.size();
14730  std::string command_hash(32, 0);
14731  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
14732  std::string authorization_section_bytes;
14733  std::string authorization_size_bytes;
14734  if (authorization_delegate) {
14735    if (!authorization_delegate->GetCommandAuthorization(
14736            command_hash, is_command_parameter_encryption_possible,
14737            is_response_parameter_encryption_possible,
14738            &authorization_section_bytes)) {
14739      return TRUNKS_RC_AUTHORIZATION_FAILED;
14740    }
14741    if (!authorization_section_bytes.empty()) {
14742      tag = TPM_ST_SESSIONS;
14743      std::string tmp;
14744      rc = Serialize_UINT32(authorization_section_bytes.size(),
14745                            &authorization_size_bytes);
14746      if (rc != TPM_RC_SUCCESS) {
14747        return rc;
14748      }
14749      command_size +=
14750          authorization_size_bytes.size() + authorization_section_bytes.size();
14751    }
14752  }
14753  std::string tag_bytes;
14754  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14755  if (rc != TPM_RC_SUCCESS) {
14756    return rc;
14757  }
14758  std::string command_size_bytes;
14759  rc = Serialize_UINT32(command_size, &command_size_bytes);
14760  if (rc != TPM_RC_SUCCESS) {
14761    return rc;
14762  }
14763  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14764                        handle_section_bytes + authorization_size_bytes +
14765                        authorization_section_bytes + parameter_section_bytes;
14766  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14767  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
14768                                            serialized_command->size());
14769  return TPM_RC_SUCCESS;
14770}
14771
14772TPM_RC Tpm::ParseResponse_GetRandom(
14773    const std::string& response,
14774    TPM2B_DIGEST* random_bytes,
14775    AuthorizationDelegate* authorization_delegate) {
14776  VLOG(3) << __func__;
14777  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14778  TPM_RC rc = TPM_RC_SUCCESS;
14779  std::string buffer(response);
14780  TPM_ST tag;
14781  std::string tag_bytes;
14782  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14783  if (rc != TPM_RC_SUCCESS) {
14784    return rc;
14785  }
14786  UINT32 response_size;
14787  std::string response_size_bytes;
14788  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14789  if (rc != TPM_RC_SUCCESS) {
14790    return rc;
14791  }
14792  TPM_RC response_code;
14793  std::string response_code_bytes;
14794  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14795  if (rc != TPM_RC_SUCCESS) {
14796    return rc;
14797  }
14798  if (response_size != response.size()) {
14799    return TPM_RC_SIZE;
14800  }
14801  if (response_code != TPM_RC_SUCCESS) {
14802    return response_code;
14803  }
14804  TPM_CC command_code = TPM_CC_GetRandom;
14805  std::string command_code_bytes;
14806  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14807  if (rc != TPM_RC_SUCCESS) {
14808    return rc;
14809  }
14810  std::string authorization_section_bytes;
14811  if (tag == TPM_ST_SESSIONS) {
14812    UINT32 parameter_section_size = buffer.size();
14813    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14814    if (rc != TPM_RC_SUCCESS) {
14815      return rc;
14816    }
14817    if (parameter_section_size > buffer.size()) {
14818      return TPM_RC_INSUFFICIENT;
14819    }
14820    authorization_section_bytes = buffer.substr(parameter_section_size);
14821    // Keep the parameter section in |buffer|.
14822    buffer.erase(parameter_section_size);
14823  }
14824  std::unique_ptr<crypto::SecureHash> hash(
14825      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14826  hash->Update(response_code_bytes.data(), response_code_bytes.size());
14827  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14828  hash->Update(buffer.data(), buffer.size());
14829  std::string response_hash(32, 0);
14830  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
14831  if (tag == TPM_ST_SESSIONS) {
14832    CHECK(authorization_delegate) << "Authorization delegate missing!";
14833    if (!authorization_delegate->CheckResponseAuthorization(
14834            response_hash, authorization_section_bytes)) {
14835      return TRUNKS_RC_AUTHORIZATION_FAILED;
14836    }
14837  }
14838  std::string random_bytes_bytes;
14839  rc = Parse_TPM2B_DIGEST(&buffer, random_bytes, &random_bytes_bytes);
14840  if (rc != TPM_RC_SUCCESS) {
14841    return rc;
14842  }
14843  if (tag == TPM_ST_SESSIONS) {
14844    CHECK(authorization_delegate) << "Authorization delegate missing!";
14845    // Decrypt just the parameter data, not the size.
14846    std::string tmp = random_bytes_bytes.substr(2);
14847    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
14848      return TRUNKS_RC_ENCRYPTION_FAILED;
14849    }
14850    random_bytes_bytes.replace(2, std::string::npos, tmp);
14851    rc = Parse_TPM2B_DIGEST(&random_bytes_bytes, random_bytes, nullptr);
14852    if (rc != TPM_RC_SUCCESS) {
14853      return rc;
14854    }
14855  }
14856  return TPM_RC_SUCCESS;
14857}
14858
14859void GetRandomErrorCallback(const Tpm::GetRandomResponse& callback,
14860                            TPM_RC response_code) {
14861  VLOG(1) << __func__;
14862  callback.Run(response_code, TPM2B_DIGEST());
14863}
14864
14865void GetRandomResponseParser(const Tpm::GetRandomResponse& callback,
14866                             AuthorizationDelegate* authorization_delegate,
14867                             const std::string& response) {
14868  VLOG(1) << __func__;
14869  base::Callback<void(TPM_RC)> error_reporter =
14870      base::Bind(GetRandomErrorCallback, callback);
14871  TPM2B_DIGEST random_bytes;
14872  TPM_RC rc = Tpm::ParseResponse_GetRandom(response, &random_bytes,
14873                                           authorization_delegate);
14874  if (rc != TPM_RC_SUCCESS) {
14875    error_reporter.Run(rc);
14876    return;
14877  }
14878  callback.Run(rc, random_bytes);
14879}
14880
14881void Tpm::GetRandom(const UINT16& bytes_requested,
14882                    AuthorizationDelegate* authorization_delegate,
14883                    const GetRandomResponse& callback) {
14884  VLOG(1) << __func__;
14885  base::Callback<void(TPM_RC)> error_reporter =
14886      base::Bind(GetRandomErrorCallback, callback);
14887  base::Callback<void(const std::string&)> parser =
14888      base::Bind(GetRandomResponseParser, callback, authorization_delegate);
14889  std::string command;
14890  TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
14891                                         authorization_delegate);
14892  if (rc != TPM_RC_SUCCESS) {
14893    error_reporter.Run(rc);
14894    return;
14895  }
14896  transceiver_->SendCommand(command, parser);
14897}
14898
14899TPM_RC Tpm::GetRandomSync(const UINT16& bytes_requested,
14900                          TPM2B_DIGEST* random_bytes,
14901                          AuthorizationDelegate* authorization_delegate) {
14902  VLOG(1) << __func__;
14903  std::string command;
14904  TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
14905                                         authorization_delegate);
14906  if (rc != TPM_RC_SUCCESS) {
14907    return rc;
14908  }
14909  std::string response = transceiver_->SendCommandAndWait(command);
14910  rc = ParseResponse_GetRandom(response, random_bytes, authorization_delegate);
14911  return rc;
14912}
14913
14914TPM_RC Tpm::SerializeCommand_StirRandom(
14915    const TPM2B_SENSITIVE_DATA& in_data,
14916    std::string* serialized_command,
14917    AuthorizationDelegate* authorization_delegate) {
14918  VLOG(3) << __func__;
14919  TPM_RC rc = TPM_RC_SUCCESS;
14920  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14921  UINT32 command_size = 10;  // Header size.
14922  std::string handle_section_bytes;
14923  std::string parameter_section_bytes;
14924  TPM_CC command_code = TPM_CC_StirRandom;
14925  bool is_command_parameter_encryption_possible = true;
14926  bool is_response_parameter_encryption_possible = false;
14927  std::string command_code_bytes;
14928  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14929  if (rc != TPM_RC_SUCCESS) {
14930    return rc;
14931  }
14932  std::string in_data_bytes;
14933  rc = Serialize_TPM2B_SENSITIVE_DATA(in_data, &in_data_bytes);
14934  if (rc != TPM_RC_SUCCESS) {
14935    return rc;
14936  }
14937  if (authorization_delegate) {
14938    // Encrypt just the parameter data, not the size.
14939    std::string tmp = in_data_bytes.substr(2);
14940    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14941      return TRUNKS_RC_ENCRYPTION_FAILED;
14942    }
14943    in_data_bytes.replace(2, std::string::npos, tmp);
14944  }
14945  std::unique_ptr<crypto::SecureHash> hash(
14946      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14947  hash->Update(command_code_bytes.data(), command_code_bytes.size());
14948  hash->Update(in_data_bytes.data(), in_data_bytes.size());
14949  parameter_section_bytes += in_data_bytes;
14950  command_size += in_data_bytes.size();
14951  std::string command_hash(32, 0);
14952  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
14953  std::string authorization_section_bytes;
14954  std::string authorization_size_bytes;
14955  if (authorization_delegate) {
14956    if (!authorization_delegate->GetCommandAuthorization(
14957            command_hash, is_command_parameter_encryption_possible,
14958            is_response_parameter_encryption_possible,
14959            &authorization_section_bytes)) {
14960      return TRUNKS_RC_AUTHORIZATION_FAILED;
14961    }
14962    if (!authorization_section_bytes.empty()) {
14963      tag = TPM_ST_SESSIONS;
14964      std::string tmp;
14965      rc = Serialize_UINT32(authorization_section_bytes.size(),
14966                            &authorization_size_bytes);
14967      if (rc != TPM_RC_SUCCESS) {
14968        return rc;
14969      }
14970      command_size +=
14971          authorization_size_bytes.size() + authorization_section_bytes.size();
14972    }
14973  }
14974  std::string tag_bytes;
14975  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14976  if (rc != TPM_RC_SUCCESS) {
14977    return rc;
14978  }
14979  std::string command_size_bytes;
14980  rc = Serialize_UINT32(command_size, &command_size_bytes);
14981  if (rc != TPM_RC_SUCCESS) {
14982    return rc;
14983  }
14984  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14985                        handle_section_bytes + authorization_size_bytes +
14986                        authorization_section_bytes + parameter_section_bytes;
14987  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14988  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
14989                                            serialized_command->size());
14990  return TPM_RC_SUCCESS;
14991}
14992
14993TPM_RC Tpm::ParseResponse_StirRandom(
14994    const std::string& response,
14995    AuthorizationDelegate* authorization_delegate) {
14996  VLOG(3) << __func__;
14997  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14998  TPM_RC rc = TPM_RC_SUCCESS;
14999  std::string buffer(response);
15000  TPM_ST tag;
15001  std::string tag_bytes;
15002  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15003  if (rc != TPM_RC_SUCCESS) {
15004    return rc;
15005  }
15006  UINT32 response_size;
15007  std::string response_size_bytes;
15008  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15009  if (rc != TPM_RC_SUCCESS) {
15010    return rc;
15011  }
15012  TPM_RC response_code;
15013  std::string response_code_bytes;
15014  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15015  if (rc != TPM_RC_SUCCESS) {
15016    return rc;
15017  }
15018  if (response_size != response.size()) {
15019    return TPM_RC_SIZE;
15020  }
15021  if (response_code != TPM_RC_SUCCESS) {
15022    return response_code;
15023  }
15024  TPM_CC command_code = TPM_CC_StirRandom;
15025  std::string command_code_bytes;
15026  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15027  if (rc != TPM_RC_SUCCESS) {
15028    return rc;
15029  }
15030  std::string authorization_section_bytes;
15031  if (tag == TPM_ST_SESSIONS) {
15032    UINT32 parameter_section_size = buffer.size();
15033    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15034    if (rc != TPM_RC_SUCCESS) {
15035      return rc;
15036    }
15037    if (parameter_section_size > buffer.size()) {
15038      return TPM_RC_INSUFFICIENT;
15039    }
15040    authorization_section_bytes = buffer.substr(parameter_section_size);
15041    // Keep the parameter section in |buffer|.
15042    buffer.erase(parameter_section_size);
15043  }
15044  std::unique_ptr<crypto::SecureHash> hash(
15045      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15046  hash->Update(response_code_bytes.data(), response_code_bytes.size());
15047  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15048  hash->Update(buffer.data(), buffer.size());
15049  std::string response_hash(32, 0);
15050  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
15051  if (tag == TPM_ST_SESSIONS) {
15052    CHECK(authorization_delegate) << "Authorization delegate missing!";
15053    if (!authorization_delegate->CheckResponseAuthorization(
15054            response_hash, authorization_section_bytes)) {
15055      return TRUNKS_RC_AUTHORIZATION_FAILED;
15056    }
15057  }
15058  return TPM_RC_SUCCESS;
15059}
15060
15061void StirRandomErrorCallback(const Tpm::StirRandomResponse& callback,
15062                             TPM_RC response_code) {
15063  VLOG(1) << __func__;
15064  callback.Run(response_code);
15065}
15066
15067void StirRandomResponseParser(const Tpm::StirRandomResponse& callback,
15068                              AuthorizationDelegate* authorization_delegate,
15069                              const std::string& response) {
15070  VLOG(1) << __func__;
15071  base::Callback<void(TPM_RC)> error_reporter =
15072      base::Bind(StirRandomErrorCallback, callback);
15073  TPM_RC rc = Tpm::ParseResponse_StirRandom(response, authorization_delegate);
15074  if (rc != TPM_RC_SUCCESS) {
15075    error_reporter.Run(rc);
15076    return;
15077  }
15078  callback.Run(rc);
15079}
15080
15081void Tpm::StirRandom(const TPM2B_SENSITIVE_DATA& in_data,
15082                     AuthorizationDelegate* authorization_delegate,
15083                     const StirRandomResponse& callback) {
15084  VLOG(1) << __func__;
15085  base::Callback<void(TPM_RC)> error_reporter =
15086      base::Bind(StirRandomErrorCallback, callback);
15087  base::Callback<void(const std::string&)> parser =
15088      base::Bind(StirRandomResponseParser, callback, authorization_delegate);
15089  std::string command;
15090  TPM_RC rc =
15091      SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15092  if (rc != TPM_RC_SUCCESS) {
15093    error_reporter.Run(rc);
15094    return;
15095  }
15096  transceiver_->SendCommand(command, parser);
15097}
15098
15099TPM_RC Tpm::StirRandomSync(const TPM2B_SENSITIVE_DATA& in_data,
15100                           AuthorizationDelegate* authorization_delegate) {
15101  VLOG(1) << __func__;
15102  std::string command;
15103  TPM_RC rc =
15104      SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15105  if (rc != TPM_RC_SUCCESS) {
15106    return rc;
15107  }
15108  std::string response = transceiver_->SendCommandAndWait(command);
15109  rc = ParseResponse_StirRandom(response, authorization_delegate);
15110  return rc;
15111}
15112
15113TPM_RC Tpm::SerializeCommand_HMAC_Start(
15114    const TPMI_DH_OBJECT& handle,
15115    const std::string& handle_name,
15116    const TPM2B_AUTH& auth,
15117    const TPMI_ALG_HASH& hash_alg,
15118    std::string* serialized_command,
15119    AuthorizationDelegate* authorization_delegate) {
15120  VLOG(3) << __func__;
15121  TPM_RC rc = TPM_RC_SUCCESS;
15122  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15123  UINT32 command_size = 10;  // Header size.
15124  std::string handle_section_bytes;
15125  std::string parameter_section_bytes;
15126  TPM_CC command_code = TPM_CC_HMAC_Start;
15127  bool is_command_parameter_encryption_possible = true;
15128  bool is_response_parameter_encryption_possible = false;
15129  std::string command_code_bytes;
15130  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15131  if (rc != TPM_RC_SUCCESS) {
15132    return rc;
15133  }
15134  std::string handle_bytes;
15135  rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
15136  if (rc != TPM_RC_SUCCESS) {
15137    return rc;
15138  }
15139  std::string auth_bytes;
15140  rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15141  if (rc != TPM_RC_SUCCESS) {
15142    return rc;
15143  }
15144  std::string hash_alg_bytes;
15145  rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15146  if (rc != TPM_RC_SUCCESS) {
15147    return rc;
15148  }
15149  if (authorization_delegate) {
15150    // Encrypt just the parameter data, not the size.
15151    std::string tmp = auth_bytes.substr(2);
15152    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15153      return TRUNKS_RC_ENCRYPTION_FAILED;
15154    }
15155    auth_bytes.replace(2, std::string::npos, tmp);
15156  }
15157  std::unique_ptr<crypto::SecureHash> hash(
15158      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15159  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15160  hash->Update(handle_name.data(), handle_name.size());
15161  handle_section_bytes += handle_bytes;
15162  command_size += handle_bytes.size();
15163  hash->Update(auth_bytes.data(), auth_bytes.size());
15164  parameter_section_bytes += auth_bytes;
15165  command_size += auth_bytes.size();
15166  hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15167  parameter_section_bytes += hash_alg_bytes;
15168  command_size += hash_alg_bytes.size();
15169  std::string command_hash(32, 0);
15170  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
15171  std::string authorization_section_bytes;
15172  std::string authorization_size_bytes;
15173  if (authorization_delegate) {
15174    if (!authorization_delegate->GetCommandAuthorization(
15175            command_hash, is_command_parameter_encryption_possible,
15176            is_response_parameter_encryption_possible,
15177            &authorization_section_bytes)) {
15178      return TRUNKS_RC_AUTHORIZATION_FAILED;
15179    }
15180    if (!authorization_section_bytes.empty()) {
15181      tag = TPM_ST_SESSIONS;
15182      std::string tmp;
15183      rc = Serialize_UINT32(authorization_section_bytes.size(),
15184                            &authorization_size_bytes);
15185      if (rc != TPM_RC_SUCCESS) {
15186        return rc;
15187      }
15188      command_size +=
15189          authorization_size_bytes.size() + authorization_section_bytes.size();
15190    }
15191  }
15192  std::string tag_bytes;
15193  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15194  if (rc != TPM_RC_SUCCESS) {
15195    return rc;
15196  }
15197  std::string command_size_bytes;
15198  rc = Serialize_UINT32(command_size, &command_size_bytes);
15199  if (rc != TPM_RC_SUCCESS) {
15200    return rc;
15201  }
15202  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15203                        handle_section_bytes + authorization_size_bytes +
15204                        authorization_section_bytes + parameter_section_bytes;
15205  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15206  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
15207                                            serialized_command->size());
15208  return TPM_RC_SUCCESS;
15209}
15210
15211TPM_RC Tpm::ParseResponse_HMAC_Start(
15212    const std::string& response,
15213    TPMI_DH_OBJECT* sequence_handle,
15214    AuthorizationDelegate* authorization_delegate) {
15215  VLOG(3) << __func__;
15216  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15217  TPM_RC rc = TPM_RC_SUCCESS;
15218  std::string buffer(response);
15219  TPM_ST tag;
15220  std::string tag_bytes;
15221  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15222  if (rc != TPM_RC_SUCCESS) {
15223    return rc;
15224  }
15225  UINT32 response_size;
15226  std::string response_size_bytes;
15227  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15228  if (rc != TPM_RC_SUCCESS) {
15229    return rc;
15230  }
15231  TPM_RC response_code;
15232  std::string response_code_bytes;
15233  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15234  if (rc != TPM_RC_SUCCESS) {
15235    return rc;
15236  }
15237  if (response_size != response.size()) {
15238    return TPM_RC_SIZE;
15239  }
15240  if (response_code != TPM_RC_SUCCESS) {
15241    return response_code;
15242  }
15243  std::string sequence_handle_bytes;
15244  rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15245  if (rc != TPM_RC_SUCCESS) {
15246    return rc;
15247  }
15248  TPM_CC command_code = TPM_CC_HMAC_Start;
15249  std::string command_code_bytes;
15250  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15251  if (rc != TPM_RC_SUCCESS) {
15252    return rc;
15253  }
15254  std::string authorization_section_bytes;
15255  if (tag == TPM_ST_SESSIONS) {
15256    UINT32 parameter_section_size = buffer.size();
15257    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15258    if (rc != TPM_RC_SUCCESS) {
15259      return rc;
15260    }
15261    if (parameter_section_size > buffer.size()) {
15262      return TPM_RC_INSUFFICIENT;
15263    }
15264    authorization_section_bytes = buffer.substr(parameter_section_size);
15265    // Keep the parameter section in |buffer|.
15266    buffer.erase(parameter_section_size);
15267  }
15268  std::unique_ptr<crypto::SecureHash> hash(
15269      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15270  hash->Update(response_code_bytes.data(), response_code_bytes.size());
15271  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15272  hash->Update(buffer.data(), buffer.size());
15273  std::string response_hash(32, 0);
15274  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
15275  if (tag == TPM_ST_SESSIONS) {
15276    CHECK(authorization_delegate) << "Authorization delegate missing!";
15277    if (!authorization_delegate->CheckResponseAuthorization(
15278            response_hash, authorization_section_bytes)) {
15279      return TRUNKS_RC_AUTHORIZATION_FAILED;
15280    }
15281  }
15282  return TPM_RC_SUCCESS;
15283}
15284
15285void HMAC_StartErrorCallback(const Tpm::HMAC_StartResponse& callback,
15286                             TPM_RC response_code) {
15287  VLOG(1) << __func__;
15288  callback.Run(response_code, TPMI_DH_OBJECT());
15289}
15290
15291void HMAC_StartResponseParser(const Tpm::HMAC_StartResponse& callback,
15292                              AuthorizationDelegate* authorization_delegate,
15293                              const std::string& response) {
15294  VLOG(1) << __func__;
15295  base::Callback<void(TPM_RC)> error_reporter =
15296      base::Bind(HMAC_StartErrorCallback, callback);
15297  TPMI_DH_OBJECT sequence_handle;
15298  TPM_RC rc = Tpm::ParseResponse_HMAC_Start(response, &sequence_handle,
15299                                            authorization_delegate);
15300  if (rc != TPM_RC_SUCCESS) {
15301    error_reporter.Run(rc);
15302    return;
15303  }
15304  callback.Run(rc, sequence_handle);
15305}
15306
15307void Tpm::HMAC_Start(const TPMI_DH_OBJECT& handle,
15308                     const std::string& handle_name,
15309                     const TPM2B_AUTH& auth,
15310                     const TPMI_ALG_HASH& hash_alg,
15311                     AuthorizationDelegate* authorization_delegate,
15312                     const HMAC_StartResponse& callback) {
15313  VLOG(1) << __func__;
15314  base::Callback<void(TPM_RC)> error_reporter =
15315      base::Bind(HMAC_StartErrorCallback, callback);
15316  base::Callback<void(const std::string&)> parser =
15317      base::Bind(HMAC_StartResponseParser, callback, authorization_delegate);
15318  std::string command;
15319  TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15320                                          &command, authorization_delegate);
15321  if (rc != TPM_RC_SUCCESS) {
15322    error_reporter.Run(rc);
15323    return;
15324  }
15325  transceiver_->SendCommand(command, parser);
15326}
15327
15328TPM_RC Tpm::HMAC_StartSync(const TPMI_DH_OBJECT& handle,
15329                           const std::string& handle_name,
15330                           const TPM2B_AUTH& auth,
15331                           const TPMI_ALG_HASH& hash_alg,
15332                           TPMI_DH_OBJECT* sequence_handle,
15333                           AuthorizationDelegate* authorization_delegate) {
15334  VLOG(1) << __func__;
15335  std::string command;
15336  TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15337                                          &command, authorization_delegate);
15338  if (rc != TPM_RC_SUCCESS) {
15339    return rc;
15340  }
15341  std::string response = transceiver_->SendCommandAndWait(command);
15342  rc = ParseResponse_HMAC_Start(response, sequence_handle,
15343                                authorization_delegate);
15344  return rc;
15345}
15346
15347TPM_RC Tpm::SerializeCommand_HashSequenceStart(
15348    const TPM2B_AUTH& auth,
15349    const TPMI_ALG_HASH& hash_alg,
15350    std::string* serialized_command,
15351    AuthorizationDelegate* authorization_delegate) {
15352  VLOG(3) << __func__;
15353  TPM_RC rc = TPM_RC_SUCCESS;
15354  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15355  UINT32 command_size = 10;  // Header size.
15356  std::string handle_section_bytes;
15357  std::string parameter_section_bytes;
15358  TPM_CC command_code = TPM_CC_HashSequenceStart;
15359  bool is_command_parameter_encryption_possible = true;
15360  bool is_response_parameter_encryption_possible = false;
15361  std::string command_code_bytes;
15362  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15363  if (rc != TPM_RC_SUCCESS) {
15364    return rc;
15365  }
15366  std::string auth_bytes;
15367  rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15368  if (rc != TPM_RC_SUCCESS) {
15369    return rc;
15370  }
15371  std::string hash_alg_bytes;
15372  rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15373  if (rc != TPM_RC_SUCCESS) {
15374    return rc;
15375  }
15376  if (authorization_delegate) {
15377    // Encrypt just the parameter data, not the size.
15378    std::string tmp = auth_bytes.substr(2);
15379    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15380      return TRUNKS_RC_ENCRYPTION_FAILED;
15381    }
15382    auth_bytes.replace(2, std::string::npos, tmp);
15383  }
15384  std::unique_ptr<crypto::SecureHash> hash(
15385      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15386  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15387  hash->Update(auth_bytes.data(), auth_bytes.size());
15388  parameter_section_bytes += auth_bytes;
15389  command_size += auth_bytes.size();
15390  hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15391  parameter_section_bytes += hash_alg_bytes;
15392  command_size += hash_alg_bytes.size();
15393  std::string command_hash(32, 0);
15394  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
15395  std::string authorization_section_bytes;
15396  std::string authorization_size_bytes;
15397  if (authorization_delegate) {
15398    if (!authorization_delegate->GetCommandAuthorization(
15399            command_hash, is_command_parameter_encryption_possible,
15400            is_response_parameter_encryption_possible,
15401            &authorization_section_bytes)) {
15402      return TRUNKS_RC_AUTHORIZATION_FAILED;
15403    }
15404    if (!authorization_section_bytes.empty()) {
15405      tag = TPM_ST_SESSIONS;
15406      std::string tmp;
15407      rc = Serialize_UINT32(authorization_section_bytes.size(),
15408                            &authorization_size_bytes);
15409      if (rc != TPM_RC_SUCCESS) {
15410        return rc;
15411      }
15412      command_size +=
15413          authorization_size_bytes.size() + authorization_section_bytes.size();
15414    }
15415  }
15416  std::string tag_bytes;
15417  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15418  if (rc != TPM_RC_SUCCESS) {
15419    return rc;
15420  }
15421  std::string command_size_bytes;
15422  rc = Serialize_UINT32(command_size, &command_size_bytes);
15423  if (rc != TPM_RC_SUCCESS) {
15424    return rc;
15425  }
15426  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15427                        handle_section_bytes + authorization_size_bytes +
15428                        authorization_section_bytes + parameter_section_bytes;
15429  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15430  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
15431                                            serialized_command->size());
15432  return TPM_RC_SUCCESS;
15433}
15434
15435TPM_RC Tpm::ParseResponse_HashSequenceStart(
15436    const std::string& response,
15437    TPMI_DH_OBJECT* sequence_handle,
15438    AuthorizationDelegate* authorization_delegate) {
15439  VLOG(3) << __func__;
15440  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15441  TPM_RC rc = TPM_RC_SUCCESS;
15442  std::string buffer(response);
15443  TPM_ST tag;
15444  std::string tag_bytes;
15445  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15446  if (rc != TPM_RC_SUCCESS) {
15447    return rc;
15448  }
15449  UINT32 response_size;
15450  std::string response_size_bytes;
15451  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15452  if (rc != TPM_RC_SUCCESS) {
15453    return rc;
15454  }
15455  TPM_RC response_code;
15456  std::string response_code_bytes;
15457  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15458  if (rc != TPM_RC_SUCCESS) {
15459    return rc;
15460  }
15461  if (response_size != response.size()) {
15462    return TPM_RC_SIZE;
15463  }
15464  if (response_code != TPM_RC_SUCCESS) {
15465    return response_code;
15466  }
15467  std::string sequence_handle_bytes;
15468  rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15469  if (rc != TPM_RC_SUCCESS) {
15470    return rc;
15471  }
15472  TPM_CC command_code = TPM_CC_HashSequenceStart;
15473  std::string command_code_bytes;
15474  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15475  if (rc != TPM_RC_SUCCESS) {
15476    return rc;
15477  }
15478  std::string authorization_section_bytes;
15479  if (tag == TPM_ST_SESSIONS) {
15480    UINT32 parameter_section_size = buffer.size();
15481    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15482    if (rc != TPM_RC_SUCCESS) {
15483      return rc;
15484    }
15485    if (parameter_section_size > buffer.size()) {
15486      return TPM_RC_INSUFFICIENT;
15487    }
15488    authorization_section_bytes = buffer.substr(parameter_section_size);
15489    // Keep the parameter section in |buffer|.
15490    buffer.erase(parameter_section_size);
15491  }
15492  std::unique_ptr<crypto::SecureHash> hash(
15493      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15494  hash->Update(response_code_bytes.data(), response_code_bytes.size());
15495  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15496  hash->Update(buffer.data(), buffer.size());
15497  std::string response_hash(32, 0);
15498  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
15499  if (tag == TPM_ST_SESSIONS) {
15500    CHECK(authorization_delegate) << "Authorization delegate missing!";
15501    if (!authorization_delegate->CheckResponseAuthorization(
15502            response_hash, authorization_section_bytes)) {
15503      return TRUNKS_RC_AUTHORIZATION_FAILED;
15504    }
15505  }
15506  return TPM_RC_SUCCESS;
15507}
15508
15509void HashSequenceStartErrorCallback(
15510    const Tpm::HashSequenceStartResponse& callback,
15511    TPM_RC response_code) {
15512  VLOG(1) << __func__;
15513  callback.Run(response_code, TPMI_DH_OBJECT());
15514}
15515
15516void HashSequenceStartResponseParser(
15517    const Tpm::HashSequenceStartResponse& callback,
15518    AuthorizationDelegate* authorization_delegate,
15519    const std::string& response) {
15520  VLOG(1) << __func__;
15521  base::Callback<void(TPM_RC)> error_reporter =
15522      base::Bind(HashSequenceStartErrorCallback, callback);
15523  TPMI_DH_OBJECT sequence_handle;
15524  TPM_RC rc = Tpm::ParseResponse_HashSequenceStart(response, &sequence_handle,
15525                                                   authorization_delegate);
15526  if (rc != TPM_RC_SUCCESS) {
15527    error_reporter.Run(rc);
15528    return;
15529  }
15530  callback.Run(rc, sequence_handle);
15531}
15532
15533void Tpm::HashSequenceStart(const TPM2B_AUTH& auth,
15534                            const TPMI_ALG_HASH& hash_alg,
15535                            AuthorizationDelegate* authorization_delegate,
15536                            const HashSequenceStartResponse& callback) {
15537  VLOG(1) << __func__;
15538  base::Callback<void(TPM_RC)> error_reporter =
15539      base::Bind(HashSequenceStartErrorCallback, callback);
15540  base::Callback<void(const std::string&)> parser = base::Bind(
15541      HashSequenceStartResponseParser, callback, authorization_delegate);
15542  std::string command;
15543  TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15544                                                 authorization_delegate);
15545  if (rc != TPM_RC_SUCCESS) {
15546    error_reporter.Run(rc);
15547    return;
15548  }
15549  transceiver_->SendCommand(command, parser);
15550}
15551
15552TPM_RC Tpm::HashSequenceStartSync(
15553    const TPM2B_AUTH& auth,
15554    const TPMI_ALG_HASH& hash_alg,
15555    TPMI_DH_OBJECT* sequence_handle,
15556    AuthorizationDelegate* authorization_delegate) {
15557  VLOG(1) << __func__;
15558  std::string command;
15559  TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15560                                                 authorization_delegate);
15561  if (rc != TPM_RC_SUCCESS) {
15562    return rc;
15563  }
15564  std::string response = transceiver_->SendCommandAndWait(command);
15565  rc = ParseResponse_HashSequenceStart(response, sequence_handle,
15566                                       authorization_delegate);
15567  return rc;
15568}
15569
15570TPM_RC Tpm::SerializeCommand_SequenceUpdate(
15571    const TPMI_DH_OBJECT& sequence_handle,
15572    const std::string& sequence_handle_name,
15573    const TPM2B_MAX_BUFFER& buffer,
15574    std::string* serialized_command,
15575    AuthorizationDelegate* authorization_delegate) {
15576  VLOG(3) << __func__;
15577  TPM_RC rc = TPM_RC_SUCCESS;
15578  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15579  UINT32 command_size = 10;  // Header size.
15580  std::string handle_section_bytes;
15581  std::string parameter_section_bytes;
15582  TPM_CC command_code = TPM_CC_SequenceUpdate;
15583  bool is_command_parameter_encryption_possible = true;
15584  bool is_response_parameter_encryption_possible = false;
15585  std::string command_code_bytes;
15586  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15587  if (rc != TPM_RC_SUCCESS) {
15588    return rc;
15589  }
15590  std::string sequence_handle_bytes;
15591  rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15592  if (rc != TPM_RC_SUCCESS) {
15593    return rc;
15594  }
15595  std::string buffer_bytes;
15596  rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15597  if (rc != TPM_RC_SUCCESS) {
15598    return rc;
15599  }
15600  if (authorization_delegate) {
15601    // Encrypt just the parameter data, not the size.
15602    std::string tmp = buffer_bytes.substr(2);
15603    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15604      return TRUNKS_RC_ENCRYPTION_FAILED;
15605    }
15606    buffer_bytes.replace(2, std::string::npos, tmp);
15607  }
15608  std::unique_ptr<crypto::SecureHash> hash(
15609      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15610  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15611  hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15612  handle_section_bytes += sequence_handle_bytes;
15613  command_size += sequence_handle_bytes.size();
15614  hash->Update(buffer_bytes.data(), buffer_bytes.size());
15615  parameter_section_bytes += buffer_bytes;
15616  command_size += buffer_bytes.size();
15617  std::string command_hash(32, 0);
15618  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
15619  std::string authorization_section_bytes;
15620  std::string authorization_size_bytes;
15621  if (authorization_delegate) {
15622    if (!authorization_delegate->GetCommandAuthorization(
15623            command_hash, is_command_parameter_encryption_possible,
15624            is_response_parameter_encryption_possible,
15625            &authorization_section_bytes)) {
15626      return TRUNKS_RC_AUTHORIZATION_FAILED;
15627    }
15628    if (!authorization_section_bytes.empty()) {
15629      tag = TPM_ST_SESSIONS;
15630      std::string tmp;
15631      rc = Serialize_UINT32(authorization_section_bytes.size(),
15632                            &authorization_size_bytes);
15633      if (rc != TPM_RC_SUCCESS) {
15634        return rc;
15635      }
15636      command_size +=
15637          authorization_size_bytes.size() + authorization_section_bytes.size();
15638    }
15639  }
15640  std::string tag_bytes;
15641  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15642  if (rc != TPM_RC_SUCCESS) {
15643    return rc;
15644  }
15645  std::string command_size_bytes;
15646  rc = Serialize_UINT32(command_size, &command_size_bytes);
15647  if (rc != TPM_RC_SUCCESS) {
15648    return rc;
15649  }
15650  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15651                        handle_section_bytes + authorization_size_bytes +
15652                        authorization_section_bytes + parameter_section_bytes;
15653  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15654  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
15655                                            serialized_command->size());
15656  return TPM_RC_SUCCESS;
15657}
15658
15659TPM_RC Tpm::ParseResponse_SequenceUpdate(
15660    const std::string& response,
15661    AuthorizationDelegate* authorization_delegate) {
15662  VLOG(3) << __func__;
15663  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15664  TPM_RC rc = TPM_RC_SUCCESS;
15665  std::string buffer(response);
15666  TPM_ST tag;
15667  std::string tag_bytes;
15668  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15669  if (rc != TPM_RC_SUCCESS) {
15670    return rc;
15671  }
15672  UINT32 response_size;
15673  std::string response_size_bytes;
15674  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15675  if (rc != TPM_RC_SUCCESS) {
15676    return rc;
15677  }
15678  TPM_RC response_code;
15679  std::string response_code_bytes;
15680  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15681  if (rc != TPM_RC_SUCCESS) {
15682    return rc;
15683  }
15684  if (response_size != response.size()) {
15685    return TPM_RC_SIZE;
15686  }
15687  if (response_code != TPM_RC_SUCCESS) {
15688    return response_code;
15689  }
15690  TPM_CC command_code = TPM_CC_SequenceUpdate;
15691  std::string command_code_bytes;
15692  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15693  if (rc != TPM_RC_SUCCESS) {
15694    return rc;
15695  }
15696  std::string authorization_section_bytes;
15697  if (tag == TPM_ST_SESSIONS) {
15698    UINT32 parameter_section_size = buffer.size();
15699    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15700    if (rc != TPM_RC_SUCCESS) {
15701      return rc;
15702    }
15703    if (parameter_section_size > buffer.size()) {
15704      return TPM_RC_INSUFFICIENT;
15705    }
15706    authorization_section_bytes = buffer.substr(parameter_section_size);
15707    // Keep the parameter section in |buffer|.
15708    buffer.erase(parameter_section_size);
15709  }
15710  std::unique_ptr<crypto::SecureHash> hash(
15711      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15712  hash->Update(response_code_bytes.data(), response_code_bytes.size());
15713  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15714  hash->Update(buffer.data(), buffer.size());
15715  std::string response_hash(32, 0);
15716  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
15717  if (tag == TPM_ST_SESSIONS) {
15718    CHECK(authorization_delegate) << "Authorization delegate missing!";
15719    if (!authorization_delegate->CheckResponseAuthorization(
15720            response_hash, authorization_section_bytes)) {
15721      return TRUNKS_RC_AUTHORIZATION_FAILED;
15722    }
15723  }
15724  return TPM_RC_SUCCESS;
15725}
15726
15727void SequenceUpdateErrorCallback(const Tpm::SequenceUpdateResponse& callback,
15728                                 TPM_RC response_code) {
15729  VLOG(1) << __func__;
15730  callback.Run(response_code);
15731}
15732
15733void SequenceUpdateResponseParser(const Tpm::SequenceUpdateResponse& callback,
15734                                  AuthorizationDelegate* authorization_delegate,
15735                                  const std::string& response) {
15736  VLOG(1) << __func__;
15737  base::Callback<void(TPM_RC)> error_reporter =
15738      base::Bind(SequenceUpdateErrorCallback, callback);
15739  TPM_RC rc =
15740      Tpm::ParseResponse_SequenceUpdate(response, authorization_delegate);
15741  if (rc != TPM_RC_SUCCESS) {
15742    error_reporter.Run(rc);
15743    return;
15744  }
15745  callback.Run(rc);
15746}
15747
15748void Tpm::SequenceUpdate(const TPMI_DH_OBJECT& sequence_handle,
15749                         const std::string& sequence_handle_name,
15750                         const TPM2B_MAX_BUFFER& buffer,
15751                         AuthorizationDelegate* authorization_delegate,
15752                         const SequenceUpdateResponse& callback) {
15753  VLOG(1) << __func__;
15754  base::Callback<void(TPM_RC)> error_reporter =
15755      base::Bind(SequenceUpdateErrorCallback, callback);
15756  base::Callback<void(const std::string&)> parser = base::Bind(
15757      SequenceUpdateResponseParser, callback, authorization_delegate);
15758  std::string command;
15759  TPM_RC rc =
15760      SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15761                                      buffer, &command, authorization_delegate);
15762  if (rc != TPM_RC_SUCCESS) {
15763    error_reporter.Run(rc);
15764    return;
15765  }
15766  transceiver_->SendCommand(command, parser);
15767}
15768
15769TPM_RC Tpm::SequenceUpdateSync(const TPMI_DH_OBJECT& sequence_handle,
15770                               const std::string& sequence_handle_name,
15771                               const TPM2B_MAX_BUFFER& buffer,
15772                               AuthorizationDelegate* authorization_delegate) {
15773  VLOG(1) << __func__;
15774  std::string command;
15775  TPM_RC rc =
15776      SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15777                                      buffer, &command, authorization_delegate);
15778  if (rc != TPM_RC_SUCCESS) {
15779    return rc;
15780  }
15781  std::string response = transceiver_->SendCommandAndWait(command);
15782  rc = ParseResponse_SequenceUpdate(response, authorization_delegate);
15783  return rc;
15784}
15785
15786TPM_RC Tpm::SerializeCommand_SequenceComplete(
15787    const TPMI_DH_OBJECT& sequence_handle,
15788    const std::string& sequence_handle_name,
15789    const TPM2B_MAX_BUFFER& buffer,
15790    const TPMI_RH_HIERARCHY& hierarchy,
15791    std::string* serialized_command,
15792    AuthorizationDelegate* authorization_delegate) {
15793  VLOG(3) << __func__;
15794  TPM_RC rc = TPM_RC_SUCCESS;
15795  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15796  UINT32 command_size = 10;  // Header size.
15797  std::string handle_section_bytes;
15798  std::string parameter_section_bytes;
15799  TPM_CC command_code = TPM_CC_SequenceComplete;
15800  bool is_command_parameter_encryption_possible = true;
15801  bool is_response_parameter_encryption_possible = true;
15802  std::string command_code_bytes;
15803  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15804  if (rc != TPM_RC_SUCCESS) {
15805    return rc;
15806  }
15807  std::string sequence_handle_bytes;
15808  rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15809  if (rc != TPM_RC_SUCCESS) {
15810    return rc;
15811  }
15812  std::string buffer_bytes;
15813  rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15814  if (rc != TPM_RC_SUCCESS) {
15815    return rc;
15816  }
15817  std::string hierarchy_bytes;
15818  rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
15819  if (rc != TPM_RC_SUCCESS) {
15820    return rc;
15821  }
15822  if (authorization_delegate) {
15823    // Encrypt just the parameter data, not the size.
15824    std::string tmp = buffer_bytes.substr(2);
15825    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15826      return TRUNKS_RC_ENCRYPTION_FAILED;
15827    }
15828    buffer_bytes.replace(2, std::string::npos, tmp);
15829  }
15830  std::unique_ptr<crypto::SecureHash> hash(
15831      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15832  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15833  hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15834  handle_section_bytes += sequence_handle_bytes;
15835  command_size += sequence_handle_bytes.size();
15836  hash->Update(buffer_bytes.data(), buffer_bytes.size());
15837  parameter_section_bytes += buffer_bytes;
15838  command_size += buffer_bytes.size();
15839  hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
15840  parameter_section_bytes += hierarchy_bytes;
15841  command_size += hierarchy_bytes.size();
15842  std::string command_hash(32, 0);
15843  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
15844  std::string authorization_section_bytes;
15845  std::string authorization_size_bytes;
15846  if (authorization_delegate) {
15847    if (!authorization_delegate->GetCommandAuthorization(
15848            command_hash, is_command_parameter_encryption_possible,
15849            is_response_parameter_encryption_possible,
15850            &authorization_section_bytes)) {
15851      return TRUNKS_RC_AUTHORIZATION_FAILED;
15852    }
15853    if (!authorization_section_bytes.empty()) {
15854      tag = TPM_ST_SESSIONS;
15855      std::string tmp;
15856      rc = Serialize_UINT32(authorization_section_bytes.size(),
15857                            &authorization_size_bytes);
15858      if (rc != TPM_RC_SUCCESS) {
15859        return rc;
15860      }
15861      command_size +=
15862          authorization_size_bytes.size() + authorization_section_bytes.size();
15863    }
15864  }
15865  std::string tag_bytes;
15866  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15867  if (rc != TPM_RC_SUCCESS) {
15868    return rc;
15869  }
15870  std::string command_size_bytes;
15871  rc = Serialize_UINT32(command_size, &command_size_bytes);
15872  if (rc != TPM_RC_SUCCESS) {
15873    return rc;
15874  }
15875  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15876                        handle_section_bytes + authorization_size_bytes +
15877                        authorization_section_bytes + parameter_section_bytes;
15878  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15879  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
15880                                            serialized_command->size());
15881  return TPM_RC_SUCCESS;
15882}
15883
15884TPM_RC Tpm::ParseResponse_SequenceComplete(
15885    const std::string& response,
15886    TPM2B_DIGEST* result,
15887    TPMT_TK_HASHCHECK* validation,
15888    AuthorizationDelegate* authorization_delegate) {
15889  VLOG(3) << __func__;
15890  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15891  TPM_RC rc = TPM_RC_SUCCESS;
15892  std::string buffer(response);
15893  TPM_ST tag;
15894  std::string tag_bytes;
15895  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15896  if (rc != TPM_RC_SUCCESS) {
15897    return rc;
15898  }
15899  UINT32 response_size;
15900  std::string response_size_bytes;
15901  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15902  if (rc != TPM_RC_SUCCESS) {
15903    return rc;
15904  }
15905  TPM_RC response_code;
15906  std::string response_code_bytes;
15907  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15908  if (rc != TPM_RC_SUCCESS) {
15909    return rc;
15910  }
15911  if (response_size != response.size()) {
15912    return TPM_RC_SIZE;
15913  }
15914  if (response_code != TPM_RC_SUCCESS) {
15915    return response_code;
15916  }
15917  TPM_CC command_code = TPM_CC_SequenceComplete;
15918  std::string command_code_bytes;
15919  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15920  if (rc != TPM_RC_SUCCESS) {
15921    return rc;
15922  }
15923  std::string authorization_section_bytes;
15924  if (tag == TPM_ST_SESSIONS) {
15925    UINT32 parameter_section_size = buffer.size();
15926    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15927    if (rc != TPM_RC_SUCCESS) {
15928      return rc;
15929    }
15930    if (parameter_section_size > buffer.size()) {
15931      return TPM_RC_INSUFFICIENT;
15932    }
15933    authorization_section_bytes = buffer.substr(parameter_section_size);
15934    // Keep the parameter section in |buffer|.
15935    buffer.erase(parameter_section_size);
15936  }
15937  std::unique_ptr<crypto::SecureHash> hash(
15938      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15939  hash->Update(response_code_bytes.data(), response_code_bytes.size());
15940  hash->Update(command_code_bytes.data(), command_code_bytes.size());
15941  hash->Update(buffer.data(), buffer.size());
15942  std::string response_hash(32, 0);
15943  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
15944  if (tag == TPM_ST_SESSIONS) {
15945    CHECK(authorization_delegate) << "Authorization delegate missing!";
15946    if (!authorization_delegate->CheckResponseAuthorization(
15947            response_hash, authorization_section_bytes)) {
15948      return TRUNKS_RC_AUTHORIZATION_FAILED;
15949    }
15950  }
15951  std::string result_bytes;
15952  rc = Parse_TPM2B_DIGEST(&buffer, result, &result_bytes);
15953  if (rc != TPM_RC_SUCCESS) {
15954    return rc;
15955  }
15956  std::string validation_bytes;
15957  rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
15958  if (rc != TPM_RC_SUCCESS) {
15959    return rc;
15960  }
15961  if (tag == TPM_ST_SESSIONS) {
15962    CHECK(authorization_delegate) << "Authorization delegate missing!";
15963    // Decrypt just the parameter data, not the size.
15964    std::string tmp = result_bytes.substr(2);
15965    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
15966      return TRUNKS_RC_ENCRYPTION_FAILED;
15967    }
15968    result_bytes.replace(2, std::string::npos, tmp);
15969    rc = Parse_TPM2B_DIGEST(&result_bytes, result, nullptr);
15970    if (rc != TPM_RC_SUCCESS) {
15971      return rc;
15972    }
15973  }
15974  return TPM_RC_SUCCESS;
15975}
15976
15977void SequenceCompleteErrorCallback(
15978    const Tpm::SequenceCompleteResponse& callback,
15979    TPM_RC response_code) {
15980  VLOG(1) << __func__;
15981  callback.Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
15982}
15983
15984void SequenceCompleteResponseParser(
15985    const Tpm::SequenceCompleteResponse& callback,
15986    AuthorizationDelegate* authorization_delegate,
15987    const std::string& response) {
15988  VLOG(1) << __func__;
15989  base::Callback<void(TPM_RC)> error_reporter =
15990      base::Bind(SequenceCompleteErrorCallback, callback);
15991  TPM2B_DIGEST result;
15992  TPMT_TK_HASHCHECK validation;
15993  TPM_RC rc = Tpm::ParseResponse_SequenceComplete(
15994      response, &result, &validation, authorization_delegate);
15995  if (rc != TPM_RC_SUCCESS) {
15996    error_reporter.Run(rc);
15997    return;
15998  }
15999  callback.Run(rc, result, validation);
16000}
16001
16002void Tpm::SequenceComplete(const TPMI_DH_OBJECT& sequence_handle,
16003                           const std::string& sequence_handle_name,
16004                           const TPM2B_MAX_BUFFER& buffer,
16005                           const TPMI_RH_HIERARCHY& hierarchy,
16006                           AuthorizationDelegate* authorization_delegate,
16007                           const SequenceCompleteResponse& callback) {
16008  VLOG(1) << __func__;
16009  base::Callback<void(TPM_RC)> error_reporter =
16010      base::Bind(SequenceCompleteErrorCallback, callback);
16011  base::Callback<void(const std::string&)> parser = base::Bind(
16012      SequenceCompleteResponseParser, callback, authorization_delegate);
16013  std::string command;
16014  TPM_RC rc = SerializeCommand_SequenceComplete(
16015      sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16016      authorization_delegate);
16017  if (rc != TPM_RC_SUCCESS) {
16018    error_reporter.Run(rc);
16019    return;
16020  }
16021  transceiver_->SendCommand(command, parser);
16022}
16023
16024TPM_RC Tpm::SequenceCompleteSync(
16025    const TPMI_DH_OBJECT& sequence_handle,
16026    const std::string& sequence_handle_name,
16027    const TPM2B_MAX_BUFFER& buffer,
16028    const TPMI_RH_HIERARCHY& hierarchy,
16029    TPM2B_DIGEST* result,
16030    TPMT_TK_HASHCHECK* validation,
16031    AuthorizationDelegate* authorization_delegate) {
16032  VLOG(1) << __func__;
16033  std::string command;
16034  TPM_RC rc = SerializeCommand_SequenceComplete(
16035      sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16036      authorization_delegate);
16037  if (rc != TPM_RC_SUCCESS) {
16038    return rc;
16039  }
16040  std::string response = transceiver_->SendCommandAndWait(command);
16041  rc = ParseResponse_SequenceComplete(response, result, validation,
16042                                      authorization_delegate);
16043  return rc;
16044}
16045
16046TPM_RC Tpm::SerializeCommand_EventSequenceComplete(
16047    const TPMI_DH_PCR& pcr_handle,
16048    const std::string& pcr_handle_name,
16049    const TPMI_DH_OBJECT& sequence_handle,
16050    const std::string& sequence_handle_name,
16051    const TPM2B_MAX_BUFFER& buffer,
16052    std::string* serialized_command,
16053    AuthorizationDelegate* authorization_delegate) {
16054  VLOG(3) << __func__;
16055  TPM_RC rc = TPM_RC_SUCCESS;
16056  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16057  UINT32 command_size = 10;  // Header size.
16058  std::string handle_section_bytes;
16059  std::string parameter_section_bytes;
16060  TPM_CC command_code = TPM_CC_EventSequenceComplete;
16061  bool is_command_parameter_encryption_possible = true;
16062  bool is_response_parameter_encryption_possible = false;
16063  std::string command_code_bytes;
16064  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16065  if (rc != TPM_RC_SUCCESS) {
16066    return rc;
16067  }
16068  std::string pcr_handle_bytes;
16069  rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
16070  if (rc != TPM_RC_SUCCESS) {
16071    return rc;
16072  }
16073  std::string sequence_handle_bytes;
16074  rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16075  if (rc != TPM_RC_SUCCESS) {
16076    return rc;
16077  }
16078  std::string buffer_bytes;
16079  rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16080  if (rc != TPM_RC_SUCCESS) {
16081    return rc;
16082  }
16083  if (authorization_delegate) {
16084    // Encrypt just the parameter data, not the size.
16085    std::string tmp = buffer_bytes.substr(2);
16086    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16087      return TRUNKS_RC_ENCRYPTION_FAILED;
16088    }
16089    buffer_bytes.replace(2, std::string::npos, tmp);
16090  }
16091  std::unique_ptr<crypto::SecureHash> hash(
16092      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16093  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16094  hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
16095  handle_section_bytes += pcr_handle_bytes;
16096  command_size += pcr_handle_bytes.size();
16097  hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16098  handle_section_bytes += sequence_handle_bytes;
16099  command_size += sequence_handle_bytes.size();
16100  hash->Update(buffer_bytes.data(), buffer_bytes.size());
16101  parameter_section_bytes += buffer_bytes;
16102  command_size += buffer_bytes.size();
16103  std::string command_hash(32, 0);
16104  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
16105  std::string authorization_section_bytes;
16106  std::string authorization_size_bytes;
16107  if (authorization_delegate) {
16108    if (!authorization_delegate->GetCommandAuthorization(
16109            command_hash, is_command_parameter_encryption_possible,
16110            is_response_parameter_encryption_possible,
16111            &authorization_section_bytes)) {
16112      return TRUNKS_RC_AUTHORIZATION_FAILED;
16113    }
16114    if (!authorization_section_bytes.empty()) {
16115      tag = TPM_ST_SESSIONS;
16116      std::string tmp;
16117      rc = Serialize_UINT32(authorization_section_bytes.size(),
16118                            &authorization_size_bytes);
16119      if (rc != TPM_RC_SUCCESS) {
16120        return rc;
16121      }
16122      command_size +=
16123          authorization_size_bytes.size() + authorization_section_bytes.size();
16124    }
16125  }
16126  std::string tag_bytes;
16127  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16128  if (rc != TPM_RC_SUCCESS) {
16129    return rc;
16130  }
16131  std::string command_size_bytes;
16132  rc = Serialize_UINT32(command_size, &command_size_bytes);
16133  if (rc != TPM_RC_SUCCESS) {
16134    return rc;
16135  }
16136  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16137                        handle_section_bytes + authorization_size_bytes +
16138                        authorization_section_bytes + parameter_section_bytes;
16139  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16140  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
16141                                            serialized_command->size());
16142  return TPM_RC_SUCCESS;
16143}
16144
16145TPM_RC Tpm::ParseResponse_EventSequenceComplete(
16146    const std::string& response,
16147    TPML_DIGEST_VALUES* results,
16148    AuthorizationDelegate* authorization_delegate) {
16149  VLOG(3) << __func__;
16150  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16151  TPM_RC rc = TPM_RC_SUCCESS;
16152  std::string buffer(response);
16153  TPM_ST tag;
16154  std::string tag_bytes;
16155  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16156  if (rc != TPM_RC_SUCCESS) {
16157    return rc;
16158  }
16159  UINT32 response_size;
16160  std::string response_size_bytes;
16161  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16162  if (rc != TPM_RC_SUCCESS) {
16163    return rc;
16164  }
16165  TPM_RC response_code;
16166  std::string response_code_bytes;
16167  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16168  if (rc != TPM_RC_SUCCESS) {
16169    return rc;
16170  }
16171  if (response_size != response.size()) {
16172    return TPM_RC_SIZE;
16173  }
16174  if (response_code != TPM_RC_SUCCESS) {
16175    return response_code;
16176  }
16177  TPM_CC command_code = TPM_CC_EventSequenceComplete;
16178  std::string command_code_bytes;
16179  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16180  if (rc != TPM_RC_SUCCESS) {
16181    return rc;
16182  }
16183  std::string authorization_section_bytes;
16184  if (tag == TPM_ST_SESSIONS) {
16185    UINT32 parameter_section_size = buffer.size();
16186    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16187    if (rc != TPM_RC_SUCCESS) {
16188      return rc;
16189    }
16190    if (parameter_section_size > buffer.size()) {
16191      return TPM_RC_INSUFFICIENT;
16192    }
16193    authorization_section_bytes = buffer.substr(parameter_section_size);
16194    // Keep the parameter section in |buffer|.
16195    buffer.erase(parameter_section_size);
16196  }
16197  std::unique_ptr<crypto::SecureHash> hash(
16198      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16199  hash->Update(response_code_bytes.data(), response_code_bytes.size());
16200  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16201  hash->Update(buffer.data(), buffer.size());
16202  std::string response_hash(32, 0);
16203  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
16204  if (tag == TPM_ST_SESSIONS) {
16205    CHECK(authorization_delegate) << "Authorization delegate missing!";
16206    if (!authorization_delegate->CheckResponseAuthorization(
16207            response_hash, authorization_section_bytes)) {
16208      return TRUNKS_RC_AUTHORIZATION_FAILED;
16209    }
16210  }
16211  std::string results_bytes;
16212  rc = Parse_TPML_DIGEST_VALUES(&buffer, results, &results_bytes);
16213  if (rc != TPM_RC_SUCCESS) {
16214    return rc;
16215  }
16216  return TPM_RC_SUCCESS;
16217}
16218
16219void EventSequenceCompleteErrorCallback(
16220    const Tpm::EventSequenceCompleteResponse& callback,
16221    TPM_RC response_code) {
16222  VLOG(1) << __func__;
16223  callback.Run(response_code, TPML_DIGEST_VALUES());
16224}
16225
16226void EventSequenceCompleteResponseParser(
16227    const Tpm::EventSequenceCompleteResponse& callback,
16228    AuthorizationDelegate* authorization_delegate,
16229    const std::string& response) {
16230  VLOG(1) << __func__;
16231  base::Callback<void(TPM_RC)> error_reporter =
16232      base::Bind(EventSequenceCompleteErrorCallback, callback);
16233  TPML_DIGEST_VALUES results;
16234  TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete(response, &results,
16235                                                       authorization_delegate);
16236  if (rc != TPM_RC_SUCCESS) {
16237    error_reporter.Run(rc);
16238    return;
16239  }
16240  callback.Run(rc, results);
16241}
16242
16243void Tpm::EventSequenceComplete(const TPMI_DH_PCR& pcr_handle,
16244                                const std::string& pcr_handle_name,
16245                                const TPMI_DH_OBJECT& sequence_handle,
16246                                const std::string& sequence_handle_name,
16247                                const TPM2B_MAX_BUFFER& buffer,
16248                                AuthorizationDelegate* authorization_delegate,
16249                                const EventSequenceCompleteResponse& callback) {
16250  VLOG(1) << __func__;
16251  base::Callback<void(TPM_RC)> error_reporter =
16252      base::Bind(EventSequenceCompleteErrorCallback, callback);
16253  base::Callback<void(const std::string&)> parser = base::Bind(
16254      EventSequenceCompleteResponseParser, callback, authorization_delegate);
16255  std::string command;
16256  TPM_RC rc = SerializeCommand_EventSequenceComplete(
16257      pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16258      buffer, &command, authorization_delegate);
16259  if (rc != TPM_RC_SUCCESS) {
16260    error_reporter.Run(rc);
16261    return;
16262  }
16263  transceiver_->SendCommand(command, parser);
16264}
16265
16266TPM_RC Tpm::EventSequenceCompleteSync(
16267    const TPMI_DH_PCR& pcr_handle,
16268    const std::string& pcr_handle_name,
16269    const TPMI_DH_OBJECT& sequence_handle,
16270    const std::string& sequence_handle_name,
16271    const TPM2B_MAX_BUFFER& buffer,
16272    TPML_DIGEST_VALUES* results,
16273    AuthorizationDelegate* authorization_delegate) {
16274  VLOG(1) << __func__;
16275  std::string command;
16276  TPM_RC rc = SerializeCommand_EventSequenceComplete(
16277      pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16278      buffer, &command, authorization_delegate);
16279  if (rc != TPM_RC_SUCCESS) {
16280    return rc;
16281  }
16282  std::string response = transceiver_->SendCommandAndWait(command);
16283  rc = ParseResponse_EventSequenceComplete(response, results,
16284                                           authorization_delegate);
16285  return rc;
16286}
16287
16288TPM_RC Tpm::SerializeCommand_Certify(
16289    const TPMI_DH_OBJECT& object_handle,
16290    const std::string& object_handle_name,
16291    const TPMI_DH_OBJECT& sign_handle,
16292    const std::string& sign_handle_name,
16293    const TPM2B_DATA& qualifying_data,
16294    const TPMT_SIG_SCHEME& in_scheme,
16295    std::string* serialized_command,
16296    AuthorizationDelegate* authorization_delegate) {
16297  VLOG(3) << __func__;
16298  TPM_RC rc = TPM_RC_SUCCESS;
16299  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16300  UINT32 command_size = 10;  // Header size.
16301  std::string handle_section_bytes;
16302  std::string parameter_section_bytes;
16303  TPM_CC command_code = TPM_CC_Certify;
16304  bool is_command_parameter_encryption_possible = true;
16305  bool is_response_parameter_encryption_possible = true;
16306  std::string command_code_bytes;
16307  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16308  if (rc != TPM_RC_SUCCESS) {
16309    return rc;
16310  }
16311  std::string object_handle_bytes;
16312  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16313  if (rc != TPM_RC_SUCCESS) {
16314    return rc;
16315  }
16316  std::string sign_handle_bytes;
16317  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16318  if (rc != TPM_RC_SUCCESS) {
16319    return rc;
16320  }
16321  std::string qualifying_data_bytes;
16322  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16323  if (rc != TPM_RC_SUCCESS) {
16324    return rc;
16325  }
16326  std::string in_scheme_bytes;
16327  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16328  if (rc != TPM_RC_SUCCESS) {
16329    return rc;
16330  }
16331  if (authorization_delegate) {
16332    // Encrypt just the parameter data, not the size.
16333    std::string tmp = qualifying_data_bytes.substr(2);
16334    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16335      return TRUNKS_RC_ENCRYPTION_FAILED;
16336    }
16337    qualifying_data_bytes.replace(2, std::string::npos, tmp);
16338  }
16339  std::unique_ptr<crypto::SecureHash> hash(
16340      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16341  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16342  hash->Update(object_handle_name.data(), object_handle_name.size());
16343  handle_section_bytes += object_handle_bytes;
16344  command_size += object_handle_bytes.size();
16345  hash->Update(sign_handle_name.data(), sign_handle_name.size());
16346  handle_section_bytes += sign_handle_bytes;
16347  command_size += sign_handle_bytes.size();
16348  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16349  parameter_section_bytes += qualifying_data_bytes;
16350  command_size += qualifying_data_bytes.size();
16351  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16352  parameter_section_bytes += in_scheme_bytes;
16353  command_size += in_scheme_bytes.size();
16354  std::string command_hash(32, 0);
16355  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
16356  std::string authorization_section_bytes;
16357  std::string authorization_size_bytes;
16358  if (authorization_delegate) {
16359    if (!authorization_delegate->GetCommandAuthorization(
16360            command_hash, is_command_parameter_encryption_possible,
16361            is_response_parameter_encryption_possible,
16362            &authorization_section_bytes)) {
16363      return TRUNKS_RC_AUTHORIZATION_FAILED;
16364    }
16365    if (!authorization_section_bytes.empty()) {
16366      tag = TPM_ST_SESSIONS;
16367      std::string tmp;
16368      rc = Serialize_UINT32(authorization_section_bytes.size(),
16369                            &authorization_size_bytes);
16370      if (rc != TPM_RC_SUCCESS) {
16371        return rc;
16372      }
16373      command_size +=
16374          authorization_size_bytes.size() + authorization_section_bytes.size();
16375    }
16376  }
16377  std::string tag_bytes;
16378  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16379  if (rc != TPM_RC_SUCCESS) {
16380    return rc;
16381  }
16382  std::string command_size_bytes;
16383  rc = Serialize_UINT32(command_size, &command_size_bytes);
16384  if (rc != TPM_RC_SUCCESS) {
16385    return rc;
16386  }
16387  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16388                        handle_section_bytes + authorization_size_bytes +
16389                        authorization_section_bytes + parameter_section_bytes;
16390  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16391  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
16392                                            serialized_command->size());
16393  return TPM_RC_SUCCESS;
16394}
16395
16396TPM_RC Tpm::ParseResponse_Certify(
16397    const std::string& response,
16398    TPM2B_ATTEST* certify_info,
16399    TPMT_SIGNATURE* signature,
16400    AuthorizationDelegate* authorization_delegate) {
16401  VLOG(3) << __func__;
16402  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16403  TPM_RC rc = TPM_RC_SUCCESS;
16404  std::string buffer(response);
16405  TPM_ST tag;
16406  std::string tag_bytes;
16407  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16408  if (rc != TPM_RC_SUCCESS) {
16409    return rc;
16410  }
16411  UINT32 response_size;
16412  std::string response_size_bytes;
16413  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16414  if (rc != TPM_RC_SUCCESS) {
16415    return rc;
16416  }
16417  TPM_RC response_code;
16418  std::string response_code_bytes;
16419  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16420  if (rc != TPM_RC_SUCCESS) {
16421    return rc;
16422  }
16423  if (response_size != response.size()) {
16424    return TPM_RC_SIZE;
16425  }
16426  if (response_code != TPM_RC_SUCCESS) {
16427    return response_code;
16428  }
16429  TPM_CC command_code = TPM_CC_Certify;
16430  std::string command_code_bytes;
16431  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16432  if (rc != TPM_RC_SUCCESS) {
16433    return rc;
16434  }
16435  std::string authorization_section_bytes;
16436  if (tag == TPM_ST_SESSIONS) {
16437    UINT32 parameter_section_size = buffer.size();
16438    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16439    if (rc != TPM_RC_SUCCESS) {
16440      return rc;
16441    }
16442    if (parameter_section_size > buffer.size()) {
16443      return TPM_RC_INSUFFICIENT;
16444    }
16445    authorization_section_bytes = buffer.substr(parameter_section_size);
16446    // Keep the parameter section in |buffer|.
16447    buffer.erase(parameter_section_size);
16448  }
16449  std::unique_ptr<crypto::SecureHash> hash(
16450      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16451  hash->Update(response_code_bytes.data(), response_code_bytes.size());
16452  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16453  hash->Update(buffer.data(), buffer.size());
16454  std::string response_hash(32, 0);
16455  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
16456  if (tag == TPM_ST_SESSIONS) {
16457    CHECK(authorization_delegate) << "Authorization delegate missing!";
16458    if (!authorization_delegate->CheckResponseAuthorization(
16459            response_hash, authorization_section_bytes)) {
16460      return TRUNKS_RC_AUTHORIZATION_FAILED;
16461    }
16462  }
16463  std::string certify_info_bytes;
16464  rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16465  if (rc != TPM_RC_SUCCESS) {
16466    return rc;
16467  }
16468  std::string signature_bytes;
16469  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16470  if (rc != TPM_RC_SUCCESS) {
16471    return rc;
16472  }
16473  if (tag == TPM_ST_SESSIONS) {
16474    CHECK(authorization_delegate) << "Authorization delegate missing!";
16475    // Decrypt just the parameter data, not the size.
16476    std::string tmp = certify_info_bytes.substr(2);
16477    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
16478      return TRUNKS_RC_ENCRYPTION_FAILED;
16479    }
16480    certify_info_bytes.replace(2, std::string::npos, tmp);
16481    rc = Parse_TPM2B_ATTEST(&certify_info_bytes, certify_info, nullptr);
16482    if (rc != TPM_RC_SUCCESS) {
16483      return rc;
16484    }
16485  }
16486  return TPM_RC_SUCCESS;
16487}
16488
16489void CertifyErrorCallback(const Tpm::CertifyResponse& callback,
16490                          TPM_RC response_code) {
16491  VLOG(1) << __func__;
16492  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16493}
16494
16495void CertifyResponseParser(const Tpm::CertifyResponse& callback,
16496                           AuthorizationDelegate* authorization_delegate,
16497                           const std::string& response) {
16498  VLOG(1) << __func__;
16499  base::Callback<void(TPM_RC)> error_reporter =
16500      base::Bind(CertifyErrorCallback, callback);
16501  TPM2B_ATTEST certify_info;
16502  TPMT_SIGNATURE signature;
16503  TPM_RC rc = Tpm::ParseResponse_Certify(response, &certify_info, &signature,
16504                                         authorization_delegate);
16505  if (rc != TPM_RC_SUCCESS) {
16506    error_reporter.Run(rc);
16507    return;
16508  }
16509  callback.Run(rc, certify_info, signature);
16510}
16511
16512void Tpm::Certify(const TPMI_DH_OBJECT& object_handle,
16513                  const std::string& object_handle_name,
16514                  const TPMI_DH_OBJECT& sign_handle,
16515                  const std::string& sign_handle_name,
16516                  const TPM2B_DATA& qualifying_data,
16517                  const TPMT_SIG_SCHEME& in_scheme,
16518                  AuthorizationDelegate* authorization_delegate,
16519                  const CertifyResponse& callback) {
16520  VLOG(1) << __func__;
16521  base::Callback<void(TPM_RC)> error_reporter =
16522      base::Bind(CertifyErrorCallback, callback);
16523  base::Callback<void(const std::string&)> parser =
16524      base::Bind(CertifyResponseParser, callback, authorization_delegate);
16525  std::string command;
16526  TPM_RC rc = SerializeCommand_Certify(
16527      object_handle, object_handle_name, sign_handle, sign_handle_name,
16528      qualifying_data, in_scheme, &command, authorization_delegate);
16529  if (rc != TPM_RC_SUCCESS) {
16530    error_reporter.Run(rc);
16531    return;
16532  }
16533  transceiver_->SendCommand(command, parser);
16534}
16535
16536TPM_RC Tpm::CertifySync(const TPMI_DH_OBJECT& object_handle,
16537                        const std::string& object_handle_name,
16538                        const TPMI_DH_OBJECT& sign_handle,
16539                        const std::string& sign_handle_name,
16540                        const TPM2B_DATA& qualifying_data,
16541                        const TPMT_SIG_SCHEME& in_scheme,
16542                        TPM2B_ATTEST* certify_info,
16543                        TPMT_SIGNATURE* signature,
16544                        AuthorizationDelegate* authorization_delegate) {
16545  VLOG(1) << __func__;
16546  std::string command;
16547  TPM_RC rc = SerializeCommand_Certify(
16548      object_handle, object_handle_name, sign_handle, sign_handle_name,
16549      qualifying_data, in_scheme, &command, authorization_delegate);
16550  if (rc != TPM_RC_SUCCESS) {
16551    return rc;
16552  }
16553  std::string response = transceiver_->SendCommandAndWait(command);
16554  rc = ParseResponse_Certify(response, certify_info, signature,
16555                             authorization_delegate);
16556  return rc;
16557}
16558
16559TPM_RC Tpm::SerializeCommand_CertifyCreation(
16560    const TPMI_DH_OBJECT& sign_handle,
16561    const std::string& sign_handle_name,
16562    const TPMI_DH_OBJECT& object_handle,
16563    const std::string& object_handle_name,
16564    const TPM2B_DATA& qualifying_data,
16565    const TPM2B_DIGEST& creation_hash,
16566    const TPMT_SIG_SCHEME& in_scheme,
16567    const TPMT_TK_CREATION& creation_ticket,
16568    std::string* serialized_command,
16569    AuthorizationDelegate* authorization_delegate) {
16570  VLOG(3) << __func__;
16571  TPM_RC rc = TPM_RC_SUCCESS;
16572  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16573  UINT32 command_size = 10;  // Header size.
16574  std::string handle_section_bytes;
16575  std::string parameter_section_bytes;
16576  TPM_CC command_code = TPM_CC_CertifyCreation;
16577  bool is_command_parameter_encryption_possible = true;
16578  bool is_response_parameter_encryption_possible = true;
16579  std::string command_code_bytes;
16580  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16581  if (rc != TPM_RC_SUCCESS) {
16582    return rc;
16583  }
16584  std::string sign_handle_bytes;
16585  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16586  if (rc != TPM_RC_SUCCESS) {
16587    return rc;
16588  }
16589  std::string object_handle_bytes;
16590  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16591  if (rc != TPM_RC_SUCCESS) {
16592    return rc;
16593  }
16594  std::string qualifying_data_bytes;
16595  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16596  if (rc != TPM_RC_SUCCESS) {
16597    return rc;
16598  }
16599  std::string creation_hash_bytes;
16600  rc = Serialize_TPM2B_DIGEST(creation_hash, &creation_hash_bytes);
16601  if (rc != TPM_RC_SUCCESS) {
16602    return rc;
16603  }
16604  std::string in_scheme_bytes;
16605  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16606  if (rc != TPM_RC_SUCCESS) {
16607    return rc;
16608  }
16609  std::string creation_ticket_bytes;
16610  rc = Serialize_TPMT_TK_CREATION(creation_ticket, &creation_ticket_bytes);
16611  if (rc != TPM_RC_SUCCESS) {
16612    return rc;
16613  }
16614  if (authorization_delegate) {
16615    // Encrypt just the parameter data, not the size.
16616    std::string tmp = qualifying_data_bytes.substr(2);
16617    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16618      return TRUNKS_RC_ENCRYPTION_FAILED;
16619    }
16620    qualifying_data_bytes.replace(2, std::string::npos, tmp);
16621  }
16622  std::unique_ptr<crypto::SecureHash> hash(
16623      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16624  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16625  hash->Update(sign_handle_name.data(), sign_handle_name.size());
16626  handle_section_bytes += sign_handle_bytes;
16627  command_size += sign_handle_bytes.size();
16628  hash->Update(object_handle_name.data(), object_handle_name.size());
16629  handle_section_bytes += object_handle_bytes;
16630  command_size += object_handle_bytes.size();
16631  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16632  parameter_section_bytes += qualifying_data_bytes;
16633  command_size += qualifying_data_bytes.size();
16634  hash->Update(creation_hash_bytes.data(), creation_hash_bytes.size());
16635  parameter_section_bytes += creation_hash_bytes;
16636  command_size += creation_hash_bytes.size();
16637  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16638  parameter_section_bytes += in_scheme_bytes;
16639  command_size += in_scheme_bytes.size();
16640  hash->Update(creation_ticket_bytes.data(), creation_ticket_bytes.size());
16641  parameter_section_bytes += creation_ticket_bytes;
16642  command_size += creation_ticket_bytes.size();
16643  std::string command_hash(32, 0);
16644  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
16645  std::string authorization_section_bytes;
16646  std::string authorization_size_bytes;
16647  if (authorization_delegate) {
16648    if (!authorization_delegate->GetCommandAuthorization(
16649            command_hash, is_command_parameter_encryption_possible,
16650            is_response_parameter_encryption_possible,
16651            &authorization_section_bytes)) {
16652      return TRUNKS_RC_AUTHORIZATION_FAILED;
16653    }
16654    if (!authorization_section_bytes.empty()) {
16655      tag = TPM_ST_SESSIONS;
16656      std::string tmp;
16657      rc = Serialize_UINT32(authorization_section_bytes.size(),
16658                            &authorization_size_bytes);
16659      if (rc != TPM_RC_SUCCESS) {
16660        return rc;
16661      }
16662      command_size +=
16663          authorization_size_bytes.size() + authorization_section_bytes.size();
16664    }
16665  }
16666  std::string tag_bytes;
16667  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16668  if (rc != TPM_RC_SUCCESS) {
16669    return rc;
16670  }
16671  std::string command_size_bytes;
16672  rc = Serialize_UINT32(command_size, &command_size_bytes);
16673  if (rc != TPM_RC_SUCCESS) {
16674    return rc;
16675  }
16676  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16677                        handle_section_bytes + authorization_size_bytes +
16678                        authorization_section_bytes + parameter_section_bytes;
16679  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16680  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
16681                                            serialized_command->size());
16682  return TPM_RC_SUCCESS;
16683}
16684
16685TPM_RC Tpm::ParseResponse_CertifyCreation(
16686    const std::string& response,
16687    TPM2B_ATTEST* certify_info,
16688    TPMT_SIGNATURE* signature,
16689    AuthorizationDelegate* authorization_delegate) {
16690  VLOG(3) << __func__;
16691  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16692  TPM_RC rc = TPM_RC_SUCCESS;
16693  std::string buffer(response);
16694  TPM_ST tag;
16695  std::string tag_bytes;
16696  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16697  if (rc != TPM_RC_SUCCESS) {
16698    return rc;
16699  }
16700  UINT32 response_size;
16701  std::string response_size_bytes;
16702  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16703  if (rc != TPM_RC_SUCCESS) {
16704    return rc;
16705  }
16706  TPM_RC response_code;
16707  std::string response_code_bytes;
16708  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16709  if (rc != TPM_RC_SUCCESS) {
16710    return rc;
16711  }
16712  if (response_size != response.size()) {
16713    return TPM_RC_SIZE;
16714  }
16715  if (response_code != TPM_RC_SUCCESS) {
16716    return response_code;
16717  }
16718  TPM_CC command_code = TPM_CC_CertifyCreation;
16719  std::string command_code_bytes;
16720  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16721  if (rc != TPM_RC_SUCCESS) {
16722    return rc;
16723  }
16724  std::string authorization_section_bytes;
16725  if (tag == TPM_ST_SESSIONS) {
16726    UINT32 parameter_section_size = buffer.size();
16727    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16728    if (rc != TPM_RC_SUCCESS) {
16729      return rc;
16730    }
16731    if (parameter_section_size > buffer.size()) {
16732      return TPM_RC_INSUFFICIENT;
16733    }
16734    authorization_section_bytes = buffer.substr(parameter_section_size);
16735    // Keep the parameter section in |buffer|.
16736    buffer.erase(parameter_section_size);
16737  }
16738  std::unique_ptr<crypto::SecureHash> hash(
16739      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16740  hash->Update(response_code_bytes.data(), response_code_bytes.size());
16741  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16742  hash->Update(buffer.data(), buffer.size());
16743  std::string response_hash(32, 0);
16744  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
16745  if (tag == TPM_ST_SESSIONS) {
16746    CHECK(authorization_delegate) << "Authorization delegate missing!";
16747    if (!authorization_delegate->CheckResponseAuthorization(
16748            response_hash, authorization_section_bytes)) {
16749      return TRUNKS_RC_AUTHORIZATION_FAILED;
16750    }
16751  }
16752  std::string certify_info_bytes;
16753  rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16754  if (rc != TPM_RC_SUCCESS) {
16755    return rc;
16756  }
16757  std::string signature_bytes;
16758  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16759  if (rc != TPM_RC_SUCCESS) {
16760    return rc;
16761  }
16762  if (tag == TPM_ST_SESSIONS) {
16763    CHECK(authorization_delegate) << "Authorization delegate missing!";
16764    // Decrypt just the parameter data, not the size.
16765    std::string tmp = certify_info_bytes.substr(2);
16766    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
16767      return TRUNKS_RC_ENCRYPTION_FAILED;
16768    }
16769    certify_info_bytes.replace(2, std::string::npos, tmp);
16770    rc = Parse_TPM2B_ATTEST(&certify_info_bytes, certify_info, nullptr);
16771    if (rc != TPM_RC_SUCCESS) {
16772      return rc;
16773    }
16774  }
16775  return TPM_RC_SUCCESS;
16776}
16777
16778void CertifyCreationErrorCallback(const Tpm::CertifyCreationResponse& callback,
16779                                  TPM_RC response_code) {
16780  VLOG(1) << __func__;
16781  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16782}
16783
16784void CertifyCreationResponseParser(
16785    const Tpm::CertifyCreationResponse& callback,
16786    AuthorizationDelegate* authorization_delegate,
16787    const std::string& response) {
16788  VLOG(1) << __func__;
16789  base::Callback<void(TPM_RC)> error_reporter =
16790      base::Bind(CertifyCreationErrorCallback, callback);
16791  TPM2B_ATTEST certify_info;
16792  TPMT_SIGNATURE signature;
16793  TPM_RC rc = Tpm::ParseResponse_CertifyCreation(
16794      response, &certify_info, &signature, authorization_delegate);
16795  if (rc != TPM_RC_SUCCESS) {
16796    error_reporter.Run(rc);
16797    return;
16798  }
16799  callback.Run(rc, certify_info, signature);
16800}
16801
16802void Tpm::CertifyCreation(const TPMI_DH_OBJECT& sign_handle,
16803                          const std::string& sign_handle_name,
16804                          const TPMI_DH_OBJECT& object_handle,
16805                          const std::string& object_handle_name,
16806                          const TPM2B_DATA& qualifying_data,
16807                          const TPM2B_DIGEST& creation_hash,
16808                          const TPMT_SIG_SCHEME& in_scheme,
16809                          const TPMT_TK_CREATION& creation_ticket,
16810                          AuthorizationDelegate* authorization_delegate,
16811                          const CertifyCreationResponse& callback) {
16812  VLOG(1) << __func__;
16813  base::Callback<void(TPM_RC)> error_reporter =
16814      base::Bind(CertifyCreationErrorCallback, callback);
16815  base::Callback<void(const std::string&)> parser = base::Bind(
16816      CertifyCreationResponseParser, callback, authorization_delegate);
16817  std::string command;
16818  TPM_RC rc = SerializeCommand_CertifyCreation(
16819      sign_handle, sign_handle_name, object_handle, object_handle_name,
16820      qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
16821      authorization_delegate);
16822  if (rc != TPM_RC_SUCCESS) {
16823    error_reporter.Run(rc);
16824    return;
16825  }
16826  transceiver_->SendCommand(command, parser);
16827}
16828
16829TPM_RC Tpm::CertifyCreationSync(const TPMI_DH_OBJECT& sign_handle,
16830                                const std::string& sign_handle_name,
16831                                const TPMI_DH_OBJECT& object_handle,
16832                                const std::string& object_handle_name,
16833                                const TPM2B_DATA& qualifying_data,
16834                                const TPM2B_DIGEST& creation_hash,
16835                                const TPMT_SIG_SCHEME& in_scheme,
16836                                const TPMT_TK_CREATION& creation_ticket,
16837                                TPM2B_ATTEST* certify_info,
16838                                TPMT_SIGNATURE* signature,
16839                                AuthorizationDelegate* authorization_delegate) {
16840  VLOG(1) << __func__;
16841  std::string command;
16842  TPM_RC rc = SerializeCommand_CertifyCreation(
16843      sign_handle, sign_handle_name, object_handle, object_handle_name,
16844      qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
16845      authorization_delegate);
16846  if (rc != TPM_RC_SUCCESS) {
16847    return rc;
16848  }
16849  std::string response = transceiver_->SendCommandAndWait(command);
16850  rc = ParseResponse_CertifyCreation(response, certify_info, signature,
16851                                     authorization_delegate);
16852  return rc;
16853}
16854
16855TPM_RC Tpm::SerializeCommand_Quote(
16856    const TPMI_DH_OBJECT& sign_handle,
16857    const std::string& sign_handle_name,
16858    const TPM2B_DATA& qualifying_data,
16859    const TPMT_SIG_SCHEME& in_scheme,
16860    const TPML_PCR_SELECTION& pcrselect,
16861    std::string* serialized_command,
16862    AuthorizationDelegate* authorization_delegate) {
16863  VLOG(3) << __func__;
16864  TPM_RC rc = TPM_RC_SUCCESS;
16865  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16866  UINT32 command_size = 10;  // Header size.
16867  std::string handle_section_bytes;
16868  std::string parameter_section_bytes;
16869  TPM_CC command_code = TPM_CC_Quote;
16870  bool is_command_parameter_encryption_possible = true;
16871  bool is_response_parameter_encryption_possible = true;
16872  std::string command_code_bytes;
16873  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16874  if (rc != TPM_RC_SUCCESS) {
16875    return rc;
16876  }
16877  std::string sign_handle_bytes;
16878  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16879  if (rc != TPM_RC_SUCCESS) {
16880    return rc;
16881  }
16882  std::string qualifying_data_bytes;
16883  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16884  if (rc != TPM_RC_SUCCESS) {
16885    return rc;
16886  }
16887  std::string in_scheme_bytes;
16888  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16889  if (rc != TPM_RC_SUCCESS) {
16890    return rc;
16891  }
16892  std::string pcrselect_bytes;
16893  rc = Serialize_TPML_PCR_SELECTION(pcrselect, &pcrselect_bytes);
16894  if (rc != TPM_RC_SUCCESS) {
16895    return rc;
16896  }
16897  if (authorization_delegate) {
16898    // Encrypt just the parameter data, not the size.
16899    std::string tmp = qualifying_data_bytes.substr(2);
16900    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16901      return TRUNKS_RC_ENCRYPTION_FAILED;
16902    }
16903    qualifying_data_bytes.replace(2, std::string::npos, tmp);
16904  }
16905  std::unique_ptr<crypto::SecureHash> hash(
16906      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16907  hash->Update(command_code_bytes.data(), command_code_bytes.size());
16908  hash->Update(sign_handle_name.data(), sign_handle_name.size());
16909  handle_section_bytes += sign_handle_bytes;
16910  command_size += sign_handle_bytes.size();
16911  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16912  parameter_section_bytes += qualifying_data_bytes;
16913  command_size += qualifying_data_bytes.size();
16914  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16915  parameter_section_bytes += in_scheme_bytes;
16916  command_size += in_scheme_bytes.size();
16917  hash->Update(pcrselect_bytes.data(), pcrselect_bytes.size());
16918  parameter_section_bytes += pcrselect_bytes;
16919  command_size += pcrselect_bytes.size();
16920  std::string command_hash(32, 0);
16921  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
16922  std::string authorization_section_bytes;
16923  std::string authorization_size_bytes;
16924  if (authorization_delegate) {
16925    if (!authorization_delegate->GetCommandAuthorization(
16926            command_hash, is_command_parameter_encryption_possible,
16927            is_response_parameter_encryption_possible,
16928            &authorization_section_bytes)) {
16929      return TRUNKS_RC_AUTHORIZATION_FAILED;
16930    }
16931    if (!authorization_section_bytes.empty()) {
16932      tag = TPM_ST_SESSIONS;
16933      std::string tmp;
16934      rc = Serialize_UINT32(authorization_section_bytes.size(),
16935                            &authorization_size_bytes);
16936      if (rc != TPM_RC_SUCCESS) {
16937        return rc;
16938      }
16939      command_size +=
16940          authorization_size_bytes.size() + authorization_section_bytes.size();
16941    }
16942  }
16943  std::string tag_bytes;
16944  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16945  if (rc != TPM_RC_SUCCESS) {
16946    return rc;
16947  }
16948  std::string command_size_bytes;
16949  rc = Serialize_UINT32(command_size, &command_size_bytes);
16950  if (rc != TPM_RC_SUCCESS) {
16951    return rc;
16952  }
16953  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16954                        handle_section_bytes + authorization_size_bytes +
16955                        authorization_section_bytes + parameter_section_bytes;
16956  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16957  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
16958                                            serialized_command->size());
16959  return TPM_RC_SUCCESS;
16960}
16961
16962TPM_RC Tpm::ParseResponse_Quote(const std::string& response,
16963                                TPM2B_ATTEST* quoted,
16964                                TPMT_SIGNATURE* signature,
16965                                AuthorizationDelegate* authorization_delegate) {
16966  VLOG(3) << __func__;
16967  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16968  TPM_RC rc = TPM_RC_SUCCESS;
16969  std::string buffer(response);
16970  TPM_ST tag;
16971  std::string tag_bytes;
16972  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16973  if (rc != TPM_RC_SUCCESS) {
16974    return rc;
16975  }
16976  UINT32 response_size;
16977  std::string response_size_bytes;
16978  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16979  if (rc != TPM_RC_SUCCESS) {
16980    return rc;
16981  }
16982  TPM_RC response_code;
16983  std::string response_code_bytes;
16984  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16985  if (rc != TPM_RC_SUCCESS) {
16986    return rc;
16987  }
16988  if (response_size != response.size()) {
16989    return TPM_RC_SIZE;
16990  }
16991  if (response_code != TPM_RC_SUCCESS) {
16992    return response_code;
16993  }
16994  TPM_CC command_code = TPM_CC_Quote;
16995  std::string command_code_bytes;
16996  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16997  if (rc != TPM_RC_SUCCESS) {
16998    return rc;
16999  }
17000  std::string authorization_section_bytes;
17001  if (tag == TPM_ST_SESSIONS) {
17002    UINT32 parameter_section_size = buffer.size();
17003    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17004    if (rc != TPM_RC_SUCCESS) {
17005      return rc;
17006    }
17007    if (parameter_section_size > buffer.size()) {
17008      return TPM_RC_INSUFFICIENT;
17009    }
17010    authorization_section_bytes = buffer.substr(parameter_section_size);
17011    // Keep the parameter section in |buffer|.
17012    buffer.erase(parameter_section_size);
17013  }
17014  std::unique_ptr<crypto::SecureHash> hash(
17015      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17016  hash->Update(response_code_bytes.data(), response_code_bytes.size());
17017  hash->Update(command_code_bytes.data(), command_code_bytes.size());
17018  hash->Update(buffer.data(), buffer.size());
17019  std::string response_hash(32, 0);
17020  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
17021  if (tag == TPM_ST_SESSIONS) {
17022    CHECK(authorization_delegate) << "Authorization delegate missing!";
17023    if (!authorization_delegate->CheckResponseAuthorization(
17024            response_hash, authorization_section_bytes)) {
17025      return TRUNKS_RC_AUTHORIZATION_FAILED;
17026    }
17027  }
17028  std::string quoted_bytes;
17029  rc = Parse_TPM2B_ATTEST(&buffer, quoted, &quoted_bytes);
17030  if (rc != TPM_RC_SUCCESS) {
17031    return rc;
17032  }
17033  std::string signature_bytes;
17034  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17035  if (rc != TPM_RC_SUCCESS) {
17036    return rc;
17037  }
17038  if (tag == TPM_ST_SESSIONS) {
17039    CHECK(authorization_delegate) << "Authorization delegate missing!";
17040    // Decrypt just the parameter data, not the size.
17041    std::string tmp = quoted_bytes.substr(2);
17042    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
17043      return TRUNKS_RC_ENCRYPTION_FAILED;
17044    }
17045    quoted_bytes.replace(2, std::string::npos, tmp);
17046    rc = Parse_TPM2B_ATTEST(&quoted_bytes, quoted, nullptr);
17047    if (rc != TPM_RC_SUCCESS) {
17048      return rc;
17049    }
17050  }
17051  return TPM_RC_SUCCESS;
17052}
17053
17054void QuoteErrorCallback(const Tpm::QuoteResponse& callback,
17055                        TPM_RC response_code) {
17056  VLOG(1) << __func__;
17057  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17058}
17059
17060void QuoteResponseParser(const Tpm::QuoteResponse& callback,
17061                         AuthorizationDelegate* authorization_delegate,
17062                         const std::string& response) {
17063  VLOG(1) << __func__;
17064  base::Callback<void(TPM_RC)> error_reporter =
17065      base::Bind(QuoteErrorCallback, callback);
17066  TPM2B_ATTEST quoted;
17067  TPMT_SIGNATURE signature;
17068  TPM_RC rc = Tpm::ParseResponse_Quote(response, &quoted, &signature,
17069                                       authorization_delegate);
17070  if (rc != TPM_RC_SUCCESS) {
17071    error_reporter.Run(rc);
17072    return;
17073  }
17074  callback.Run(rc, quoted, signature);
17075}
17076
17077void Tpm::Quote(const TPMI_DH_OBJECT& sign_handle,
17078                const std::string& sign_handle_name,
17079                const TPM2B_DATA& qualifying_data,
17080                const TPMT_SIG_SCHEME& in_scheme,
17081                const TPML_PCR_SELECTION& pcrselect,
17082                AuthorizationDelegate* authorization_delegate,
17083                const QuoteResponse& callback) {
17084  VLOG(1) << __func__;
17085  base::Callback<void(TPM_RC)> error_reporter =
17086      base::Bind(QuoteErrorCallback, callback);
17087  base::Callback<void(const std::string&)> parser =
17088      base::Bind(QuoteResponseParser, callback, authorization_delegate);
17089  std::string command;
17090  TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17091                                     qualifying_data, in_scheme, pcrselect,
17092                                     &command, authorization_delegate);
17093  if (rc != TPM_RC_SUCCESS) {
17094    error_reporter.Run(rc);
17095    return;
17096  }
17097  transceiver_->SendCommand(command, parser);
17098}
17099
17100TPM_RC Tpm::QuoteSync(const TPMI_DH_OBJECT& sign_handle,
17101                      const std::string& sign_handle_name,
17102                      const TPM2B_DATA& qualifying_data,
17103                      const TPMT_SIG_SCHEME& in_scheme,
17104                      const TPML_PCR_SELECTION& pcrselect,
17105                      TPM2B_ATTEST* quoted,
17106                      TPMT_SIGNATURE* signature,
17107                      AuthorizationDelegate* authorization_delegate) {
17108  VLOG(1) << __func__;
17109  std::string command;
17110  TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17111                                     qualifying_data, in_scheme, pcrselect,
17112                                     &command, authorization_delegate);
17113  if (rc != TPM_RC_SUCCESS) {
17114    return rc;
17115  }
17116  std::string response = transceiver_->SendCommandAndWait(command);
17117  rc = ParseResponse_Quote(response, quoted, signature, authorization_delegate);
17118  return rc;
17119}
17120
17121TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest(
17122    const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17123    const std::string& privacy_admin_handle_name,
17124    const TPMI_DH_OBJECT& sign_handle,
17125    const std::string& sign_handle_name,
17126    const TPMI_SH_HMAC& session_handle,
17127    const std::string& session_handle_name,
17128    const TPM2B_DATA& qualifying_data,
17129    const TPMT_SIG_SCHEME& in_scheme,
17130    std::string* serialized_command,
17131    AuthorizationDelegate* authorization_delegate) {
17132  VLOG(3) << __func__;
17133  TPM_RC rc = TPM_RC_SUCCESS;
17134  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17135  UINT32 command_size = 10;  // Header size.
17136  std::string handle_section_bytes;
17137  std::string parameter_section_bytes;
17138  TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17139  bool is_command_parameter_encryption_possible = true;
17140  bool is_response_parameter_encryption_possible = true;
17141  std::string command_code_bytes;
17142  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17143  if (rc != TPM_RC_SUCCESS) {
17144    return rc;
17145  }
17146  std::string privacy_admin_handle_bytes;
17147  rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17148                                     &privacy_admin_handle_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 session_handle_bytes;
17158  rc = Serialize_TPMI_SH_HMAC(session_handle, &session_handle_bytes);
17159  if (rc != TPM_RC_SUCCESS) {
17160    return rc;
17161  }
17162  std::string qualifying_data_bytes;
17163  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17164  if (rc != TPM_RC_SUCCESS) {
17165    return rc;
17166  }
17167  std::string in_scheme_bytes;
17168  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_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(privacy_admin_handle_name.data(),
17184               privacy_admin_handle_name.size());
17185  handle_section_bytes += privacy_admin_handle_bytes;
17186  command_size += privacy_admin_handle_bytes.size();
17187  hash->Update(sign_handle_name.data(), sign_handle_name.size());
17188  handle_section_bytes += sign_handle_bytes;
17189  command_size += sign_handle_bytes.size();
17190  hash->Update(session_handle_name.data(), session_handle_name.size());
17191  handle_section_bytes += session_handle_bytes;
17192  command_size += session_handle_bytes.size();
17193  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17194  parameter_section_bytes += qualifying_data_bytes;
17195  command_size += qualifying_data_bytes.size();
17196  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17197  parameter_section_bytes += in_scheme_bytes;
17198  command_size += in_scheme_bytes.size();
17199  std::string command_hash(32, 0);
17200  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
17201  std::string authorization_section_bytes;
17202  std::string authorization_size_bytes;
17203  if (authorization_delegate) {
17204    if (!authorization_delegate->GetCommandAuthorization(
17205            command_hash, is_command_parameter_encryption_possible,
17206            is_response_parameter_encryption_possible,
17207            &authorization_section_bytes)) {
17208      return TRUNKS_RC_AUTHORIZATION_FAILED;
17209    }
17210    if (!authorization_section_bytes.empty()) {
17211      tag = TPM_ST_SESSIONS;
17212      std::string tmp;
17213      rc = Serialize_UINT32(authorization_section_bytes.size(),
17214                            &authorization_size_bytes);
17215      if (rc != TPM_RC_SUCCESS) {
17216        return rc;
17217      }
17218      command_size +=
17219          authorization_size_bytes.size() + authorization_section_bytes.size();
17220    }
17221  }
17222  std::string tag_bytes;
17223  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17224  if (rc != TPM_RC_SUCCESS) {
17225    return rc;
17226  }
17227  std::string command_size_bytes;
17228  rc = Serialize_UINT32(command_size, &command_size_bytes);
17229  if (rc != TPM_RC_SUCCESS) {
17230    return rc;
17231  }
17232  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17233                        handle_section_bytes + authorization_size_bytes +
17234                        authorization_section_bytes + parameter_section_bytes;
17235  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17236  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
17237                                            serialized_command->size());
17238  return TPM_RC_SUCCESS;
17239}
17240
17241TPM_RC Tpm::ParseResponse_GetSessionAuditDigest(
17242    const std::string& response,
17243    TPM2B_ATTEST* audit_info,
17244    TPMT_SIGNATURE* signature,
17245    AuthorizationDelegate* authorization_delegate) {
17246  VLOG(3) << __func__;
17247  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17248  TPM_RC rc = TPM_RC_SUCCESS;
17249  std::string buffer(response);
17250  TPM_ST tag;
17251  std::string tag_bytes;
17252  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17253  if (rc != TPM_RC_SUCCESS) {
17254    return rc;
17255  }
17256  UINT32 response_size;
17257  std::string response_size_bytes;
17258  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17259  if (rc != TPM_RC_SUCCESS) {
17260    return rc;
17261  }
17262  TPM_RC response_code;
17263  std::string response_code_bytes;
17264  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17265  if (rc != TPM_RC_SUCCESS) {
17266    return rc;
17267  }
17268  if (response_size != response.size()) {
17269    return TPM_RC_SIZE;
17270  }
17271  if (response_code != TPM_RC_SUCCESS) {
17272    return response_code;
17273  }
17274  TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17275  std::string command_code_bytes;
17276  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17277  if (rc != TPM_RC_SUCCESS) {
17278    return rc;
17279  }
17280  std::string authorization_section_bytes;
17281  if (tag == TPM_ST_SESSIONS) {
17282    UINT32 parameter_section_size = buffer.size();
17283    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17284    if (rc != TPM_RC_SUCCESS) {
17285      return rc;
17286    }
17287    if (parameter_section_size > buffer.size()) {
17288      return TPM_RC_INSUFFICIENT;
17289    }
17290    authorization_section_bytes = buffer.substr(parameter_section_size);
17291    // Keep the parameter section in |buffer|.
17292    buffer.erase(parameter_section_size);
17293  }
17294  std::unique_ptr<crypto::SecureHash> hash(
17295      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17296  hash->Update(response_code_bytes.data(), response_code_bytes.size());
17297  hash->Update(command_code_bytes.data(), command_code_bytes.size());
17298  hash->Update(buffer.data(), buffer.size());
17299  std::string response_hash(32, 0);
17300  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
17301  if (tag == TPM_ST_SESSIONS) {
17302    CHECK(authorization_delegate) << "Authorization delegate missing!";
17303    if (!authorization_delegate->CheckResponseAuthorization(
17304            response_hash, authorization_section_bytes)) {
17305      return TRUNKS_RC_AUTHORIZATION_FAILED;
17306    }
17307  }
17308  std::string audit_info_bytes;
17309  rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17310  if (rc != TPM_RC_SUCCESS) {
17311    return rc;
17312  }
17313  std::string signature_bytes;
17314  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17315  if (rc != TPM_RC_SUCCESS) {
17316    return rc;
17317  }
17318  if (tag == TPM_ST_SESSIONS) {
17319    CHECK(authorization_delegate) << "Authorization delegate missing!";
17320    // Decrypt just the parameter data, not the size.
17321    std::string tmp = audit_info_bytes.substr(2);
17322    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
17323      return TRUNKS_RC_ENCRYPTION_FAILED;
17324    }
17325    audit_info_bytes.replace(2, std::string::npos, tmp);
17326    rc = Parse_TPM2B_ATTEST(&audit_info_bytes, audit_info, nullptr);
17327    if (rc != TPM_RC_SUCCESS) {
17328      return rc;
17329    }
17330  }
17331  return TPM_RC_SUCCESS;
17332}
17333
17334void GetSessionAuditDigestErrorCallback(
17335    const Tpm::GetSessionAuditDigestResponse& callback,
17336    TPM_RC response_code) {
17337  VLOG(1) << __func__;
17338  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17339}
17340
17341void GetSessionAuditDigestResponseParser(
17342    const Tpm::GetSessionAuditDigestResponse& callback,
17343    AuthorizationDelegate* authorization_delegate,
17344    const std::string& response) {
17345  VLOG(1) << __func__;
17346  base::Callback<void(TPM_RC)> error_reporter =
17347      base::Bind(GetSessionAuditDigestErrorCallback, callback);
17348  TPM2B_ATTEST audit_info;
17349  TPMT_SIGNATURE signature;
17350  TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest(
17351      response, &audit_info, &signature, authorization_delegate);
17352  if (rc != TPM_RC_SUCCESS) {
17353    error_reporter.Run(rc);
17354    return;
17355  }
17356  callback.Run(rc, audit_info, signature);
17357}
17358
17359void Tpm::GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17360                                const std::string& privacy_admin_handle_name,
17361                                const TPMI_DH_OBJECT& sign_handle,
17362                                const std::string& sign_handle_name,
17363                                const TPMI_SH_HMAC& session_handle,
17364                                const std::string& session_handle_name,
17365                                const TPM2B_DATA& qualifying_data,
17366                                const TPMT_SIG_SCHEME& in_scheme,
17367                                AuthorizationDelegate* authorization_delegate,
17368                                const GetSessionAuditDigestResponse& callback) {
17369  VLOG(1) << __func__;
17370  base::Callback<void(TPM_RC)> error_reporter =
17371      base::Bind(GetSessionAuditDigestErrorCallback, callback);
17372  base::Callback<void(const std::string&)> parser = base::Bind(
17373      GetSessionAuditDigestResponseParser, callback, authorization_delegate);
17374  std::string command;
17375  TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17376      privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17377      sign_handle_name, session_handle, session_handle_name, qualifying_data,
17378      in_scheme, &command, authorization_delegate);
17379  if (rc != TPM_RC_SUCCESS) {
17380    error_reporter.Run(rc);
17381    return;
17382  }
17383  transceiver_->SendCommand(command, parser);
17384}
17385
17386TPM_RC Tpm::GetSessionAuditDigestSync(
17387    const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17388    const std::string& privacy_admin_handle_name,
17389    const TPMI_DH_OBJECT& sign_handle,
17390    const std::string& sign_handle_name,
17391    const TPMI_SH_HMAC& session_handle,
17392    const std::string& session_handle_name,
17393    const TPM2B_DATA& qualifying_data,
17394    const TPMT_SIG_SCHEME& in_scheme,
17395    TPM2B_ATTEST* audit_info,
17396    TPMT_SIGNATURE* signature,
17397    AuthorizationDelegate* authorization_delegate) {
17398  VLOG(1) << __func__;
17399  std::string command;
17400  TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17401      privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17402      sign_handle_name, session_handle, session_handle_name, qualifying_data,
17403      in_scheme, &command, authorization_delegate);
17404  if (rc != TPM_RC_SUCCESS) {
17405    return rc;
17406  }
17407  std::string response = transceiver_->SendCommandAndWait(command);
17408  rc = ParseResponse_GetSessionAuditDigest(response, audit_info, signature,
17409                                           authorization_delegate);
17410  return rc;
17411}
17412
17413TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest(
17414    const TPMI_RH_ENDORSEMENT& privacy_handle,
17415    const std::string& privacy_handle_name,
17416    const TPMI_DH_OBJECT& sign_handle,
17417    const std::string& sign_handle_name,
17418    const TPM2B_DATA& qualifying_data,
17419    const TPMT_SIG_SCHEME& in_scheme,
17420    std::string* serialized_command,
17421    AuthorizationDelegate* authorization_delegate) {
17422  VLOG(3) << __func__;
17423  TPM_RC rc = TPM_RC_SUCCESS;
17424  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17425  UINT32 command_size = 10;  // Header size.
17426  std::string handle_section_bytes;
17427  std::string parameter_section_bytes;
17428  TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17429  bool is_command_parameter_encryption_possible = true;
17430  bool is_response_parameter_encryption_possible = true;
17431  std::string command_code_bytes;
17432  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17433  if (rc != TPM_RC_SUCCESS) {
17434    return rc;
17435  }
17436  std::string privacy_handle_bytes;
17437  rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_handle, &privacy_handle_bytes);
17438  if (rc != TPM_RC_SUCCESS) {
17439    return rc;
17440  }
17441  std::string sign_handle_bytes;
17442  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_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_handle_name.data(), privacy_handle_name.size());
17468  handle_section_bytes += privacy_handle_bytes;
17469  command_size += privacy_handle_bytes.size();
17470  hash->Update(sign_handle_name.data(), sign_handle_name.size());
17471  handle_section_bytes += sign_handle_bytes;
17472  command_size += sign_handle_bytes.size();
17473  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17474  parameter_section_bytes += qualifying_data_bytes;
17475  command_size += qualifying_data_bytes.size();
17476  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17477  parameter_section_bytes += in_scheme_bytes;
17478  command_size += in_scheme_bytes.size();
17479  std::string command_hash(32, 0);
17480  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
17481  std::string authorization_section_bytes;
17482  std::string authorization_size_bytes;
17483  if (authorization_delegate) {
17484    if (!authorization_delegate->GetCommandAuthorization(
17485            command_hash, is_command_parameter_encryption_possible,
17486            is_response_parameter_encryption_possible,
17487            &authorization_section_bytes)) {
17488      return TRUNKS_RC_AUTHORIZATION_FAILED;
17489    }
17490    if (!authorization_section_bytes.empty()) {
17491      tag = TPM_ST_SESSIONS;
17492      std::string tmp;
17493      rc = Serialize_UINT32(authorization_section_bytes.size(),
17494                            &authorization_size_bytes);
17495      if (rc != TPM_RC_SUCCESS) {
17496        return rc;
17497      }
17498      command_size +=
17499          authorization_size_bytes.size() + authorization_section_bytes.size();
17500    }
17501  }
17502  std::string tag_bytes;
17503  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17504  if (rc != TPM_RC_SUCCESS) {
17505    return rc;
17506  }
17507  std::string command_size_bytes;
17508  rc = Serialize_UINT32(command_size, &command_size_bytes);
17509  if (rc != TPM_RC_SUCCESS) {
17510    return rc;
17511  }
17512  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17513                        handle_section_bytes + authorization_size_bytes +
17514                        authorization_section_bytes + parameter_section_bytes;
17515  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17516  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
17517                                            serialized_command->size());
17518  return TPM_RC_SUCCESS;
17519}
17520
17521TPM_RC Tpm::ParseResponse_GetCommandAuditDigest(
17522    const std::string& response,
17523    TPM2B_ATTEST* audit_info,
17524    TPMT_SIGNATURE* signature,
17525    AuthorizationDelegate* authorization_delegate) {
17526  VLOG(3) << __func__;
17527  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17528  TPM_RC rc = TPM_RC_SUCCESS;
17529  std::string buffer(response);
17530  TPM_ST tag;
17531  std::string tag_bytes;
17532  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17533  if (rc != TPM_RC_SUCCESS) {
17534    return rc;
17535  }
17536  UINT32 response_size;
17537  std::string response_size_bytes;
17538  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17539  if (rc != TPM_RC_SUCCESS) {
17540    return rc;
17541  }
17542  TPM_RC response_code;
17543  std::string response_code_bytes;
17544  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17545  if (rc != TPM_RC_SUCCESS) {
17546    return rc;
17547  }
17548  if (response_size != response.size()) {
17549    return TPM_RC_SIZE;
17550  }
17551  if (response_code != TPM_RC_SUCCESS) {
17552    return response_code;
17553  }
17554  TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17555  std::string command_code_bytes;
17556  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17557  if (rc != TPM_RC_SUCCESS) {
17558    return rc;
17559  }
17560  std::string authorization_section_bytes;
17561  if (tag == TPM_ST_SESSIONS) {
17562    UINT32 parameter_section_size = buffer.size();
17563    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17564    if (rc != TPM_RC_SUCCESS) {
17565      return rc;
17566    }
17567    if (parameter_section_size > buffer.size()) {
17568      return TPM_RC_INSUFFICIENT;
17569    }
17570    authorization_section_bytes = buffer.substr(parameter_section_size);
17571    // Keep the parameter section in |buffer|.
17572    buffer.erase(parameter_section_size);
17573  }
17574  std::unique_ptr<crypto::SecureHash> hash(
17575      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17576  hash->Update(response_code_bytes.data(), response_code_bytes.size());
17577  hash->Update(command_code_bytes.data(), command_code_bytes.size());
17578  hash->Update(buffer.data(), buffer.size());
17579  std::string response_hash(32, 0);
17580  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
17581  if (tag == TPM_ST_SESSIONS) {
17582    CHECK(authorization_delegate) << "Authorization delegate missing!";
17583    if (!authorization_delegate->CheckResponseAuthorization(
17584            response_hash, authorization_section_bytes)) {
17585      return TRUNKS_RC_AUTHORIZATION_FAILED;
17586    }
17587  }
17588  std::string audit_info_bytes;
17589  rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17590  if (rc != TPM_RC_SUCCESS) {
17591    return rc;
17592  }
17593  std::string signature_bytes;
17594  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17595  if (rc != TPM_RC_SUCCESS) {
17596    return rc;
17597  }
17598  if (tag == TPM_ST_SESSIONS) {
17599    CHECK(authorization_delegate) << "Authorization delegate missing!";
17600    // Decrypt just the parameter data, not the size.
17601    std::string tmp = audit_info_bytes.substr(2);
17602    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
17603      return TRUNKS_RC_ENCRYPTION_FAILED;
17604    }
17605    audit_info_bytes.replace(2, std::string::npos, tmp);
17606    rc = Parse_TPM2B_ATTEST(&audit_info_bytes, audit_info, nullptr);
17607    if (rc != TPM_RC_SUCCESS) {
17608      return rc;
17609    }
17610  }
17611  return TPM_RC_SUCCESS;
17612}
17613
17614void GetCommandAuditDigestErrorCallback(
17615    const Tpm::GetCommandAuditDigestResponse& callback,
17616    TPM_RC response_code) {
17617  VLOG(1) << __func__;
17618  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17619}
17620
17621void GetCommandAuditDigestResponseParser(
17622    const Tpm::GetCommandAuditDigestResponse& callback,
17623    AuthorizationDelegate* authorization_delegate,
17624    const std::string& response) {
17625  VLOG(1) << __func__;
17626  base::Callback<void(TPM_RC)> error_reporter =
17627      base::Bind(GetCommandAuditDigestErrorCallback, callback);
17628  TPM2B_ATTEST audit_info;
17629  TPMT_SIGNATURE signature;
17630  TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest(
17631      response, &audit_info, &signature, authorization_delegate);
17632  if (rc != TPM_RC_SUCCESS) {
17633    error_reporter.Run(rc);
17634    return;
17635  }
17636  callback.Run(rc, audit_info, signature);
17637}
17638
17639void Tpm::GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_handle,
17640                                const std::string& privacy_handle_name,
17641                                const TPMI_DH_OBJECT& sign_handle,
17642                                const std::string& sign_handle_name,
17643                                const TPM2B_DATA& qualifying_data,
17644                                const TPMT_SIG_SCHEME& in_scheme,
17645                                AuthorizationDelegate* authorization_delegate,
17646                                const GetCommandAuditDigestResponse& callback) {
17647  VLOG(1) << __func__;
17648  base::Callback<void(TPM_RC)> error_reporter =
17649      base::Bind(GetCommandAuditDigestErrorCallback, callback);
17650  base::Callback<void(const std::string&)> parser = base::Bind(
17651      GetCommandAuditDigestResponseParser, callback, authorization_delegate);
17652  std::string command;
17653  TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17654      privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17655      qualifying_data, in_scheme, &command, authorization_delegate);
17656  if (rc != TPM_RC_SUCCESS) {
17657    error_reporter.Run(rc);
17658    return;
17659  }
17660  transceiver_->SendCommand(command, parser);
17661}
17662
17663TPM_RC Tpm::GetCommandAuditDigestSync(
17664    const TPMI_RH_ENDORSEMENT& privacy_handle,
17665    const std::string& privacy_handle_name,
17666    const TPMI_DH_OBJECT& sign_handle,
17667    const std::string& sign_handle_name,
17668    const TPM2B_DATA& qualifying_data,
17669    const TPMT_SIG_SCHEME& in_scheme,
17670    TPM2B_ATTEST* audit_info,
17671    TPMT_SIGNATURE* signature,
17672    AuthorizationDelegate* authorization_delegate) {
17673  VLOG(1) << __func__;
17674  std::string command;
17675  TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17676      privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17677      qualifying_data, in_scheme, &command, authorization_delegate);
17678  if (rc != TPM_RC_SUCCESS) {
17679    return rc;
17680  }
17681  std::string response = transceiver_->SendCommandAndWait(command);
17682  rc = ParseResponse_GetCommandAuditDigest(response, audit_info, signature,
17683                                           authorization_delegate);
17684  return rc;
17685}
17686
17687TPM_RC Tpm::SerializeCommand_GetTime(
17688    const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17689    const std::string& privacy_admin_handle_name,
17690    const TPMI_DH_OBJECT& sign_handle,
17691    const std::string& sign_handle_name,
17692    const TPM2B_DATA& qualifying_data,
17693    const TPMT_SIG_SCHEME& in_scheme,
17694    std::string* serialized_command,
17695    AuthorizationDelegate* authorization_delegate) {
17696  VLOG(3) << __func__;
17697  TPM_RC rc = TPM_RC_SUCCESS;
17698  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17699  UINT32 command_size = 10;  // Header size.
17700  std::string handle_section_bytes;
17701  std::string parameter_section_bytes;
17702  TPM_CC command_code = TPM_CC_GetTime;
17703  bool is_command_parameter_encryption_possible = true;
17704  bool is_response_parameter_encryption_possible = true;
17705  std::string command_code_bytes;
17706  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17707  if (rc != TPM_RC_SUCCESS) {
17708    return rc;
17709  }
17710  std::string privacy_admin_handle_bytes;
17711  rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17712                                     &privacy_admin_handle_bytes);
17713  if (rc != TPM_RC_SUCCESS) {
17714    return rc;
17715  }
17716  std::string sign_handle_bytes;
17717  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17718  if (rc != TPM_RC_SUCCESS) {
17719    return rc;
17720  }
17721  std::string qualifying_data_bytes;
17722  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17723  if (rc != TPM_RC_SUCCESS) {
17724    return rc;
17725  }
17726  std::string in_scheme_bytes;
17727  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17728  if (rc != TPM_RC_SUCCESS) {
17729    return rc;
17730  }
17731  if (authorization_delegate) {
17732    // Encrypt just the parameter data, not the size.
17733    std::string tmp = qualifying_data_bytes.substr(2);
17734    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17735      return TRUNKS_RC_ENCRYPTION_FAILED;
17736    }
17737    qualifying_data_bytes.replace(2, std::string::npos, tmp);
17738  }
17739  std::unique_ptr<crypto::SecureHash> hash(
17740      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17741  hash->Update(command_code_bytes.data(), command_code_bytes.size());
17742  hash->Update(privacy_admin_handle_name.data(),
17743               privacy_admin_handle_name.size());
17744  handle_section_bytes += privacy_admin_handle_bytes;
17745  command_size += privacy_admin_handle_bytes.size();
17746  hash->Update(sign_handle_name.data(), sign_handle_name.size());
17747  handle_section_bytes += sign_handle_bytes;
17748  command_size += sign_handle_bytes.size();
17749  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17750  parameter_section_bytes += qualifying_data_bytes;
17751  command_size += qualifying_data_bytes.size();
17752  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17753  parameter_section_bytes += in_scheme_bytes;
17754  command_size += in_scheme_bytes.size();
17755  std::string command_hash(32, 0);
17756  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
17757  std::string authorization_section_bytes;
17758  std::string authorization_size_bytes;
17759  if (authorization_delegate) {
17760    if (!authorization_delegate->GetCommandAuthorization(
17761            command_hash, is_command_parameter_encryption_possible,
17762            is_response_parameter_encryption_possible,
17763            &authorization_section_bytes)) {
17764      return TRUNKS_RC_AUTHORIZATION_FAILED;
17765    }
17766    if (!authorization_section_bytes.empty()) {
17767      tag = TPM_ST_SESSIONS;
17768      std::string tmp;
17769      rc = Serialize_UINT32(authorization_section_bytes.size(),
17770                            &authorization_size_bytes);
17771      if (rc != TPM_RC_SUCCESS) {
17772        return rc;
17773      }
17774      command_size +=
17775          authorization_size_bytes.size() + authorization_section_bytes.size();
17776    }
17777  }
17778  std::string tag_bytes;
17779  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17780  if (rc != TPM_RC_SUCCESS) {
17781    return rc;
17782  }
17783  std::string command_size_bytes;
17784  rc = Serialize_UINT32(command_size, &command_size_bytes);
17785  if (rc != TPM_RC_SUCCESS) {
17786    return rc;
17787  }
17788  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17789                        handle_section_bytes + authorization_size_bytes +
17790                        authorization_section_bytes + parameter_section_bytes;
17791  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17792  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
17793                                            serialized_command->size());
17794  return TPM_RC_SUCCESS;
17795}
17796
17797TPM_RC Tpm::ParseResponse_GetTime(
17798    const std::string& response,
17799    TPM2B_ATTEST* time_info,
17800    TPMT_SIGNATURE* signature,
17801    AuthorizationDelegate* authorization_delegate) {
17802  VLOG(3) << __func__;
17803  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17804  TPM_RC rc = TPM_RC_SUCCESS;
17805  std::string buffer(response);
17806  TPM_ST tag;
17807  std::string tag_bytes;
17808  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17809  if (rc != TPM_RC_SUCCESS) {
17810    return rc;
17811  }
17812  UINT32 response_size;
17813  std::string response_size_bytes;
17814  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17815  if (rc != TPM_RC_SUCCESS) {
17816    return rc;
17817  }
17818  TPM_RC response_code;
17819  std::string response_code_bytes;
17820  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17821  if (rc != TPM_RC_SUCCESS) {
17822    return rc;
17823  }
17824  if (response_size != response.size()) {
17825    return TPM_RC_SIZE;
17826  }
17827  if (response_code != TPM_RC_SUCCESS) {
17828    return response_code;
17829  }
17830  TPM_CC command_code = TPM_CC_GetTime;
17831  std::string command_code_bytes;
17832  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17833  if (rc != TPM_RC_SUCCESS) {
17834    return rc;
17835  }
17836  std::string authorization_section_bytes;
17837  if (tag == TPM_ST_SESSIONS) {
17838    UINT32 parameter_section_size = buffer.size();
17839    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17840    if (rc != TPM_RC_SUCCESS) {
17841      return rc;
17842    }
17843    if (parameter_section_size > buffer.size()) {
17844      return TPM_RC_INSUFFICIENT;
17845    }
17846    authorization_section_bytes = buffer.substr(parameter_section_size);
17847    // Keep the parameter section in |buffer|.
17848    buffer.erase(parameter_section_size);
17849  }
17850  std::unique_ptr<crypto::SecureHash> hash(
17851      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17852  hash->Update(response_code_bytes.data(), response_code_bytes.size());
17853  hash->Update(command_code_bytes.data(), command_code_bytes.size());
17854  hash->Update(buffer.data(), buffer.size());
17855  std::string response_hash(32, 0);
17856  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
17857  if (tag == TPM_ST_SESSIONS) {
17858    CHECK(authorization_delegate) << "Authorization delegate missing!";
17859    if (!authorization_delegate->CheckResponseAuthorization(
17860            response_hash, authorization_section_bytes)) {
17861      return TRUNKS_RC_AUTHORIZATION_FAILED;
17862    }
17863  }
17864  std::string time_info_bytes;
17865  rc = Parse_TPM2B_ATTEST(&buffer, time_info, &time_info_bytes);
17866  if (rc != TPM_RC_SUCCESS) {
17867    return rc;
17868  }
17869  std::string signature_bytes;
17870  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17871  if (rc != TPM_RC_SUCCESS) {
17872    return rc;
17873  }
17874  if (tag == TPM_ST_SESSIONS) {
17875    CHECK(authorization_delegate) << "Authorization delegate missing!";
17876    // Decrypt just the parameter data, not the size.
17877    std::string tmp = time_info_bytes.substr(2);
17878    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
17879      return TRUNKS_RC_ENCRYPTION_FAILED;
17880    }
17881    time_info_bytes.replace(2, std::string::npos, tmp);
17882    rc = Parse_TPM2B_ATTEST(&time_info_bytes, time_info, nullptr);
17883    if (rc != TPM_RC_SUCCESS) {
17884      return rc;
17885    }
17886  }
17887  return TPM_RC_SUCCESS;
17888}
17889
17890void GetTimeErrorCallback(const Tpm::GetTimeResponse& callback,
17891                          TPM_RC response_code) {
17892  VLOG(1) << __func__;
17893  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17894}
17895
17896void GetTimeResponseParser(const Tpm::GetTimeResponse& callback,
17897                           AuthorizationDelegate* authorization_delegate,
17898                           const std::string& response) {
17899  VLOG(1) << __func__;
17900  base::Callback<void(TPM_RC)> error_reporter =
17901      base::Bind(GetTimeErrorCallback, callback);
17902  TPM2B_ATTEST time_info;
17903  TPMT_SIGNATURE signature;
17904  TPM_RC rc = Tpm::ParseResponse_GetTime(response, &time_info, &signature,
17905                                         authorization_delegate);
17906  if (rc != TPM_RC_SUCCESS) {
17907    error_reporter.Run(rc);
17908    return;
17909  }
17910  callback.Run(rc, time_info, signature);
17911}
17912
17913void Tpm::GetTime(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17914                  const std::string& privacy_admin_handle_name,
17915                  const TPMI_DH_OBJECT& sign_handle,
17916                  const std::string& sign_handle_name,
17917                  const TPM2B_DATA& qualifying_data,
17918                  const TPMT_SIG_SCHEME& in_scheme,
17919                  AuthorizationDelegate* authorization_delegate,
17920                  const GetTimeResponse& callback) {
17921  VLOG(1) << __func__;
17922  base::Callback<void(TPM_RC)> error_reporter =
17923      base::Bind(GetTimeErrorCallback, callback);
17924  base::Callback<void(const std::string&)> parser =
17925      base::Bind(GetTimeResponseParser, callback, authorization_delegate);
17926  std::string command;
17927  TPM_RC rc =
17928      SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
17929                               sign_handle, sign_handle_name, qualifying_data,
17930                               in_scheme, &command, authorization_delegate);
17931  if (rc != TPM_RC_SUCCESS) {
17932    error_reporter.Run(rc);
17933    return;
17934  }
17935  transceiver_->SendCommand(command, parser);
17936}
17937
17938TPM_RC Tpm::GetTimeSync(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17939                        const std::string& privacy_admin_handle_name,
17940                        const TPMI_DH_OBJECT& sign_handle,
17941                        const std::string& sign_handle_name,
17942                        const TPM2B_DATA& qualifying_data,
17943                        const TPMT_SIG_SCHEME& in_scheme,
17944                        TPM2B_ATTEST* time_info,
17945                        TPMT_SIGNATURE* signature,
17946                        AuthorizationDelegate* authorization_delegate) {
17947  VLOG(1) << __func__;
17948  std::string command;
17949  TPM_RC rc =
17950      SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
17951                               sign_handle, sign_handle_name, qualifying_data,
17952                               in_scheme, &command, authorization_delegate);
17953  if (rc != TPM_RC_SUCCESS) {
17954    return rc;
17955  }
17956  std::string response = transceiver_->SendCommandAndWait(command);
17957  rc = ParseResponse_GetTime(response, time_info, signature,
17958                             authorization_delegate);
17959  return rc;
17960}
17961
17962TPM_RC Tpm::SerializeCommand_Commit(
17963    const TPMI_DH_OBJECT& sign_handle,
17964    const std::string& sign_handle_name,
17965    const UINT32& param_size,
17966    const TPM2B_ECC_POINT& p1,
17967    const TPM2B_SENSITIVE_DATA& s2,
17968    const TPM2B_ECC_PARAMETER& y2,
17969    std::string* serialized_command,
17970    AuthorizationDelegate* authorization_delegate) {
17971  VLOG(3) << __func__;
17972  TPM_RC rc = TPM_RC_SUCCESS;
17973  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17974  UINT32 command_size = 10;  // Header size.
17975  std::string handle_section_bytes;
17976  std::string parameter_section_bytes;
17977  TPM_CC command_code = TPM_CC_Commit;
17978  bool is_command_parameter_encryption_possible = false;
17979  bool is_response_parameter_encryption_possible = false;
17980  std::string command_code_bytes;
17981  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17982  if (rc != TPM_RC_SUCCESS) {
17983    return rc;
17984  }
17985  std::string param_size_bytes;
17986  rc = Serialize_UINT32(param_size, &param_size_bytes);
17987  if (rc != TPM_RC_SUCCESS) {
17988    return rc;
17989  }
17990  std::string sign_handle_bytes;
17991  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17992  if (rc != TPM_RC_SUCCESS) {
17993    return rc;
17994  }
17995  std::string p1_bytes;
17996  rc = Serialize_TPM2B_ECC_POINT(p1, &p1_bytes);
17997  if (rc != TPM_RC_SUCCESS) {
17998    return rc;
17999  }
18000  std::string s2_bytes;
18001  rc = Serialize_TPM2B_SENSITIVE_DATA(s2, &s2_bytes);
18002  if (rc != TPM_RC_SUCCESS) {
18003    return rc;
18004  }
18005  std::string y2_bytes;
18006  rc = Serialize_TPM2B_ECC_PARAMETER(y2, &y2_bytes);
18007  if (rc != TPM_RC_SUCCESS) {
18008    return rc;
18009  }
18010  std::unique_ptr<crypto::SecureHash> hash(
18011      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18012  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18013  hash->Update(sign_handle_name.data(), sign_handle_name.size());
18014  handle_section_bytes += sign_handle_bytes;
18015  command_size += sign_handle_bytes.size();
18016  hash->Update(param_size_bytes.data(), param_size_bytes.size());
18017  parameter_section_bytes += param_size_bytes;
18018  command_size += param_size_bytes.size();
18019  hash->Update(p1_bytes.data(), p1_bytes.size());
18020  parameter_section_bytes += p1_bytes;
18021  command_size += p1_bytes.size();
18022  hash->Update(s2_bytes.data(), s2_bytes.size());
18023  parameter_section_bytes += s2_bytes;
18024  command_size += s2_bytes.size();
18025  hash->Update(y2_bytes.data(), y2_bytes.size());
18026  parameter_section_bytes += y2_bytes;
18027  command_size += y2_bytes.size();
18028  std::string command_hash(32, 0);
18029  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
18030  std::string authorization_section_bytes;
18031  std::string authorization_size_bytes;
18032  if (authorization_delegate) {
18033    if (!authorization_delegate->GetCommandAuthorization(
18034            command_hash, is_command_parameter_encryption_possible,
18035            is_response_parameter_encryption_possible,
18036            &authorization_section_bytes)) {
18037      return TRUNKS_RC_AUTHORIZATION_FAILED;
18038    }
18039    if (!authorization_section_bytes.empty()) {
18040      tag = TPM_ST_SESSIONS;
18041      std::string tmp;
18042      rc = Serialize_UINT32(authorization_section_bytes.size(),
18043                            &authorization_size_bytes);
18044      if (rc != TPM_RC_SUCCESS) {
18045        return rc;
18046      }
18047      command_size +=
18048          authorization_size_bytes.size() + authorization_section_bytes.size();
18049    }
18050  }
18051  std::string tag_bytes;
18052  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18053  if (rc != TPM_RC_SUCCESS) {
18054    return rc;
18055  }
18056  std::string command_size_bytes;
18057  rc = Serialize_UINT32(command_size, &command_size_bytes);
18058  if (rc != TPM_RC_SUCCESS) {
18059    return rc;
18060  }
18061  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18062                        handle_section_bytes + authorization_size_bytes +
18063                        authorization_section_bytes + parameter_section_bytes;
18064  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18065  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
18066                                            serialized_command->size());
18067  return TPM_RC_SUCCESS;
18068}
18069
18070TPM_RC Tpm::ParseResponse_Commit(
18071    const std::string& response,
18072    UINT32* param_size_out,
18073    TPM2B_ECC_POINT* k,
18074    TPM2B_ECC_POINT* l,
18075    TPM2B_ECC_POINT* e,
18076    UINT16* counter,
18077    AuthorizationDelegate* authorization_delegate) {
18078  VLOG(3) << __func__;
18079  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18080  TPM_RC rc = TPM_RC_SUCCESS;
18081  std::string buffer(response);
18082  TPM_ST tag;
18083  std::string tag_bytes;
18084  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18085  if (rc != TPM_RC_SUCCESS) {
18086    return rc;
18087  }
18088  UINT32 response_size;
18089  std::string response_size_bytes;
18090  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18091  if (rc != TPM_RC_SUCCESS) {
18092    return rc;
18093  }
18094  TPM_RC response_code;
18095  std::string response_code_bytes;
18096  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18097  if (rc != TPM_RC_SUCCESS) {
18098    return rc;
18099  }
18100  if (response_size != response.size()) {
18101    return TPM_RC_SIZE;
18102  }
18103  if (response_code != TPM_RC_SUCCESS) {
18104    return response_code;
18105  }
18106  TPM_CC command_code = TPM_CC_Commit;
18107  std::string command_code_bytes;
18108  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18109  if (rc != TPM_RC_SUCCESS) {
18110    return rc;
18111  }
18112  std::string authorization_section_bytes;
18113  if (tag == TPM_ST_SESSIONS) {
18114    UINT32 parameter_section_size = buffer.size();
18115    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18116    if (rc != TPM_RC_SUCCESS) {
18117      return rc;
18118    }
18119    if (parameter_section_size > buffer.size()) {
18120      return TPM_RC_INSUFFICIENT;
18121    }
18122    authorization_section_bytes = buffer.substr(parameter_section_size);
18123    // Keep the parameter section in |buffer|.
18124    buffer.erase(parameter_section_size);
18125  }
18126  std::unique_ptr<crypto::SecureHash> hash(
18127      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18128  hash->Update(response_code_bytes.data(), response_code_bytes.size());
18129  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18130  hash->Update(buffer.data(), buffer.size());
18131  std::string response_hash(32, 0);
18132  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
18133  if (tag == TPM_ST_SESSIONS) {
18134    CHECK(authorization_delegate) << "Authorization delegate missing!";
18135    if (!authorization_delegate->CheckResponseAuthorization(
18136            response_hash, authorization_section_bytes)) {
18137      return TRUNKS_RC_AUTHORIZATION_FAILED;
18138    }
18139  }
18140  std::string param_size_out_bytes;
18141  rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18142  if (rc != TPM_RC_SUCCESS) {
18143    return rc;
18144  }
18145  std::string k_bytes;
18146  rc = Parse_TPM2B_ECC_POINT(&buffer, k, &k_bytes);
18147  if (rc != TPM_RC_SUCCESS) {
18148    return rc;
18149  }
18150  std::string l_bytes;
18151  rc = Parse_TPM2B_ECC_POINT(&buffer, l, &l_bytes);
18152  if (rc != TPM_RC_SUCCESS) {
18153    return rc;
18154  }
18155  std::string e_bytes;
18156  rc = Parse_TPM2B_ECC_POINT(&buffer, e, &e_bytes);
18157  if (rc != TPM_RC_SUCCESS) {
18158    return rc;
18159  }
18160  std::string counter_bytes;
18161  rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18162  if (rc != TPM_RC_SUCCESS) {
18163    return rc;
18164  }
18165  return TPM_RC_SUCCESS;
18166}
18167
18168void CommitErrorCallback(const Tpm::CommitResponse& callback,
18169                         TPM_RC response_code) {
18170  VLOG(1) << __func__;
18171  callback.Run(response_code, UINT32(), TPM2B_ECC_POINT(), TPM2B_ECC_POINT(),
18172               TPM2B_ECC_POINT(), UINT16());
18173}
18174
18175void CommitResponseParser(const Tpm::CommitResponse& callback,
18176                          AuthorizationDelegate* authorization_delegate,
18177                          const std::string& response) {
18178  VLOG(1) << __func__;
18179  base::Callback<void(TPM_RC)> error_reporter =
18180      base::Bind(CommitErrorCallback, callback);
18181  UINT32 param_size_out;
18182  TPM2B_ECC_POINT k;
18183  TPM2B_ECC_POINT l;
18184  TPM2B_ECC_POINT e;
18185  UINT16 counter;
18186  TPM_RC rc = Tpm::ParseResponse_Commit(response, &param_size_out, &k, &l, &e,
18187                                        &counter, authorization_delegate);
18188  if (rc != TPM_RC_SUCCESS) {
18189    error_reporter.Run(rc);
18190    return;
18191  }
18192  callback.Run(rc, param_size_out, k, l, e, counter);
18193}
18194
18195void Tpm::Commit(const TPMI_DH_OBJECT& sign_handle,
18196                 const std::string& sign_handle_name,
18197                 const UINT32& param_size,
18198                 const TPM2B_ECC_POINT& p1,
18199                 const TPM2B_SENSITIVE_DATA& s2,
18200                 const TPM2B_ECC_PARAMETER& y2,
18201                 AuthorizationDelegate* authorization_delegate,
18202                 const CommitResponse& callback) {
18203  VLOG(1) << __func__;
18204  base::Callback<void(TPM_RC)> error_reporter =
18205      base::Bind(CommitErrorCallback, callback);
18206  base::Callback<void(const std::string&)> parser =
18207      base::Bind(CommitResponseParser, callback, authorization_delegate);
18208  std::string command;
18209  TPM_RC rc =
18210      SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18211                              y2, &command, authorization_delegate);
18212  if (rc != TPM_RC_SUCCESS) {
18213    error_reporter.Run(rc);
18214    return;
18215  }
18216  transceiver_->SendCommand(command, parser);
18217}
18218
18219TPM_RC Tpm::CommitSync(const TPMI_DH_OBJECT& sign_handle,
18220                       const std::string& sign_handle_name,
18221                       const UINT32& param_size,
18222                       const TPM2B_ECC_POINT& p1,
18223                       const TPM2B_SENSITIVE_DATA& s2,
18224                       const TPM2B_ECC_PARAMETER& y2,
18225                       UINT32* param_size_out,
18226                       TPM2B_ECC_POINT* k,
18227                       TPM2B_ECC_POINT* l,
18228                       TPM2B_ECC_POINT* e,
18229                       UINT16* counter,
18230                       AuthorizationDelegate* authorization_delegate) {
18231  VLOG(1) << __func__;
18232  std::string command;
18233  TPM_RC rc =
18234      SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18235                              y2, &command, authorization_delegate);
18236  if (rc != TPM_RC_SUCCESS) {
18237    return rc;
18238  }
18239  std::string response = transceiver_->SendCommandAndWait(command);
18240  rc = ParseResponse_Commit(response, param_size_out, k, l, e, counter,
18241                            authorization_delegate);
18242  return rc;
18243}
18244
18245TPM_RC Tpm::SerializeCommand_EC_Ephemeral(
18246    const UINT32& param_size,
18247    const TPMI_ECC_CURVE& curve_id,
18248    std::string* serialized_command,
18249    AuthorizationDelegate* authorization_delegate) {
18250  VLOG(3) << __func__;
18251  TPM_RC rc = TPM_RC_SUCCESS;
18252  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18253  UINT32 command_size = 10;  // Header size.
18254  std::string handle_section_bytes;
18255  std::string parameter_section_bytes;
18256  TPM_CC command_code = TPM_CC_EC_Ephemeral;
18257  bool is_command_parameter_encryption_possible = false;
18258  bool is_response_parameter_encryption_possible = false;
18259  std::string command_code_bytes;
18260  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18261  if (rc != TPM_RC_SUCCESS) {
18262    return rc;
18263  }
18264  std::string param_size_bytes;
18265  rc = Serialize_UINT32(param_size, &param_size_bytes);
18266  if (rc != TPM_RC_SUCCESS) {
18267    return rc;
18268  }
18269  std::string curve_id_bytes;
18270  rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
18271  if (rc != TPM_RC_SUCCESS) {
18272    return rc;
18273  }
18274  std::unique_ptr<crypto::SecureHash> hash(
18275      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18276  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18277  hash->Update(param_size_bytes.data(), param_size_bytes.size());
18278  parameter_section_bytes += param_size_bytes;
18279  command_size += param_size_bytes.size();
18280  hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
18281  parameter_section_bytes += curve_id_bytes;
18282  command_size += curve_id_bytes.size();
18283  std::string command_hash(32, 0);
18284  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
18285  std::string authorization_section_bytes;
18286  std::string authorization_size_bytes;
18287  if (authorization_delegate) {
18288    if (!authorization_delegate->GetCommandAuthorization(
18289            command_hash, is_command_parameter_encryption_possible,
18290            is_response_parameter_encryption_possible,
18291            &authorization_section_bytes)) {
18292      return TRUNKS_RC_AUTHORIZATION_FAILED;
18293    }
18294    if (!authorization_section_bytes.empty()) {
18295      tag = TPM_ST_SESSIONS;
18296      std::string tmp;
18297      rc = Serialize_UINT32(authorization_section_bytes.size(),
18298                            &authorization_size_bytes);
18299      if (rc != TPM_RC_SUCCESS) {
18300        return rc;
18301      }
18302      command_size +=
18303          authorization_size_bytes.size() + authorization_section_bytes.size();
18304    }
18305  }
18306  std::string tag_bytes;
18307  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18308  if (rc != TPM_RC_SUCCESS) {
18309    return rc;
18310  }
18311  std::string command_size_bytes;
18312  rc = Serialize_UINT32(command_size, &command_size_bytes);
18313  if (rc != TPM_RC_SUCCESS) {
18314    return rc;
18315  }
18316  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18317                        handle_section_bytes + authorization_size_bytes +
18318                        authorization_section_bytes + parameter_section_bytes;
18319  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18320  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
18321                                            serialized_command->size());
18322  return TPM_RC_SUCCESS;
18323}
18324
18325TPM_RC Tpm::ParseResponse_EC_Ephemeral(
18326    const std::string& response,
18327    UINT32* param_size_out,
18328    TPM2B_ECC_POINT* q,
18329    UINT16* counter,
18330    AuthorizationDelegate* authorization_delegate) {
18331  VLOG(3) << __func__;
18332  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18333  TPM_RC rc = TPM_RC_SUCCESS;
18334  std::string buffer(response);
18335  TPM_ST tag;
18336  std::string tag_bytes;
18337  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18338  if (rc != TPM_RC_SUCCESS) {
18339    return rc;
18340  }
18341  UINT32 response_size;
18342  std::string response_size_bytes;
18343  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18344  if (rc != TPM_RC_SUCCESS) {
18345    return rc;
18346  }
18347  TPM_RC response_code;
18348  std::string response_code_bytes;
18349  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18350  if (rc != TPM_RC_SUCCESS) {
18351    return rc;
18352  }
18353  if (response_size != response.size()) {
18354    return TPM_RC_SIZE;
18355  }
18356  if (response_code != TPM_RC_SUCCESS) {
18357    return response_code;
18358  }
18359  TPM_CC command_code = TPM_CC_EC_Ephemeral;
18360  std::string command_code_bytes;
18361  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18362  if (rc != TPM_RC_SUCCESS) {
18363    return rc;
18364  }
18365  std::string authorization_section_bytes;
18366  if (tag == TPM_ST_SESSIONS) {
18367    UINT32 parameter_section_size = buffer.size();
18368    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18369    if (rc != TPM_RC_SUCCESS) {
18370      return rc;
18371    }
18372    if (parameter_section_size > buffer.size()) {
18373      return TPM_RC_INSUFFICIENT;
18374    }
18375    authorization_section_bytes = buffer.substr(parameter_section_size);
18376    // Keep the parameter section in |buffer|.
18377    buffer.erase(parameter_section_size);
18378  }
18379  std::unique_ptr<crypto::SecureHash> hash(
18380      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18381  hash->Update(response_code_bytes.data(), response_code_bytes.size());
18382  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18383  hash->Update(buffer.data(), buffer.size());
18384  std::string response_hash(32, 0);
18385  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
18386  if (tag == TPM_ST_SESSIONS) {
18387    CHECK(authorization_delegate) << "Authorization delegate missing!";
18388    if (!authorization_delegate->CheckResponseAuthorization(
18389            response_hash, authorization_section_bytes)) {
18390      return TRUNKS_RC_AUTHORIZATION_FAILED;
18391    }
18392  }
18393  std::string param_size_out_bytes;
18394  rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18395  if (rc != TPM_RC_SUCCESS) {
18396    return rc;
18397  }
18398  std::string q_bytes;
18399  rc = Parse_TPM2B_ECC_POINT(&buffer, q, &q_bytes);
18400  if (rc != TPM_RC_SUCCESS) {
18401    return rc;
18402  }
18403  std::string counter_bytes;
18404  rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18405  if (rc != TPM_RC_SUCCESS) {
18406    return rc;
18407  }
18408  return TPM_RC_SUCCESS;
18409}
18410
18411void EC_EphemeralErrorCallback(const Tpm::EC_EphemeralResponse& callback,
18412                               TPM_RC response_code) {
18413  VLOG(1) << __func__;
18414  callback.Run(response_code, UINT32(), TPM2B_ECC_POINT(), UINT16());
18415}
18416
18417void EC_EphemeralResponseParser(const Tpm::EC_EphemeralResponse& callback,
18418                                AuthorizationDelegate* authorization_delegate,
18419                                const std::string& response) {
18420  VLOG(1) << __func__;
18421  base::Callback<void(TPM_RC)> error_reporter =
18422      base::Bind(EC_EphemeralErrorCallback, callback);
18423  UINT32 param_size_out;
18424  TPM2B_ECC_POINT q;
18425  UINT16 counter;
18426  TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral(response, &param_size_out, &q,
18427                                              &counter, authorization_delegate);
18428  if (rc != TPM_RC_SUCCESS) {
18429    error_reporter.Run(rc);
18430    return;
18431  }
18432  callback.Run(rc, param_size_out, q, counter);
18433}
18434
18435void Tpm::EC_Ephemeral(const UINT32& param_size,
18436                       const TPMI_ECC_CURVE& curve_id,
18437                       AuthorizationDelegate* authorization_delegate,
18438                       const EC_EphemeralResponse& callback) {
18439  VLOG(1) << __func__;
18440  base::Callback<void(TPM_RC)> error_reporter =
18441      base::Bind(EC_EphemeralErrorCallback, callback);
18442  base::Callback<void(const std::string&)> parser =
18443      base::Bind(EC_EphemeralResponseParser, callback, authorization_delegate);
18444  std::string command;
18445  TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18446                                            authorization_delegate);
18447  if (rc != TPM_RC_SUCCESS) {
18448    error_reporter.Run(rc);
18449    return;
18450  }
18451  transceiver_->SendCommand(command, parser);
18452}
18453
18454TPM_RC Tpm::EC_EphemeralSync(const UINT32& param_size,
18455                             const TPMI_ECC_CURVE& curve_id,
18456                             UINT32* param_size_out,
18457                             TPM2B_ECC_POINT* q,
18458                             UINT16* counter,
18459                             AuthorizationDelegate* authorization_delegate) {
18460  VLOG(1) << __func__;
18461  std::string command;
18462  TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18463                                            authorization_delegate);
18464  if (rc != TPM_RC_SUCCESS) {
18465    return rc;
18466  }
18467  std::string response = transceiver_->SendCommandAndWait(command);
18468  rc = ParseResponse_EC_Ephemeral(response, param_size_out, q, counter,
18469                                  authorization_delegate);
18470  return rc;
18471}
18472
18473TPM_RC Tpm::SerializeCommand_VerifySignature(
18474    const TPMI_DH_OBJECT& key_handle,
18475    const std::string& key_handle_name,
18476    const TPM2B_DIGEST& digest,
18477    const TPMT_SIGNATURE& signature,
18478    std::string* serialized_command,
18479    AuthorizationDelegate* authorization_delegate) {
18480  VLOG(3) << __func__;
18481  TPM_RC rc = TPM_RC_SUCCESS;
18482  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18483  UINT32 command_size = 10;  // Header size.
18484  std::string handle_section_bytes;
18485  std::string parameter_section_bytes;
18486  TPM_CC command_code = TPM_CC_VerifySignature;
18487  bool is_command_parameter_encryption_possible = true;
18488  bool is_response_parameter_encryption_possible = false;
18489  std::string command_code_bytes;
18490  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18491  if (rc != TPM_RC_SUCCESS) {
18492    return rc;
18493  }
18494  std::string key_handle_bytes;
18495  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18496  if (rc != TPM_RC_SUCCESS) {
18497    return rc;
18498  }
18499  std::string digest_bytes;
18500  rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18501  if (rc != TPM_RC_SUCCESS) {
18502    return rc;
18503  }
18504  std::string signature_bytes;
18505  rc = Serialize_TPMT_SIGNATURE(signature, &signature_bytes);
18506  if (rc != TPM_RC_SUCCESS) {
18507    return rc;
18508  }
18509  if (authorization_delegate) {
18510    // Encrypt just the parameter data, not the size.
18511    std::string tmp = digest_bytes.substr(2);
18512    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18513      return TRUNKS_RC_ENCRYPTION_FAILED;
18514    }
18515    digest_bytes.replace(2, std::string::npos, tmp);
18516  }
18517  std::unique_ptr<crypto::SecureHash> hash(
18518      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18519  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18520  hash->Update(key_handle_name.data(), key_handle_name.size());
18521  handle_section_bytes += key_handle_bytes;
18522  command_size += key_handle_bytes.size();
18523  hash->Update(digest_bytes.data(), digest_bytes.size());
18524  parameter_section_bytes += digest_bytes;
18525  command_size += digest_bytes.size();
18526  hash->Update(signature_bytes.data(), signature_bytes.size());
18527  parameter_section_bytes += signature_bytes;
18528  command_size += signature_bytes.size();
18529  std::string command_hash(32, 0);
18530  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
18531  std::string authorization_section_bytes;
18532  std::string authorization_size_bytes;
18533  if (authorization_delegate) {
18534    if (!authorization_delegate->GetCommandAuthorization(
18535            command_hash, is_command_parameter_encryption_possible,
18536            is_response_parameter_encryption_possible,
18537            &authorization_section_bytes)) {
18538      return TRUNKS_RC_AUTHORIZATION_FAILED;
18539    }
18540    if (!authorization_section_bytes.empty()) {
18541      tag = TPM_ST_SESSIONS;
18542      std::string tmp;
18543      rc = Serialize_UINT32(authorization_section_bytes.size(),
18544                            &authorization_size_bytes);
18545      if (rc != TPM_RC_SUCCESS) {
18546        return rc;
18547      }
18548      command_size +=
18549          authorization_size_bytes.size() + authorization_section_bytes.size();
18550    }
18551  }
18552  std::string tag_bytes;
18553  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18554  if (rc != TPM_RC_SUCCESS) {
18555    return rc;
18556  }
18557  std::string command_size_bytes;
18558  rc = Serialize_UINT32(command_size, &command_size_bytes);
18559  if (rc != TPM_RC_SUCCESS) {
18560    return rc;
18561  }
18562  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18563                        handle_section_bytes + authorization_size_bytes +
18564                        authorization_section_bytes + parameter_section_bytes;
18565  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18566  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
18567                                            serialized_command->size());
18568  return TPM_RC_SUCCESS;
18569}
18570
18571TPM_RC Tpm::ParseResponse_VerifySignature(
18572    const std::string& response,
18573    TPMT_TK_VERIFIED* validation,
18574    AuthorizationDelegate* authorization_delegate) {
18575  VLOG(3) << __func__;
18576  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18577  TPM_RC rc = TPM_RC_SUCCESS;
18578  std::string buffer(response);
18579  TPM_ST tag;
18580  std::string tag_bytes;
18581  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18582  if (rc != TPM_RC_SUCCESS) {
18583    return rc;
18584  }
18585  UINT32 response_size;
18586  std::string response_size_bytes;
18587  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18588  if (rc != TPM_RC_SUCCESS) {
18589    return rc;
18590  }
18591  TPM_RC response_code;
18592  std::string response_code_bytes;
18593  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18594  if (rc != TPM_RC_SUCCESS) {
18595    return rc;
18596  }
18597  if (response_size != response.size()) {
18598    return TPM_RC_SIZE;
18599  }
18600  if (response_code != TPM_RC_SUCCESS) {
18601    return response_code;
18602  }
18603  TPM_CC command_code = TPM_CC_VerifySignature;
18604  std::string command_code_bytes;
18605  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18606  if (rc != TPM_RC_SUCCESS) {
18607    return rc;
18608  }
18609  std::string authorization_section_bytes;
18610  if (tag == TPM_ST_SESSIONS) {
18611    UINT32 parameter_section_size = buffer.size();
18612    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18613    if (rc != TPM_RC_SUCCESS) {
18614      return rc;
18615    }
18616    if (parameter_section_size > buffer.size()) {
18617      return TPM_RC_INSUFFICIENT;
18618    }
18619    authorization_section_bytes = buffer.substr(parameter_section_size);
18620    // Keep the parameter section in |buffer|.
18621    buffer.erase(parameter_section_size);
18622  }
18623  std::unique_ptr<crypto::SecureHash> hash(
18624      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18625  hash->Update(response_code_bytes.data(), response_code_bytes.size());
18626  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18627  hash->Update(buffer.data(), buffer.size());
18628  std::string response_hash(32, 0);
18629  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
18630  if (tag == TPM_ST_SESSIONS) {
18631    CHECK(authorization_delegate) << "Authorization delegate missing!";
18632    if (!authorization_delegate->CheckResponseAuthorization(
18633            response_hash, authorization_section_bytes)) {
18634      return TRUNKS_RC_AUTHORIZATION_FAILED;
18635    }
18636  }
18637  std::string validation_bytes;
18638  rc = Parse_TPMT_TK_VERIFIED(&buffer, validation, &validation_bytes);
18639  if (rc != TPM_RC_SUCCESS) {
18640    return rc;
18641  }
18642  return TPM_RC_SUCCESS;
18643}
18644
18645void VerifySignatureErrorCallback(const Tpm::VerifySignatureResponse& callback,
18646                                  TPM_RC response_code) {
18647  VLOG(1) << __func__;
18648  callback.Run(response_code, TPMT_TK_VERIFIED());
18649}
18650
18651void VerifySignatureResponseParser(
18652    const Tpm::VerifySignatureResponse& callback,
18653    AuthorizationDelegate* authorization_delegate,
18654    const std::string& response) {
18655  VLOG(1) << __func__;
18656  base::Callback<void(TPM_RC)> error_reporter =
18657      base::Bind(VerifySignatureErrorCallback, callback);
18658  TPMT_TK_VERIFIED validation;
18659  TPM_RC rc = Tpm::ParseResponse_VerifySignature(response, &validation,
18660                                                 authorization_delegate);
18661  if (rc != TPM_RC_SUCCESS) {
18662    error_reporter.Run(rc);
18663    return;
18664  }
18665  callback.Run(rc, validation);
18666}
18667
18668void Tpm::VerifySignature(const TPMI_DH_OBJECT& key_handle,
18669                          const std::string& key_handle_name,
18670                          const TPM2B_DIGEST& digest,
18671                          const TPMT_SIGNATURE& signature,
18672                          AuthorizationDelegate* authorization_delegate,
18673                          const VerifySignatureResponse& callback) {
18674  VLOG(1) << __func__;
18675  base::Callback<void(TPM_RC)> error_reporter =
18676      base::Bind(VerifySignatureErrorCallback, callback);
18677  base::Callback<void(const std::string&)> parser = base::Bind(
18678      VerifySignatureResponseParser, callback, authorization_delegate);
18679  std::string command;
18680  TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18681                                               digest, signature, &command,
18682                                               authorization_delegate);
18683  if (rc != TPM_RC_SUCCESS) {
18684    error_reporter.Run(rc);
18685    return;
18686  }
18687  transceiver_->SendCommand(command, parser);
18688}
18689
18690TPM_RC Tpm::VerifySignatureSync(const TPMI_DH_OBJECT& key_handle,
18691                                const std::string& key_handle_name,
18692                                const TPM2B_DIGEST& digest,
18693                                const TPMT_SIGNATURE& signature,
18694                                TPMT_TK_VERIFIED* validation,
18695                                AuthorizationDelegate* authorization_delegate) {
18696  VLOG(1) << __func__;
18697  std::string command;
18698  TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18699                                               digest, signature, &command,
18700                                               authorization_delegate);
18701  if (rc != TPM_RC_SUCCESS) {
18702    return rc;
18703  }
18704  std::string response = transceiver_->SendCommandAndWait(command);
18705  rc = ParseResponse_VerifySignature(response, validation,
18706                                     authorization_delegate);
18707  return rc;
18708}
18709
18710TPM_RC Tpm::SerializeCommand_Sign(
18711    const TPMI_DH_OBJECT& key_handle,
18712    const std::string& key_handle_name,
18713    const TPM2B_DIGEST& digest,
18714    const TPMT_SIG_SCHEME& in_scheme,
18715    const TPMT_TK_HASHCHECK& validation,
18716    std::string* serialized_command,
18717    AuthorizationDelegate* authorization_delegate) {
18718  VLOG(3) << __func__;
18719  TPM_RC rc = TPM_RC_SUCCESS;
18720  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18721  UINT32 command_size = 10;  // Header size.
18722  std::string handle_section_bytes;
18723  std::string parameter_section_bytes;
18724  TPM_CC command_code = TPM_CC_Sign;
18725  bool is_command_parameter_encryption_possible = true;
18726  bool is_response_parameter_encryption_possible = false;
18727  std::string command_code_bytes;
18728  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18729  if (rc != TPM_RC_SUCCESS) {
18730    return rc;
18731  }
18732  std::string key_handle_bytes;
18733  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18734  if (rc != TPM_RC_SUCCESS) {
18735    return rc;
18736  }
18737  std::string digest_bytes;
18738  rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18739  if (rc != TPM_RC_SUCCESS) {
18740    return rc;
18741  }
18742  std::string in_scheme_bytes;
18743  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
18744  if (rc != TPM_RC_SUCCESS) {
18745    return rc;
18746  }
18747  std::string validation_bytes;
18748  rc = Serialize_TPMT_TK_HASHCHECK(validation, &validation_bytes);
18749  if (rc != TPM_RC_SUCCESS) {
18750    return rc;
18751  }
18752  if (authorization_delegate) {
18753    // Encrypt just the parameter data, not the size.
18754    std::string tmp = digest_bytes.substr(2);
18755    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18756      return TRUNKS_RC_ENCRYPTION_FAILED;
18757    }
18758    digest_bytes.replace(2, std::string::npos, tmp);
18759  }
18760  std::unique_ptr<crypto::SecureHash> hash(
18761      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18762  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18763  hash->Update(key_handle_name.data(), key_handle_name.size());
18764  handle_section_bytes += key_handle_bytes;
18765  command_size += key_handle_bytes.size();
18766  hash->Update(digest_bytes.data(), digest_bytes.size());
18767  parameter_section_bytes += digest_bytes;
18768  command_size += digest_bytes.size();
18769  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
18770  parameter_section_bytes += in_scheme_bytes;
18771  command_size += in_scheme_bytes.size();
18772  hash->Update(validation_bytes.data(), validation_bytes.size());
18773  parameter_section_bytes += validation_bytes;
18774  command_size += validation_bytes.size();
18775  std::string command_hash(32, 0);
18776  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
18777  std::string authorization_section_bytes;
18778  std::string authorization_size_bytes;
18779  if (authorization_delegate) {
18780    if (!authorization_delegate->GetCommandAuthorization(
18781            command_hash, is_command_parameter_encryption_possible,
18782            is_response_parameter_encryption_possible,
18783            &authorization_section_bytes)) {
18784      return TRUNKS_RC_AUTHORIZATION_FAILED;
18785    }
18786    if (!authorization_section_bytes.empty()) {
18787      tag = TPM_ST_SESSIONS;
18788      std::string tmp;
18789      rc = Serialize_UINT32(authorization_section_bytes.size(),
18790                            &authorization_size_bytes);
18791      if (rc != TPM_RC_SUCCESS) {
18792        return rc;
18793      }
18794      command_size +=
18795          authorization_size_bytes.size() + authorization_section_bytes.size();
18796    }
18797  }
18798  std::string tag_bytes;
18799  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18800  if (rc != TPM_RC_SUCCESS) {
18801    return rc;
18802  }
18803  std::string command_size_bytes;
18804  rc = Serialize_UINT32(command_size, &command_size_bytes);
18805  if (rc != TPM_RC_SUCCESS) {
18806    return rc;
18807  }
18808  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18809                        handle_section_bytes + authorization_size_bytes +
18810                        authorization_section_bytes + parameter_section_bytes;
18811  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18812  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
18813                                            serialized_command->size());
18814  return TPM_RC_SUCCESS;
18815}
18816
18817TPM_RC Tpm::ParseResponse_Sign(const std::string& response,
18818                               TPMT_SIGNATURE* signature,
18819                               AuthorizationDelegate* authorization_delegate) {
18820  VLOG(3) << __func__;
18821  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18822  TPM_RC rc = TPM_RC_SUCCESS;
18823  std::string buffer(response);
18824  TPM_ST tag;
18825  std::string tag_bytes;
18826  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18827  if (rc != TPM_RC_SUCCESS) {
18828    return rc;
18829  }
18830  UINT32 response_size;
18831  std::string response_size_bytes;
18832  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18833  if (rc != TPM_RC_SUCCESS) {
18834    return rc;
18835  }
18836  TPM_RC response_code;
18837  std::string response_code_bytes;
18838  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18839  if (rc != TPM_RC_SUCCESS) {
18840    return rc;
18841  }
18842  if (response_size != response.size()) {
18843    return TPM_RC_SIZE;
18844  }
18845  if (response_code != TPM_RC_SUCCESS) {
18846    return response_code;
18847  }
18848  TPM_CC command_code = TPM_CC_Sign;
18849  std::string command_code_bytes;
18850  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18851  if (rc != TPM_RC_SUCCESS) {
18852    return rc;
18853  }
18854  std::string authorization_section_bytes;
18855  if (tag == TPM_ST_SESSIONS) {
18856    UINT32 parameter_section_size = buffer.size();
18857    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18858    if (rc != TPM_RC_SUCCESS) {
18859      return rc;
18860    }
18861    if (parameter_section_size > buffer.size()) {
18862      return TPM_RC_INSUFFICIENT;
18863    }
18864    authorization_section_bytes = buffer.substr(parameter_section_size);
18865    // Keep the parameter section in |buffer|.
18866    buffer.erase(parameter_section_size);
18867  }
18868  std::unique_ptr<crypto::SecureHash> hash(
18869      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18870  hash->Update(response_code_bytes.data(), response_code_bytes.size());
18871  hash->Update(command_code_bytes.data(), command_code_bytes.size());
18872  hash->Update(buffer.data(), buffer.size());
18873  std::string response_hash(32, 0);
18874  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
18875  if (tag == TPM_ST_SESSIONS) {
18876    CHECK(authorization_delegate) << "Authorization delegate missing!";
18877    if (!authorization_delegate->CheckResponseAuthorization(
18878            response_hash, authorization_section_bytes)) {
18879      return TRUNKS_RC_AUTHORIZATION_FAILED;
18880    }
18881  }
18882  std::string signature_bytes;
18883  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
18884  if (rc != TPM_RC_SUCCESS) {
18885    return rc;
18886  }
18887  return TPM_RC_SUCCESS;
18888}
18889
18890void SignErrorCallback(const Tpm::SignResponse& callback,
18891                       TPM_RC response_code) {
18892  VLOG(1) << __func__;
18893  callback.Run(response_code, TPMT_SIGNATURE());
18894}
18895
18896void SignResponseParser(const Tpm::SignResponse& callback,
18897                        AuthorizationDelegate* authorization_delegate,
18898                        const std::string& response) {
18899  VLOG(1) << __func__;
18900  base::Callback<void(TPM_RC)> error_reporter =
18901      base::Bind(SignErrorCallback, callback);
18902  TPMT_SIGNATURE signature;
18903  TPM_RC rc =
18904      Tpm::ParseResponse_Sign(response, &signature, authorization_delegate);
18905  if (rc != TPM_RC_SUCCESS) {
18906    error_reporter.Run(rc);
18907    return;
18908  }
18909  callback.Run(rc, signature);
18910}
18911
18912void Tpm::Sign(const TPMI_DH_OBJECT& key_handle,
18913               const std::string& key_handle_name,
18914               const TPM2B_DIGEST& digest,
18915               const TPMT_SIG_SCHEME& in_scheme,
18916               const TPMT_TK_HASHCHECK& validation,
18917               AuthorizationDelegate* authorization_delegate,
18918               const SignResponse& callback) {
18919  VLOG(1) << __func__;
18920  base::Callback<void(TPM_RC)> error_reporter =
18921      base::Bind(SignErrorCallback, callback);
18922  base::Callback<void(const std::string&)> parser =
18923      base::Bind(SignResponseParser, callback, authorization_delegate);
18924  std::string command;
18925  TPM_RC rc =
18926      SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
18927                            validation, &command, authorization_delegate);
18928  if (rc != TPM_RC_SUCCESS) {
18929    error_reporter.Run(rc);
18930    return;
18931  }
18932  transceiver_->SendCommand(command, parser);
18933}
18934
18935TPM_RC Tpm::SignSync(const TPMI_DH_OBJECT& key_handle,
18936                     const std::string& key_handle_name,
18937                     const TPM2B_DIGEST& digest,
18938                     const TPMT_SIG_SCHEME& in_scheme,
18939                     const TPMT_TK_HASHCHECK& validation,
18940                     TPMT_SIGNATURE* signature,
18941                     AuthorizationDelegate* authorization_delegate) {
18942  VLOG(1) << __func__;
18943  std::string command;
18944  TPM_RC rc =
18945      SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
18946                            validation, &command, authorization_delegate);
18947  if (rc != TPM_RC_SUCCESS) {
18948    return rc;
18949  }
18950  std::string response = transceiver_->SendCommandAndWait(command);
18951  rc = ParseResponse_Sign(response, signature, authorization_delegate);
18952  return rc;
18953}
18954
18955TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus(
18956    const TPMI_RH_PROVISION& auth,
18957    const std::string& auth_name,
18958    const TPMI_ALG_HASH& audit_alg,
18959    const TPML_CC& set_list,
18960    const TPML_CC& clear_list,
18961    std::string* serialized_command,
18962    AuthorizationDelegate* authorization_delegate) {
18963  VLOG(3) << __func__;
18964  TPM_RC rc = TPM_RC_SUCCESS;
18965  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18966  UINT32 command_size = 10;  // Header size.
18967  std::string handle_section_bytes;
18968  std::string parameter_section_bytes;
18969  TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
18970  bool is_command_parameter_encryption_possible = false;
18971  bool is_response_parameter_encryption_possible = false;
18972  std::string command_code_bytes;
18973  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18974  if (rc != TPM_RC_SUCCESS) {
18975    return rc;
18976  }
18977  std::string auth_bytes;
18978  rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
18979  if (rc != TPM_RC_SUCCESS) {
18980    return rc;
18981  }
18982  std::string audit_alg_bytes;
18983  rc = Serialize_TPMI_ALG_HASH(audit_alg, &audit_alg_bytes);
18984  if (rc != TPM_RC_SUCCESS) {
18985    return rc;
18986  }
18987  std::string set_list_bytes;
18988  rc = Serialize_TPML_CC(set_list, &set_list_bytes);
18989  if (rc != TPM_RC_SUCCESS) {
18990    return rc;
18991  }
18992  std::string clear_list_bytes;
18993  rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
18994  if (rc != TPM_RC_SUCCESS) {
18995    return rc;
18996  }
18997  std::unique_ptr<crypto::SecureHash> hash(
18998      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18999  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19000  hash->Update(auth_name.data(), auth_name.size());
19001  handle_section_bytes += auth_bytes;
19002  command_size += auth_bytes.size();
19003  hash->Update(audit_alg_bytes.data(), audit_alg_bytes.size());
19004  parameter_section_bytes += audit_alg_bytes;
19005  command_size += audit_alg_bytes.size();
19006  hash->Update(set_list_bytes.data(), set_list_bytes.size());
19007  parameter_section_bytes += set_list_bytes;
19008  command_size += set_list_bytes.size();
19009  hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
19010  parameter_section_bytes += clear_list_bytes;
19011  command_size += clear_list_bytes.size();
19012  std::string command_hash(32, 0);
19013  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
19014  std::string authorization_section_bytes;
19015  std::string authorization_size_bytes;
19016  if (authorization_delegate) {
19017    if (!authorization_delegate->GetCommandAuthorization(
19018            command_hash, is_command_parameter_encryption_possible,
19019            is_response_parameter_encryption_possible,
19020            &authorization_section_bytes)) {
19021      return TRUNKS_RC_AUTHORIZATION_FAILED;
19022    }
19023    if (!authorization_section_bytes.empty()) {
19024      tag = TPM_ST_SESSIONS;
19025      std::string tmp;
19026      rc = Serialize_UINT32(authorization_section_bytes.size(),
19027                            &authorization_size_bytes);
19028      if (rc != TPM_RC_SUCCESS) {
19029        return rc;
19030      }
19031      command_size +=
19032          authorization_size_bytes.size() + authorization_section_bytes.size();
19033    }
19034  }
19035  std::string tag_bytes;
19036  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19037  if (rc != TPM_RC_SUCCESS) {
19038    return rc;
19039  }
19040  std::string command_size_bytes;
19041  rc = Serialize_UINT32(command_size, &command_size_bytes);
19042  if (rc != TPM_RC_SUCCESS) {
19043    return rc;
19044  }
19045  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19046                        handle_section_bytes + authorization_size_bytes +
19047                        authorization_section_bytes + parameter_section_bytes;
19048  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19049  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
19050                                            serialized_command->size());
19051  return TPM_RC_SUCCESS;
19052}
19053
19054TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus(
19055    const std::string& response,
19056    AuthorizationDelegate* authorization_delegate) {
19057  VLOG(3) << __func__;
19058  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19059  TPM_RC rc = TPM_RC_SUCCESS;
19060  std::string buffer(response);
19061  TPM_ST tag;
19062  std::string tag_bytes;
19063  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19064  if (rc != TPM_RC_SUCCESS) {
19065    return rc;
19066  }
19067  UINT32 response_size;
19068  std::string response_size_bytes;
19069  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19070  if (rc != TPM_RC_SUCCESS) {
19071    return rc;
19072  }
19073  TPM_RC response_code;
19074  std::string response_code_bytes;
19075  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19076  if (rc != TPM_RC_SUCCESS) {
19077    return rc;
19078  }
19079  if (response_size != response.size()) {
19080    return TPM_RC_SIZE;
19081  }
19082  if (response_code != TPM_RC_SUCCESS) {
19083    return response_code;
19084  }
19085  TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19086  std::string command_code_bytes;
19087  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19088  if (rc != TPM_RC_SUCCESS) {
19089    return rc;
19090  }
19091  std::string authorization_section_bytes;
19092  if (tag == TPM_ST_SESSIONS) {
19093    UINT32 parameter_section_size = buffer.size();
19094    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19095    if (rc != TPM_RC_SUCCESS) {
19096      return rc;
19097    }
19098    if (parameter_section_size > buffer.size()) {
19099      return TPM_RC_INSUFFICIENT;
19100    }
19101    authorization_section_bytes = buffer.substr(parameter_section_size);
19102    // Keep the parameter section in |buffer|.
19103    buffer.erase(parameter_section_size);
19104  }
19105  std::unique_ptr<crypto::SecureHash> hash(
19106      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19107  hash->Update(response_code_bytes.data(), response_code_bytes.size());
19108  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19109  hash->Update(buffer.data(), buffer.size());
19110  std::string response_hash(32, 0);
19111  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
19112  if (tag == TPM_ST_SESSIONS) {
19113    CHECK(authorization_delegate) << "Authorization delegate missing!";
19114    if (!authorization_delegate->CheckResponseAuthorization(
19115            response_hash, authorization_section_bytes)) {
19116      return TRUNKS_RC_AUTHORIZATION_FAILED;
19117    }
19118  }
19119  return TPM_RC_SUCCESS;
19120}
19121
19122void SetCommandCodeAuditStatusErrorCallback(
19123    const Tpm::SetCommandCodeAuditStatusResponse& callback,
19124    TPM_RC response_code) {
19125  VLOG(1) << __func__;
19126  callback.Run(response_code);
19127}
19128
19129void SetCommandCodeAuditStatusResponseParser(
19130    const Tpm::SetCommandCodeAuditStatusResponse& callback,
19131    AuthorizationDelegate* authorization_delegate,
19132    const std::string& response) {
19133  VLOG(1) << __func__;
19134  base::Callback<void(TPM_RC)> error_reporter =
19135      base::Bind(SetCommandCodeAuditStatusErrorCallback, callback);
19136  TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus(
19137      response, authorization_delegate);
19138  if (rc != TPM_RC_SUCCESS) {
19139    error_reporter.Run(rc);
19140    return;
19141  }
19142  callback.Run(rc);
19143}
19144
19145void Tpm::SetCommandCodeAuditStatus(
19146    const TPMI_RH_PROVISION& auth,
19147    const std::string& auth_name,
19148    const TPMI_ALG_HASH& audit_alg,
19149    const TPML_CC& set_list,
19150    const TPML_CC& clear_list,
19151    AuthorizationDelegate* authorization_delegate,
19152    const SetCommandCodeAuditStatusResponse& callback) {
19153  VLOG(1) << __func__;
19154  base::Callback<void(TPM_RC)> error_reporter =
19155      base::Bind(SetCommandCodeAuditStatusErrorCallback, callback);
19156  base::Callback<void(const std::string&)> parser =
19157      base::Bind(SetCommandCodeAuditStatusResponseParser, callback,
19158                 authorization_delegate);
19159  std::string command;
19160  TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19161      auth, auth_name, audit_alg, set_list, clear_list, &command,
19162      authorization_delegate);
19163  if (rc != TPM_RC_SUCCESS) {
19164    error_reporter.Run(rc);
19165    return;
19166  }
19167  transceiver_->SendCommand(command, parser);
19168}
19169
19170TPM_RC Tpm::SetCommandCodeAuditStatusSync(
19171    const TPMI_RH_PROVISION& auth,
19172    const std::string& auth_name,
19173    const TPMI_ALG_HASH& audit_alg,
19174    const TPML_CC& set_list,
19175    const TPML_CC& clear_list,
19176    AuthorizationDelegate* authorization_delegate) {
19177  VLOG(1) << __func__;
19178  std::string command;
19179  TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19180      auth, auth_name, audit_alg, set_list, clear_list, &command,
19181      authorization_delegate);
19182  if (rc != TPM_RC_SUCCESS) {
19183    return rc;
19184  }
19185  std::string response = transceiver_->SendCommandAndWait(command);
19186  rc =
19187      ParseResponse_SetCommandCodeAuditStatus(response, authorization_delegate);
19188  return rc;
19189}
19190
19191TPM_RC Tpm::SerializeCommand_PCR_Extend(
19192    const TPMI_DH_PCR& pcr_handle,
19193    const std::string& pcr_handle_name,
19194    const TPML_DIGEST_VALUES& digests,
19195    std::string* serialized_command,
19196    AuthorizationDelegate* authorization_delegate) {
19197  VLOG(3) << __func__;
19198  TPM_RC rc = TPM_RC_SUCCESS;
19199  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19200  UINT32 command_size = 10;  // Header size.
19201  std::string handle_section_bytes;
19202  std::string parameter_section_bytes;
19203  TPM_CC command_code = TPM_CC_PCR_Extend;
19204  bool is_command_parameter_encryption_possible = false;
19205  bool is_response_parameter_encryption_possible = false;
19206  std::string command_code_bytes;
19207  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19208  if (rc != TPM_RC_SUCCESS) {
19209    return rc;
19210  }
19211  std::string pcr_handle_bytes;
19212  rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19213  if (rc != TPM_RC_SUCCESS) {
19214    return rc;
19215  }
19216  std::string digests_bytes;
19217  rc = Serialize_TPML_DIGEST_VALUES(digests, &digests_bytes);
19218  if (rc != TPM_RC_SUCCESS) {
19219    return rc;
19220  }
19221  std::unique_ptr<crypto::SecureHash> hash(
19222      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19223  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19224  hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19225  handle_section_bytes += pcr_handle_bytes;
19226  command_size += pcr_handle_bytes.size();
19227  hash->Update(digests_bytes.data(), digests_bytes.size());
19228  parameter_section_bytes += digests_bytes;
19229  command_size += digests_bytes.size();
19230  std::string command_hash(32, 0);
19231  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
19232  std::string authorization_section_bytes;
19233  std::string authorization_size_bytes;
19234  if (authorization_delegate) {
19235    if (!authorization_delegate->GetCommandAuthorization(
19236            command_hash, is_command_parameter_encryption_possible,
19237            is_response_parameter_encryption_possible,
19238            &authorization_section_bytes)) {
19239      return TRUNKS_RC_AUTHORIZATION_FAILED;
19240    }
19241    if (!authorization_section_bytes.empty()) {
19242      tag = TPM_ST_SESSIONS;
19243      std::string tmp;
19244      rc = Serialize_UINT32(authorization_section_bytes.size(),
19245                            &authorization_size_bytes);
19246      if (rc != TPM_RC_SUCCESS) {
19247        return rc;
19248      }
19249      command_size +=
19250          authorization_size_bytes.size() + authorization_section_bytes.size();
19251    }
19252  }
19253  std::string tag_bytes;
19254  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19255  if (rc != TPM_RC_SUCCESS) {
19256    return rc;
19257  }
19258  std::string command_size_bytes;
19259  rc = Serialize_UINT32(command_size, &command_size_bytes);
19260  if (rc != TPM_RC_SUCCESS) {
19261    return rc;
19262  }
19263  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19264                        handle_section_bytes + authorization_size_bytes +
19265                        authorization_section_bytes + parameter_section_bytes;
19266  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19267  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
19268                                            serialized_command->size());
19269  return TPM_RC_SUCCESS;
19270}
19271
19272TPM_RC Tpm::ParseResponse_PCR_Extend(
19273    const std::string& response,
19274    AuthorizationDelegate* authorization_delegate) {
19275  VLOG(3) << __func__;
19276  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19277  TPM_RC rc = TPM_RC_SUCCESS;
19278  std::string buffer(response);
19279  TPM_ST tag;
19280  std::string tag_bytes;
19281  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19282  if (rc != TPM_RC_SUCCESS) {
19283    return rc;
19284  }
19285  UINT32 response_size;
19286  std::string response_size_bytes;
19287  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19288  if (rc != TPM_RC_SUCCESS) {
19289    return rc;
19290  }
19291  TPM_RC response_code;
19292  std::string response_code_bytes;
19293  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19294  if (rc != TPM_RC_SUCCESS) {
19295    return rc;
19296  }
19297  if (response_size != response.size()) {
19298    return TPM_RC_SIZE;
19299  }
19300  if (response_code != TPM_RC_SUCCESS) {
19301    return response_code;
19302  }
19303  TPM_CC command_code = TPM_CC_PCR_Extend;
19304  std::string command_code_bytes;
19305  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19306  if (rc != TPM_RC_SUCCESS) {
19307    return rc;
19308  }
19309  std::string authorization_section_bytes;
19310  if (tag == TPM_ST_SESSIONS) {
19311    UINT32 parameter_section_size = buffer.size();
19312    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19313    if (rc != TPM_RC_SUCCESS) {
19314      return rc;
19315    }
19316    if (parameter_section_size > buffer.size()) {
19317      return TPM_RC_INSUFFICIENT;
19318    }
19319    authorization_section_bytes = buffer.substr(parameter_section_size);
19320    // Keep the parameter section in |buffer|.
19321    buffer.erase(parameter_section_size);
19322  }
19323  std::unique_ptr<crypto::SecureHash> hash(
19324      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19325  hash->Update(response_code_bytes.data(), response_code_bytes.size());
19326  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19327  hash->Update(buffer.data(), buffer.size());
19328  std::string response_hash(32, 0);
19329  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
19330  if (tag == TPM_ST_SESSIONS) {
19331    CHECK(authorization_delegate) << "Authorization delegate missing!";
19332    if (!authorization_delegate->CheckResponseAuthorization(
19333            response_hash, authorization_section_bytes)) {
19334      return TRUNKS_RC_AUTHORIZATION_FAILED;
19335    }
19336  }
19337  return TPM_RC_SUCCESS;
19338}
19339
19340void PCR_ExtendErrorCallback(const Tpm::PCR_ExtendResponse& callback,
19341                             TPM_RC response_code) {
19342  VLOG(1) << __func__;
19343  callback.Run(response_code);
19344}
19345
19346void PCR_ExtendResponseParser(const Tpm::PCR_ExtendResponse& callback,
19347                              AuthorizationDelegate* authorization_delegate,
19348                              const std::string& response) {
19349  VLOG(1) << __func__;
19350  base::Callback<void(TPM_RC)> error_reporter =
19351      base::Bind(PCR_ExtendErrorCallback, callback);
19352  TPM_RC rc = Tpm::ParseResponse_PCR_Extend(response, authorization_delegate);
19353  if (rc != TPM_RC_SUCCESS) {
19354    error_reporter.Run(rc);
19355    return;
19356  }
19357  callback.Run(rc);
19358}
19359
19360void Tpm::PCR_Extend(const TPMI_DH_PCR& pcr_handle,
19361                     const std::string& pcr_handle_name,
19362                     const TPML_DIGEST_VALUES& digests,
19363                     AuthorizationDelegate* authorization_delegate,
19364                     const PCR_ExtendResponse& callback) {
19365  VLOG(1) << __func__;
19366  base::Callback<void(TPM_RC)> error_reporter =
19367      base::Bind(PCR_ExtendErrorCallback, callback);
19368  base::Callback<void(const std::string&)> parser =
19369      base::Bind(PCR_ExtendResponseParser, callback, authorization_delegate);
19370  std::string command;
19371  TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19372                                          &command, authorization_delegate);
19373  if (rc != TPM_RC_SUCCESS) {
19374    error_reporter.Run(rc);
19375    return;
19376  }
19377  transceiver_->SendCommand(command, parser);
19378}
19379
19380TPM_RC Tpm::PCR_ExtendSync(const TPMI_DH_PCR& pcr_handle,
19381                           const std::string& pcr_handle_name,
19382                           const TPML_DIGEST_VALUES& digests,
19383                           AuthorizationDelegate* authorization_delegate) {
19384  VLOG(1) << __func__;
19385  std::string command;
19386  TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19387                                          &command, authorization_delegate);
19388  if (rc != TPM_RC_SUCCESS) {
19389    return rc;
19390  }
19391  std::string response = transceiver_->SendCommandAndWait(command);
19392  rc = ParseResponse_PCR_Extend(response, authorization_delegate);
19393  return rc;
19394}
19395
19396TPM_RC Tpm::SerializeCommand_PCR_Event(
19397    const TPMI_DH_PCR& pcr_handle,
19398    const std::string& pcr_handle_name,
19399    const TPM2B_EVENT& event_data,
19400    std::string* serialized_command,
19401    AuthorizationDelegate* authorization_delegate) {
19402  VLOG(3) << __func__;
19403  TPM_RC rc = TPM_RC_SUCCESS;
19404  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19405  UINT32 command_size = 10;  // Header size.
19406  std::string handle_section_bytes;
19407  std::string parameter_section_bytes;
19408  TPM_CC command_code = TPM_CC_PCR_Event;
19409  bool is_command_parameter_encryption_possible = true;
19410  bool is_response_parameter_encryption_possible = false;
19411  std::string command_code_bytes;
19412  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19413  if (rc != TPM_RC_SUCCESS) {
19414    return rc;
19415  }
19416  std::string pcr_handle_bytes;
19417  rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19418  if (rc != TPM_RC_SUCCESS) {
19419    return rc;
19420  }
19421  std::string event_data_bytes;
19422  rc = Serialize_TPM2B_EVENT(event_data, &event_data_bytes);
19423  if (rc != TPM_RC_SUCCESS) {
19424    return rc;
19425  }
19426  if (authorization_delegate) {
19427    // Encrypt just the parameter data, not the size.
19428    std::string tmp = event_data_bytes.substr(2);
19429    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19430      return TRUNKS_RC_ENCRYPTION_FAILED;
19431    }
19432    event_data_bytes.replace(2, std::string::npos, tmp);
19433  }
19434  std::unique_ptr<crypto::SecureHash> hash(
19435      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19436  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19437  hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19438  handle_section_bytes += pcr_handle_bytes;
19439  command_size += pcr_handle_bytes.size();
19440  hash->Update(event_data_bytes.data(), event_data_bytes.size());
19441  parameter_section_bytes += event_data_bytes;
19442  command_size += event_data_bytes.size();
19443  std::string command_hash(32, 0);
19444  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
19445  std::string authorization_section_bytes;
19446  std::string authorization_size_bytes;
19447  if (authorization_delegate) {
19448    if (!authorization_delegate->GetCommandAuthorization(
19449            command_hash, is_command_parameter_encryption_possible,
19450            is_response_parameter_encryption_possible,
19451            &authorization_section_bytes)) {
19452      return TRUNKS_RC_AUTHORIZATION_FAILED;
19453    }
19454    if (!authorization_section_bytes.empty()) {
19455      tag = TPM_ST_SESSIONS;
19456      std::string tmp;
19457      rc = Serialize_UINT32(authorization_section_bytes.size(),
19458                            &authorization_size_bytes);
19459      if (rc != TPM_RC_SUCCESS) {
19460        return rc;
19461      }
19462      command_size +=
19463          authorization_size_bytes.size() + authorization_section_bytes.size();
19464    }
19465  }
19466  std::string tag_bytes;
19467  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19468  if (rc != TPM_RC_SUCCESS) {
19469    return rc;
19470  }
19471  std::string command_size_bytes;
19472  rc = Serialize_UINT32(command_size, &command_size_bytes);
19473  if (rc != TPM_RC_SUCCESS) {
19474    return rc;
19475  }
19476  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19477                        handle_section_bytes + authorization_size_bytes +
19478                        authorization_section_bytes + parameter_section_bytes;
19479  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19480  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
19481                                            serialized_command->size());
19482  return TPM_RC_SUCCESS;
19483}
19484
19485TPM_RC Tpm::ParseResponse_PCR_Event(
19486    const std::string& response,
19487    TPML_DIGEST_VALUES* digests,
19488    AuthorizationDelegate* authorization_delegate) {
19489  VLOG(3) << __func__;
19490  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19491  TPM_RC rc = TPM_RC_SUCCESS;
19492  std::string buffer(response);
19493  TPM_ST tag;
19494  std::string tag_bytes;
19495  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19496  if (rc != TPM_RC_SUCCESS) {
19497    return rc;
19498  }
19499  UINT32 response_size;
19500  std::string response_size_bytes;
19501  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19502  if (rc != TPM_RC_SUCCESS) {
19503    return rc;
19504  }
19505  TPM_RC response_code;
19506  std::string response_code_bytes;
19507  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19508  if (rc != TPM_RC_SUCCESS) {
19509    return rc;
19510  }
19511  if (response_size != response.size()) {
19512    return TPM_RC_SIZE;
19513  }
19514  if (response_code != TPM_RC_SUCCESS) {
19515    return response_code;
19516  }
19517  TPM_CC command_code = TPM_CC_PCR_Event;
19518  std::string command_code_bytes;
19519  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19520  if (rc != TPM_RC_SUCCESS) {
19521    return rc;
19522  }
19523  std::string authorization_section_bytes;
19524  if (tag == TPM_ST_SESSIONS) {
19525    UINT32 parameter_section_size = buffer.size();
19526    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19527    if (rc != TPM_RC_SUCCESS) {
19528      return rc;
19529    }
19530    if (parameter_section_size > buffer.size()) {
19531      return TPM_RC_INSUFFICIENT;
19532    }
19533    authorization_section_bytes = buffer.substr(parameter_section_size);
19534    // Keep the parameter section in |buffer|.
19535    buffer.erase(parameter_section_size);
19536  }
19537  std::unique_ptr<crypto::SecureHash> hash(
19538      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19539  hash->Update(response_code_bytes.data(), response_code_bytes.size());
19540  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19541  hash->Update(buffer.data(), buffer.size());
19542  std::string response_hash(32, 0);
19543  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
19544  if (tag == TPM_ST_SESSIONS) {
19545    CHECK(authorization_delegate) << "Authorization delegate missing!";
19546    if (!authorization_delegate->CheckResponseAuthorization(
19547            response_hash, authorization_section_bytes)) {
19548      return TRUNKS_RC_AUTHORIZATION_FAILED;
19549    }
19550  }
19551  std::string digests_bytes;
19552  rc = Parse_TPML_DIGEST_VALUES(&buffer, digests, &digests_bytes);
19553  if (rc != TPM_RC_SUCCESS) {
19554    return rc;
19555  }
19556  return TPM_RC_SUCCESS;
19557}
19558
19559void PCR_EventErrorCallback(const Tpm::PCR_EventResponse& callback,
19560                            TPM_RC response_code) {
19561  VLOG(1) << __func__;
19562  callback.Run(response_code, TPML_DIGEST_VALUES());
19563}
19564
19565void PCR_EventResponseParser(const Tpm::PCR_EventResponse& callback,
19566                             AuthorizationDelegate* authorization_delegate,
19567                             const std::string& response) {
19568  VLOG(1) << __func__;
19569  base::Callback<void(TPM_RC)> error_reporter =
19570      base::Bind(PCR_EventErrorCallback, callback);
19571  TPML_DIGEST_VALUES digests;
19572  TPM_RC rc =
19573      Tpm::ParseResponse_PCR_Event(response, &digests, authorization_delegate);
19574  if (rc != TPM_RC_SUCCESS) {
19575    error_reporter.Run(rc);
19576    return;
19577  }
19578  callback.Run(rc, digests);
19579}
19580
19581void Tpm::PCR_Event(const TPMI_DH_PCR& pcr_handle,
19582                    const std::string& pcr_handle_name,
19583                    const TPM2B_EVENT& event_data,
19584                    AuthorizationDelegate* authorization_delegate,
19585                    const PCR_EventResponse& callback) {
19586  VLOG(1) << __func__;
19587  base::Callback<void(TPM_RC)> error_reporter =
19588      base::Bind(PCR_EventErrorCallback, callback);
19589  base::Callback<void(const std::string&)> parser =
19590      base::Bind(PCR_EventResponseParser, callback, authorization_delegate);
19591  std::string command;
19592  TPM_RC rc =
19593      SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19594                                 &command, authorization_delegate);
19595  if (rc != TPM_RC_SUCCESS) {
19596    error_reporter.Run(rc);
19597    return;
19598  }
19599  transceiver_->SendCommand(command, parser);
19600}
19601
19602TPM_RC Tpm::PCR_EventSync(const TPMI_DH_PCR& pcr_handle,
19603                          const std::string& pcr_handle_name,
19604                          const TPM2B_EVENT& event_data,
19605                          TPML_DIGEST_VALUES* digests,
19606                          AuthorizationDelegate* authorization_delegate) {
19607  VLOG(1) << __func__;
19608  std::string command;
19609  TPM_RC rc =
19610      SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19611                                 &command, authorization_delegate);
19612  if (rc != TPM_RC_SUCCESS) {
19613    return rc;
19614  }
19615  std::string response = transceiver_->SendCommandAndWait(command);
19616  rc = ParseResponse_PCR_Event(response, digests, authorization_delegate);
19617  return rc;
19618}
19619
19620TPM_RC Tpm::SerializeCommand_PCR_Read(
19621    const TPML_PCR_SELECTION& pcr_selection_in,
19622    std::string* serialized_command,
19623    AuthorizationDelegate* authorization_delegate) {
19624  VLOG(3) << __func__;
19625  TPM_RC rc = TPM_RC_SUCCESS;
19626  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19627  UINT32 command_size = 10;  // Header size.
19628  std::string handle_section_bytes;
19629  std::string parameter_section_bytes;
19630  TPM_CC command_code = TPM_CC_PCR_Read;
19631  bool is_command_parameter_encryption_possible = false;
19632  bool is_response_parameter_encryption_possible = false;
19633  std::string command_code_bytes;
19634  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19635  if (rc != TPM_RC_SUCCESS) {
19636    return rc;
19637  }
19638  std::string pcr_selection_in_bytes;
19639  rc = Serialize_TPML_PCR_SELECTION(pcr_selection_in, &pcr_selection_in_bytes);
19640  if (rc != TPM_RC_SUCCESS) {
19641    return rc;
19642  }
19643  std::unique_ptr<crypto::SecureHash> hash(
19644      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19645  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19646  hash->Update(pcr_selection_in_bytes.data(), pcr_selection_in_bytes.size());
19647  parameter_section_bytes += pcr_selection_in_bytes;
19648  command_size += pcr_selection_in_bytes.size();
19649  std::string command_hash(32, 0);
19650  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
19651  std::string authorization_section_bytes;
19652  std::string authorization_size_bytes;
19653  if (authorization_delegate) {
19654    if (!authorization_delegate->GetCommandAuthorization(
19655            command_hash, is_command_parameter_encryption_possible,
19656            is_response_parameter_encryption_possible,
19657            &authorization_section_bytes)) {
19658      return TRUNKS_RC_AUTHORIZATION_FAILED;
19659    }
19660    if (!authorization_section_bytes.empty()) {
19661      tag = TPM_ST_SESSIONS;
19662      std::string tmp;
19663      rc = Serialize_UINT32(authorization_section_bytes.size(),
19664                            &authorization_size_bytes);
19665      if (rc != TPM_RC_SUCCESS) {
19666        return rc;
19667      }
19668      command_size +=
19669          authorization_size_bytes.size() + authorization_section_bytes.size();
19670    }
19671  }
19672  std::string tag_bytes;
19673  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19674  if (rc != TPM_RC_SUCCESS) {
19675    return rc;
19676  }
19677  std::string command_size_bytes;
19678  rc = Serialize_UINT32(command_size, &command_size_bytes);
19679  if (rc != TPM_RC_SUCCESS) {
19680    return rc;
19681  }
19682  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19683                        handle_section_bytes + authorization_size_bytes +
19684                        authorization_section_bytes + parameter_section_bytes;
19685  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19686  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
19687                                            serialized_command->size());
19688  return TPM_RC_SUCCESS;
19689}
19690
19691TPM_RC Tpm::ParseResponse_PCR_Read(
19692    const std::string& response,
19693    UINT32* pcr_update_counter,
19694    TPML_PCR_SELECTION* pcr_selection_out,
19695    TPML_DIGEST* pcr_values,
19696    AuthorizationDelegate* authorization_delegate) {
19697  VLOG(3) << __func__;
19698  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19699  TPM_RC rc = TPM_RC_SUCCESS;
19700  std::string buffer(response);
19701  TPM_ST tag;
19702  std::string tag_bytes;
19703  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19704  if (rc != TPM_RC_SUCCESS) {
19705    return rc;
19706  }
19707  UINT32 response_size;
19708  std::string response_size_bytes;
19709  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19710  if (rc != TPM_RC_SUCCESS) {
19711    return rc;
19712  }
19713  TPM_RC response_code;
19714  std::string response_code_bytes;
19715  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19716  if (rc != TPM_RC_SUCCESS) {
19717    return rc;
19718  }
19719  if (response_size != response.size()) {
19720    return TPM_RC_SIZE;
19721  }
19722  if (response_code != TPM_RC_SUCCESS) {
19723    return response_code;
19724  }
19725  TPM_CC command_code = TPM_CC_PCR_Read;
19726  std::string command_code_bytes;
19727  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19728  if (rc != TPM_RC_SUCCESS) {
19729    return rc;
19730  }
19731  std::string authorization_section_bytes;
19732  if (tag == TPM_ST_SESSIONS) {
19733    UINT32 parameter_section_size = buffer.size();
19734    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19735    if (rc != TPM_RC_SUCCESS) {
19736      return rc;
19737    }
19738    if (parameter_section_size > buffer.size()) {
19739      return TPM_RC_INSUFFICIENT;
19740    }
19741    authorization_section_bytes = buffer.substr(parameter_section_size);
19742    // Keep the parameter section in |buffer|.
19743    buffer.erase(parameter_section_size);
19744  }
19745  std::unique_ptr<crypto::SecureHash> hash(
19746      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19747  hash->Update(response_code_bytes.data(), response_code_bytes.size());
19748  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19749  hash->Update(buffer.data(), buffer.size());
19750  std::string response_hash(32, 0);
19751  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
19752  if (tag == TPM_ST_SESSIONS) {
19753    CHECK(authorization_delegate) << "Authorization delegate missing!";
19754    if (!authorization_delegate->CheckResponseAuthorization(
19755            response_hash, authorization_section_bytes)) {
19756      return TRUNKS_RC_AUTHORIZATION_FAILED;
19757    }
19758  }
19759  std::string pcr_update_counter_bytes;
19760  rc = Parse_UINT32(&buffer, pcr_update_counter, &pcr_update_counter_bytes);
19761  if (rc != TPM_RC_SUCCESS) {
19762    return rc;
19763  }
19764  std::string pcr_selection_out_bytes;
19765  rc = Parse_TPML_PCR_SELECTION(&buffer, pcr_selection_out,
19766                                &pcr_selection_out_bytes);
19767  if (rc != TPM_RC_SUCCESS) {
19768    return rc;
19769  }
19770  std::string pcr_values_bytes;
19771  rc = Parse_TPML_DIGEST(&buffer, pcr_values, &pcr_values_bytes);
19772  if (rc != TPM_RC_SUCCESS) {
19773    return rc;
19774  }
19775  return TPM_RC_SUCCESS;
19776}
19777
19778void PCR_ReadErrorCallback(const Tpm::PCR_ReadResponse& callback,
19779                           TPM_RC response_code) {
19780  VLOG(1) << __func__;
19781  callback.Run(response_code, UINT32(), TPML_PCR_SELECTION(), TPML_DIGEST());
19782}
19783
19784void PCR_ReadResponseParser(const Tpm::PCR_ReadResponse& callback,
19785                            AuthorizationDelegate* authorization_delegate,
19786                            const std::string& response) {
19787  VLOG(1) << __func__;
19788  base::Callback<void(TPM_RC)> error_reporter =
19789      base::Bind(PCR_ReadErrorCallback, callback);
19790  UINT32 pcr_update_counter;
19791  TPML_PCR_SELECTION pcr_selection_out;
19792  TPML_DIGEST pcr_values;
19793  TPM_RC rc = Tpm::ParseResponse_PCR_Read(response, &pcr_update_counter,
19794                                          &pcr_selection_out, &pcr_values,
19795                                          authorization_delegate);
19796  if (rc != TPM_RC_SUCCESS) {
19797    error_reporter.Run(rc);
19798    return;
19799  }
19800  callback.Run(rc, pcr_update_counter, pcr_selection_out, pcr_values);
19801}
19802
19803void Tpm::PCR_Read(const TPML_PCR_SELECTION& pcr_selection_in,
19804                   AuthorizationDelegate* authorization_delegate,
19805                   const PCR_ReadResponse& callback) {
19806  VLOG(1) << __func__;
19807  base::Callback<void(TPM_RC)> error_reporter =
19808      base::Bind(PCR_ReadErrorCallback, callback);
19809  base::Callback<void(const std::string&)> parser =
19810      base::Bind(PCR_ReadResponseParser, callback, authorization_delegate);
19811  std::string command;
19812  TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
19813                                        authorization_delegate);
19814  if (rc != TPM_RC_SUCCESS) {
19815    error_reporter.Run(rc);
19816    return;
19817  }
19818  transceiver_->SendCommand(command, parser);
19819}
19820
19821TPM_RC Tpm::PCR_ReadSync(const TPML_PCR_SELECTION& pcr_selection_in,
19822                         UINT32* pcr_update_counter,
19823                         TPML_PCR_SELECTION* pcr_selection_out,
19824                         TPML_DIGEST* pcr_values,
19825                         AuthorizationDelegate* authorization_delegate) {
19826  VLOG(1) << __func__;
19827  std::string command;
19828  TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
19829                                        authorization_delegate);
19830  if (rc != TPM_RC_SUCCESS) {
19831    return rc;
19832  }
19833  std::string response = transceiver_->SendCommandAndWait(command);
19834  rc = ParseResponse_PCR_Read(response, pcr_update_counter, pcr_selection_out,
19835                              pcr_values, authorization_delegate);
19836  return rc;
19837}
19838
19839TPM_RC Tpm::SerializeCommand_PCR_Allocate(
19840    const TPMI_RH_PLATFORM& auth_handle,
19841    const std::string& auth_handle_name,
19842    const TPML_PCR_SELECTION& pcr_allocation,
19843    std::string* serialized_command,
19844    AuthorizationDelegate* authorization_delegate) {
19845  VLOG(3) << __func__;
19846  TPM_RC rc = TPM_RC_SUCCESS;
19847  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19848  UINT32 command_size = 10;  // Header size.
19849  std::string handle_section_bytes;
19850  std::string parameter_section_bytes;
19851  TPM_CC command_code = TPM_CC_PCR_Allocate;
19852  bool is_command_parameter_encryption_possible = false;
19853  bool is_response_parameter_encryption_possible = false;
19854  std::string command_code_bytes;
19855  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19856  if (rc != TPM_RC_SUCCESS) {
19857    return rc;
19858  }
19859  std::string auth_handle_bytes;
19860  rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
19861  if (rc != TPM_RC_SUCCESS) {
19862    return rc;
19863  }
19864  std::string pcr_allocation_bytes;
19865  rc = Serialize_TPML_PCR_SELECTION(pcr_allocation, &pcr_allocation_bytes);
19866  if (rc != TPM_RC_SUCCESS) {
19867    return rc;
19868  }
19869  std::unique_ptr<crypto::SecureHash> hash(
19870      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19871  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19872  hash->Update(auth_handle_name.data(), auth_handle_name.size());
19873  handle_section_bytes += auth_handle_bytes;
19874  command_size += auth_handle_bytes.size();
19875  hash->Update(pcr_allocation_bytes.data(), pcr_allocation_bytes.size());
19876  parameter_section_bytes += pcr_allocation_bytes;
19877  command_size += pcr_allocation_bytes.size();
19878  std::string command_hash(32, 0);
19879  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
19880  std::string authorization_section_bytes;
19881  std::string authorization_size_bytes;
19882  if (authorization_delegate) {
19883    if (!authorization_delegate->GetCommandAuthorization(
19884            command_hash, is_command_parameter_encryption_possible,
19885            is_response_parameter_encryption_possible,
19886            &authorization_section_bytes)) {
19887      return TRUNKS_RC_AUTHORIZATION_FAILED;
19888    }
19889    if (!authorization_section_bytes.empty()) {
19890      tag = TPM_ST_SESSIONS;
19891      std::string tmp;
19892      rc = Serialize_UINT32(authorization_section_bytes.size(),
19893                            &authorization_size_bytes);
19894      if (rc != TPM_RC_SUCCESS) {
19895        return rc;
19896      }
19897      command_size +=
19898          authorization_size_bytes.size() + authorization_section_bytes.size();
19899    }
19900  }
19901  std::string tag_bytes;
19902  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19903  if (rc != TPM_RC_SUCCESS) {
19904    return rc;
19905  }
19906  std::string command_size_bytes;
19907  rc = Serialize_UINT32(command_size, &command_size_bytes);
19908  if (rc != TPM_RC_SUCCESS) {
19909    return rc;
19910  }
19911  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19912                        handle_section_bytes + authorization_size_bytes +
19913                        authorization_section_bytes + parameter_section_bytes;
19914  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19915  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
19916                                            serialized_command->size());
19917  return TPM_RC_SUCCESS;
19918}
19919
19920TPM_RC Tpm::ParseResponse_PCR_Allocate(
19921    const std::string& response,
19922    TPMI_YES_NO* allocation_success,
19923    UINT32* max_pcr,
19924    UINT32* size_needed,
19925    UINT32* size_available,
19926    AuthorizationDelegate* authorization_delegate) {
19927  VLOG(3) << __func__;
19928  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19929  TPM_RC rc = TPM_RC_SUCCESS;
19930  std::string buffer(response);
19931  TPM_ST tag;
19932  std::string tag_bytes;
19933  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19934  if (rc != TPM_RC_SUCCESS) {
19935    return rc;
19936  }
19937  UINT32 response_size;
19938  std::string response_size_bytes;
19939  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19940  if (rc != TPM_RC_SUCCESS) {
19941    return rc;
19942  }
19943  TPM_RC response_code;
19944  std::string response_code_bytes;
19945  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19946  if (rc != TPM_RC_SUCCESS) {
19947    return rc;
19948  }
19949  if (response_size != response.size()) {
19950    return TPM_RC_SIZE;
19951  }
19952  if (response_code != TPM_RC_SUCCESS) {
19953    return response_code;
19954  }
19955  TPM_CC command_code = TPM_CC_PCR_Allocate;
19956  std::string command_code_bytes;
19957  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19958  if (rc != TPM_RC_SUCCESS) {
19959    return rc;
19960  }
19961  std::string authorization_section_bytes;
19962  if (tag == TPM_ST_SESSIONS) {
19963    UINT32 parameter_section_size = buffer.size();
19964    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19965    if (rc != TPM_RC_SUCCESS) {
19966      return rc;
19967    }
19968    if (parameter_section_size > buffer.size()) {
19969      return TPM_RC_INSUFFICIENT;
19970    }
19971    authorization_section_bytes = buffer.substr(parameter_section_size);
19972    // Keep the parameter section in |buffer|.
19973    buffer.erase(parameter_section_size);
19974  }
19975  std::unique_ptr<crypto::SecureHash> hash(
19976      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19977  hash->Update(response_code_bytes.data(), response_code_bytes.size());
19978  hash->Update(command_code_bytes.data(), command_code_bytes.size());
19979  hash->Update(buffer.data(), buffer.size());
19980  std::string response_hash(32, 0);
19981  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
19982  if (tag == TPM_ST_SESSIONS) {
19983    CHECK(authorization_delegate) << "Authorization delegate missing!";
19984    if (!authorization_delegate->CheckResponseAuthorization(
19985            response_hash, authorization_section_bytes)) {
19986      return TRUNKS_RC_AUTHORIZATION_FAILED;
19987    }
19988  }
19989  std::string allocation_success_bytes;
19990  rc =
19991      Parse_TPMI_YES_NO(&buffer, allocation_success, &allocation_success_bytes);
19992  if (rc != TPM_RC_SUCCESS) {
19993    return rc;
19994  }
19995  std::string max_pcr_bytes;
19996  rc = Parse_UINT32(&buffer, max_pcr, &max_pcr_bytes);
19997  if (rc != TPM_RC_SUCCESS) {
19998    return rc;
19999  }
20000  std::string size_needed_bytes;
20001  rc = Parse_UINT32(&buffer, size_needed, &size_needed_bytes);
20002  if (rc != TPM_RC_SUCCESS) {
20003    return rc;
20004  }
20005  std::string size_available_bytes;
20006  rc = Parse_UINT32(&buffer, size_available, &size_available_bytes);
20007  if (rc != TPM_RC_SUCCESS) {
20008    return rc;
20009  }
20010  return TPM_RC_SUCCESS;
20011}
20012
20013void PCR_AllocateErrorCallback(const Tpm::PCR_AllocateResponse& callback,
20014                               TPM_RC response_code) {
20015  VLOG(1) << __func__;
20016  callback.Run(response_code, TPMI_YES_NO(), UINT32(), UINT32(), UINT32());
20017}
20018
20019void PCR_AllocateResponseParser(const Tpm::PCR_AllocateResponse& callback,
20020                                AuthorizationDelegate* authorization_delegate,
20021                                const std::string& response) {
20022  VLOG(1) << __func__;
20023  base::Callback<void(TPM_RC)> error_reporter =
20024      base::Bind(PCR_AllocateErrorCallback, callback);
20025  TPMI_YES_NO allocation_success;
20026  UINT32 max_pcr;
20027  UINT32 size_needed;
20028  UINT32 size_available;
20029  TPM_RC rc = Tpm::ParseResponse_PCR_Allocate(
20030      response, &allocation_success, &max_pcr, &size_needed, &size_available,
20031      authorization_delegate);
20032  if (rc != TPM_RC_SUCCESS) {
20033    error_reporter.Run(rc);
20034    return;
20035  }
20036  callback.Run(rc, allocation_success, max_pcr, size_needed, size_available);
20037}
20038
20039void Tpm::PCR_Allocate(const TPMI_RH_PLATFORM& auth_handle,
20040                       const std::string& auth_handle_name,
20041                       const TPML_PCR_SELECTION& pcr_allocation,
20042                       AuthorizationDelegate* authorization_delegate,
20043                       const PCR_AllocateResponse& callback) {
20044  VLOG(1) << __func__;
20045  base::Callback<void(TPM_RC)> error_reporter =
20046      base::Bind(PCR_AllocateErrorCallback, callback);
20047  base::Callback<void(const std::string&)> parser =
20048      base::Bind(PCR_AllocateResponseParser, callback, authorization_delegate);
20049  std::string command;
20050  TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20051                                            pcr_allocation, &command,
20052                                            authorization_delegate);
20053  if (rc != TPM_RC_SUCCESS) {
20054    error_reporter.Run(rc);
20055    return;
20056  }
20057  transceiver_->SendCommand(command, parser);
20058}
20059
20060TPM_RC Tpm::PCR_AllocateSync(const TPMI_RH_PLATFORM& auth_handle,
20061                             const std::string& auth_handle_name,
20062                             const TPML_PCR_SELECTION& pcr_allocation,
20063                             TPMI_YES_NO* allocation_success,
20064                             UINT32* max_pcr,
20065                             UINT32* size_needed,
20066                             UINT32* size_available,
20067                             AuthorizationDelegate* authorization_delegate) {
20068  VLOG(1) << __func__;
20069  std::string command;
20070  TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20071                                            pcr_allocation, &command,
20072                                            authorization_delegate);
20073  if (rc != TPM_RC_SUCCESS) {
20074    return rc;
20075  }
20076  std::string response = transceiver_->SendCommandAndWait(command);
20077  rc = ParseResponse_PCR_Allocate(response, allocation_success, max_pcr,
20078                                  size_needed, size_available,
20079                                  authorization_delegate);
20080  return rc;
20081}
20082
20083TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy(
20084    const TPMI_RH_PLATFORM& auth_handle,
20085    const std::string& auth_handle_name,
20086    const TPMI_DH_PCR& pcr_num,
20087    const std::string& pcr_num_name,
20088    const TPM2B_DIGEST& auth_policy,
20089    const TPMI_ALG_HASH& policy_digest,
20090    std::string* serialized_command,
20091    AuthorizationDelegate* authorization_delegate) {
20092  VLOG(3) << __func__;
20093  TPM_RC rc = TPM_RC_SUCCESS;
20094  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20095  UINT32 command_size = 10;  // Header size.
20096  std::string handle_section_bytes;
20097  std::string parameter_section_bytes;
20098  TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20099  bool is_command_parameter_encryption_possible = true;
20100  bool is_response_parameter_encryption_possible = false;
20101  std::string command_code_bytes;
20102  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20103  if (rc != TPM_RC_SUCCESS) {
20104    return rc;
20105  }
20106  std::string auth_handle_bytes;
20107  rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20108  if (rc != TPM_RC_SUCCESS) {
20109    return rc;
20110  }
20111  std::string auth_policy_bytes;
20112  rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
20113  if (rc != TPM_RC_SUCCESS) {
20114    return rc;
20115  }
20116  std::string policy_digest_bytes;
20117  rc = Serialize_TPMI_ALG_HASH(policy_digest, &policy_digest_bytes);
20118  if (rc != TPM_RC_SUCCESS) {
20119    return rc;
20120  }
20121  std::string pcr_num_bytes;
20122  rc = Serialize_TPMI_DH_PCR(pcr_num, &pcr_num_bytes);
20123  if (rc != TPM_RC_SUCCESS) {
20124    return rc;
20125  }
20126  if (authorization_delegate) {
20127    // Encrypt just the parameter data, not the size.
20128    std::string tmp = auth_policy_bytes.substr(2);
20129    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20130      return TRUNKS_RC_ENCRYPTION_FAILED;
20131    }
20132    auth_policy_bytes.replace(2, std::string::npos, tmp);
20133  }
20134  std::unique_ptr<crypto::SecureHash> hash(
20135      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20136  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20137  hash->Update(auth_handle_name.data(), auth_handle_name.size());
20138  handle_section_bytes += auth_handle_bytes;
20139  command_size += auth_handle_bytes.size();
20140  hash->Update(pcr_num_name.data(), pcr_num_name.size());
20141  handle_section_bytes += pcr_num_bytes;
20142  command_size += pcr_num_bytes.size();
20143  hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
20144  parameter_section_bytes += auth_policy_bytes;
20145  command_size += auth_policy_bytes.size();
20146  hash->Update(policy_digest_bytes.data(), policy_digest_bytes.size());
20147  parameter_section_bytes += policy_digest_bytes;
20148  command_size += policy_digest_bytes.size();
20149  std::string command_hash(32, 0);
20150  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
20151  std::string authorization_section_bytes;
20152  std::string authorization_size_bytes;
20153  if (authorization_delegate) {
20154    if (!authorization_delegate->GetCommandAuthorization(
20155            command_hash, is_command_parameter_encryption_possible,
20156            is_response_parameter_encryption_possible,
20157            &authorization_section_bytes)) {
20158      return TRUNKS_RC_AUTHORIZATION_FAILED;
20159    }
20160    if (!authorization_section_bytes.empty()) {
20161      tag = TPM_ST_SESSIONS;
20162      std::string tmp;
20163      rc = Serialize_UINT32(authorization_section_bytes.size(),
20164                            &authorization_size_bytes);
20165      if (rc != TPM_RC_SUCCESS) {
20166        return rc;
20167      }
20168      command_size +=
20169          authorization_size_bytes.size() + authorization_section_bytes.size();
20170    }
20171  }
20172  std::string tag_bytes;
20173  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20174  if (rc != TPM_RC_SUCCESS) {
20175    return rc;
20176  }
20177  std::string command_size_bytes;
20178  rc = Serialize_UINT32(command_size, &command_size_bytes);
20179  if (rc != TPM_RC_SUCCESS) {
20180    return rc;
20181  }
20182  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20183                        handle_section_bytes + authorization_size_bytes +
20184                        authorization_section_bytes + parameter_section_bytes;
20185  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20186  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
20187                                            serialized_command->size());
20188  return TPM_RC_SUCCESS;
20189}
20190
20191TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy(
20192    const std::string& response,
20193    AuthorizationDelegate* authorization_delegate) {
20194  VLOG(3) << __func__;
20195  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20196  TPM_RC rc = TPM_RC_SUCCESS;
20197  std::string buffer(response);
20198  TPM_ST tag;
20199  std::string tag_bytes;
20200  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20201  if (rc != TPM_RC_SUCCESS) {
20202    return rc;
20203  }
20204  UINT32 response_size;
20205  std::string response_size_bytes;
20206  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20207  if (rc != TPM_RC_SUCCESS) {
20208    return rc;
20209  }
20210  TPM_RC response_code;
20211  std::string response_code_bytes;
20212  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20213  if (rc != TPM_RC_SUCCESS) {
20214    return rc;
20215  }
20216  if (response_size != response.size()) {
20217    return TPM_RC_SIZE;
20218  }
20219  if (response_code != TPM_RC_SUCCESS) {
20220    return response_code;
20221  }
20222  TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20223  std::string command_code_bytes;
20224  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20225  if (rc != TPM_RC_SUCCESS) {
20226    return rc;
20227  }
20228  std::string authorization_section_bytes;
20229  if (tag == TPM_ST_SESSIONS) {
20230    UINT32 parameter_section_size = buffer.size();
20231    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20232    if (rc != TPM_RC_SUCCESS) {
20233      return rc;
20234    }
20235    if (parameter_section_size > buffer.size()) {
20236      return TPM_RC_INSUFFICIENT;
20237    }
20238    authorization_section_bytes = buffer.substr(parameter_section_size);
20239    // Keep the parameter section in |buffer|.
20240    buffer.erase(parameter_section_size);
20241  }
20242  std::unique_ptr<crypto::SecureHash> hash(
20243      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20244  hash->Update(response_code_bytes.data(), response_code_bytes.size());
20245  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20246  hash->Update(buffer.data(), buffer.size());
20247  std::string response_hash(32, 0);
20248  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
20249  if (tag == TPM_ST_SESSIONS) {
20250    CHECK(authorization_delegate) << "Authorization delegate missing!";
20251    if (!authorization_delegate->CheckResponseAuthorization(
20252            response_hash, authorization_section_bytes)) {
20253      return TRUNKS_RC_AUTHORIZATION_FAILED;
20254    }
20255  }
20256  return TPM_RC_SUCCESS;
20257}
20258
20259void PCR_SetAuthPolicyErrorCallback(
20260    const Tpm::PCR_SetAuthPolicyResponse& callback,
20261    TPM_RC response_code) {
20262  VLOG(1) << __func__;
20263  callback.Run(response_code);
20264}
20265
20266void PCR_SetAuthPolicyResponseParser(
20267    const Tpm::PCR_SetAuthPolicyResponse& callback,
20268    AuthorizationDelegate* authorization_delegate,
20269    const std::string& response) {
20270  VLOG(1) << __func__;
20271  base::Callback<void(TPM_RC)> error_reporter =
20272      base::Bind(PCR_SetAuthPolicyErrorCallback, callback);
20273  TPM_RC rc =
20274      Tpm::ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20275  if (rc != TPM_RC_SUCCESS) {
20276    error_reporter.Run(rc);
20277    return;
20278  }
20279  callback.Run(rc);
20280}
20281
20282void Tpm::PCR_SetAuthPolicy(const TPMI_RH_PLATFORM& auth_handle,
20283                            const std::string& auth_handle_name,
20284                            const TPMI_DH_PCR& pcr_num,
20285                            const std::string& pcr_num_name,
20286                            const TPM2B_DIGEST& auth_policy,
20287                            const TPMI_ALG_HASH& policy_digest,
20288                            AuthorizationDelegate* authorization_delegate,
20289                            const PCR_SetAuthPolicyResponse& callback) {
20290  VLOG(1) << __func__;
20291  base::Callback<void(TPM_RC)> error_reporter =
20292      base::Bind(PCR_SetAuthPolicyErrorCallback, callback);
20293  base::Callback<void(const std::string&)> parser = base::Bind(
20294      PCR_SetAuthPolicyResponseParser, callback, authorization_delegate);
20295  std::string command;
20296  TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20297      auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20298      policy_digest, &command, authorization_delegate);
20299  if (rc != TPM_RC_SUCCESS) {
20300    error_reporter.Run(rc);
20301    return;
20302  }
20303  transceiver_->SendCommand(command, parser);
20304}
20305
20306TPM_RC Tpm::PCR_SetAuthPolicySync(
20307    const TPMI_RH_PLATFORM& auth_handle,
20308    const std::string& auth_handle_name,
20309    const TPMI_DH_PCR& pcr_num,
20310    const std::string& pcr_num_name,
20311    const TPM2B_DIGEST& auth_policy,
20312    const TPMI_ALG_HASH& policy_digest,
20313    AuthorizationDelegate* authorization_delegate) {
20314  VLOG(1) << __func__;
20315  std::string command;
20316  TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20317      auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20318      policy_digest, &command, authorization_delegate);
20319  if (rc != TPM_RC_SUCCESS) {
20320    return rc;
20321  }
20322  std::string response = transceiver_->SendCommandAndWait(command);
20323  rc = ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20324  return rc;
20325}
20326
20327TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue(
20328    const TPMI_DH_PCR& pcr_handle,
20329    const std::string& pcr_handle_name,
20330    const TPM2B_DIGEST& auth,
20331    std::string* serialized_command,
20332    AuthorizationDelegate* authorization_delegate) {
20333  VLOG(3) << __func__;
20334  TPM_RC rc = TPM_RC_SUCCESS;
20335  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20336  UINT32 command_size = 10;  // Header size.
20337  std::string handle_section_bytes;
20338  std::string parameter_section_bytes;
20339  TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20340  bool is_command_parameter_encryption_possible = true;
20341  bool is_response_parameter_encryption_possible = false;
20342  std::string command_code_bytes;
20343  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20344  if (rc != TPM_RC_SUCCESS) {
20345    return rc;
20346  }
20347  std::string pcr_handle_bytes;
20348  rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20349  if (rc != TPM_RC_SUCCESS) {
20350    return rc;
20351  }
20352  std::string auth_bytes;
20353  rc = Serialize_TPM2B_DIGEST(auth, &auth_bytes);
20354  if (rc != TPM_RC_SUCCESS) {
20355    return rc;
20356  }
20357  if (authorization_delegate) {
20358    // Encrypt just the parameter data, not the size.
20359    std::string tmp = auth_bytes.substr(2);
20360    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20361      return TRUNKS_RC_ENCRYPTION_FAILED;
20362    }
20363    auth_bytes.replace(2, std::string::npos, tmp);
20364  }
20365  std::unique_ptr<crypto::SecureHash> hash(
20366      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20367  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20368  hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20369  handle_section_bytes += pcr_handle_bytes;
20370  command_size += pcr_handle_bytes.size();
20371  hash->Update(auth_bytes.data(), auth_bytes.size());
20372  parameter_section_bytes += auth_bytes;
20373  command_size += auth_bytes.size();
20374  std::string command_hash(32, 0);
20375  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
20376  std::string authorization_section_bytes;
20377  std::string authorization_size_bytes;
20378  if (authorization_delegate) {
20379    if (!authorization_delegate->GetCommandAuthorization(
20380            command_hash, is_command_parameter_encryption_possible,
20381            is_response_parameter_encryption_possible,
20382            &authorization_section_bytes)) {
20383      return TRUNKS_RC_AUTHORIZATION_FAILED;
20384    }
20385    if (!authorization_section_bytes.empty()) {
20386      tag = TPM_ST_SESSIONS;
20387      std::string tmp;
20388      rc = Serialize_UINT32(authorization_section_bytes.size(),
20389                            &authorization_size_bytes);
20390      if (rc != TPM_RC_SUCCESS) {
20391        return rc;
20392      }
20393      command_size +=
20394          authorization_size_bytes.size() + authorization_section_bytes.size();
20395    }
20396  }
20397  std::string tag_bytes;
20398  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20399  if (rc != TPM_RC_SUCCESS) {
20400    return rc;
20401  }
20402  std::string command_size_bytes;
20403  rc = Serialize_UINT32(command_size, &command_size_bytes);
20404  if (rc != TPM_RC_SUCCESS) {
20405    return rc;
20406  }
20407  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20408                        handle_section_bytes + authorization_size_bytes +
20409                        authorization_section_bytes + parameter_section_bytes;
20410  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20411  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
20412                                            serialized_command->size());
20413  return TPM_RC_SUCCESS;
20414}
20415
20416TPM_RC Tpm::ParseResponse_PCR_SetAuthValue(
20417    const std::string& response,
20418    AuthorizationDelegate* authorization_delegate) {
20419  VLOG(3) << __func__;
20420  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20421  TPM_RC rc = TPM_RC_SUCCESS;
20422  std::string buffer(response);
20423  TPM_ST tag;
20424  std::string tag_bytes;
20425  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20426  if (rc != TPM_RC_SUCCESS) {
20427    return rc;
20428  }
20429  UINT32 response_size;
20430  std::string response_size_bytes;
20431  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20432  if (rc != TPM_RC_SUCCESS) {
20433    return rc;
20434  }
20435  TPM_RC response_code;
20436  std::string response_code_bytes;
20437  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20438  if (rc != TPM_RC_SUCCESS) {
20439    return rc;
20440  }
20441  if (response_size != response.size()) {
20442    return TPM_RC_SIZE;
20443  }
20444  if (response_code != TPM_RC_SUCCESS) {
20445    return response_code;
20446  }
20447  TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20448  std::string command_code_bytes;
20449  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20450  if (rc != TPM_RC_SUCCESS) {
20451    return rc;
20452  }
20453  std::string authorization_section_bytes;
20454  if (tag == TPM_ST_SESSIONS) {
20455    UINT32 parameter_section_size = buffer.size();
20456    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20457    if (rc != TPM_RC_SUCCESS) {
20458      return rc;
20459    }
20460    if (parameter_section_size > buffer.size()) {
20461      return TPM_RC_INSUFFICIENT;
20462    }
20463    authorization_section_bytes = buffer.substr(parameter_section_size);
20464    // Keep the parameter section in |buffer|.
20465    buffer.erase(parameter_section_size);
20466  }
20467  std::unique_ptr<crypto::SecureHash> hash(
20468      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20469  hash->Update(response_code_bytes.data(), response_code_bytes.size());
20470  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20471  hash->Update(buffer.data(), buffer.size());
20472  std::string response_hash(32, 0);
20473  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
20474  if (tag == TPM_ST_SESSIONS) {
20475    CHECK(authorization_delegate) << "Authorization delegate missing!";
20476    if (!authorization_delegate->CheckResponseAuthorization(
20477            response_hash, authorization_section_bytes)) {
20478      return TRUNKS_RC_AUTHORIZATION_FAILED;
20479    }
20480  }
20481  return TPM_RC_SUCCESS;
20482}
20483
20484void PCR_SetAuthValueErrorCallback(
20485    const Tpm::PCR_SetAuthValueResponse& callback,
20486    TPM_RC response_code) {
20487  VLOG(1) << __func__;
20488  callback.Run(response_code);
20489}
20490
20491void PCR_SetAuthValueResponseParser(
20492    const Tpm::PCR_SetAuthValueResponse& callback,
20493    AuthorizationDelegate* authorization_delegate,
20494    const std::string& response) {
20495  VLOG(1) << __func__;
20496  base::Callback<void(TPM_RC)> error_reporter =
20497      base::Bind(PCR_SetAuthValueErrorCallback, callback);
20498  TPM_RC rc =
20499      Tpm::ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20500  if (rc != TPM_RC_SUCCESS) {
20501    error_reporter.Run(rc);
20502    return;
20503  }
20504  callback.Run(rc);
20505}
20506
20507void Tpm::PCR_SetAuthValue(const TPMI_DH_PCR& pcr_handle,
20508                           const std::string& pcr_handle_name,
20509                           const TPM2B_DIGEST& auth,
20510                           AuthorizationDelegate* authorization_delegate,
20511                           const PCR_SetAuthValueResponse& callback) {
20512  VLOG(1) << __func__;
20513  base::Callback<void(TPM_RC)> error_reporter =
20514      base::Bind(PCR_SetAuthValueErrorCallback, callback);
20515  base::Callback<void(const std::string&)> parser = base::Bind(
20516      PCR_SetAuthValueResponseParser, callback, authorization_delegate);
20517  std::string command;
20518  TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20519      pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20520  if (rc != TPM_RC_SUCCESS) {
20521    error_reporter.Run(rc);
20522    return;
20523  }
20524  transceiver_->SendCommand(command, parser);
20525}
20526
20527TPM_RC Tpm::PCR_SetAuthValueSync(
20528    const TPMI_DH_PCR& pcr_handle,
20529    const std::string& pcr_handle_name,
20530    const TPM2B_DIGEST& auth,
20531    AuthorizationDelegate* authorization_delegate) {
20532  VLOG(1) << __func__;
20533  std::string command;
20534  TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20535      pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20536  if (rc != TPM_RC_SUCCESS) {
20537    return rc;
20538  }
20539  std::string response = transceiver_->SendCommandAndWait(command);
20540  rc = ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20541  return rc;
20542}
20543
20544TPM_RC Tpm::SerializeCommand_PCR_Reset(
20545    const TPMI_DH_PCR& pcr_handle,
20546    const std::string& pcr_handle_name,
20547    std::string* serialized_command,
20548    AuthorizationDelegate* authorization_delegate) {
20549  VLOG(3) << __func__;
20550  TPM_RC rc = TPM_RC_SUCCESS;
20551  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20552  UINT32 command_size = 10;  // Header size.
20553  std::string handle_section_bytes;
20554  std::string parameter_section_bytes;
20555  TPM_CC command_code = TPM_CC_PCR_Reset;
20556  bool is_command_parameter_encryption_possible = false;
20557  bool is_response_parameter_encryption_possible = false;
20558  std::string command_code_bytes;
20559  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20560  if (rc != TPM_RC_SUCCESS) {
20561    return rc;
20562  }
20563  std::string pcr_handle_bytes;
20564  rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20565  if (rc != TPM_RC_SUCCESS) {
20566    return rc;
20567  }
20568  std::unique_ptr<crypto::SecureHash> hash(
20569      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20570  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20571  hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20572  handle_section_bytes += pcr_handle_bytes;
20573  command_size += pcr_handle_bytes.size();
20574  std::string command_hash(32, 0);
20575  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
20576  std::string authorization_section_bytes;
20577  std::string authorization_size_bytes;
20578  if (authorization_delegate) {
20579    if (!authorization_delegate->GetCommandAuthorization(
20580            command_hash, is_command_parameter_encryption_possible,
20581            is_response_parameter_encryption_possible,
20582            &authorization_section_bytes)) {
20583      return TRUNKS_RC_AUTHORIZATION_FAILED;
20584    }
20585    if (!authorization_section_bytes.empty()) {
20586      tag = TPM_ST_SESSIONS;
20587      std::string tmp;
20588      rc = Serialize_UINT32(authorization_section_bytes.size(),
20589                            &authorization_size_bytes);
20590      if (rc != TPM_RC_SUCCESS) {
20591        return rc;
20592      }
20593      command_size +=
20594          authorization_size_bytes.size() + authorization_section_bytes.size();
20595    }
20596  }
20597  std::string tag_bytes;
20598  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20599  if (rc != TPM_RC_SUCCESS) {
20600    return rc;
20601  }
20602  std::string command_size_bytes;
20603  rc = Serialize_UINT32(command_size, &command_size_bytes);
20604  if (rc != TPM_RC_SUCCESS) {
20605    return rc;
20606  }
20607  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20608                        handle_section_bytes + authorization_size_bytes +
20609                        authorization_section_bytes + parameter_section_bytes;
20610  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20611  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
20612                                            serialized_command->size());
20613  return TPM_RC_SUCCESS;
20614}
20615
20616TPM_RC Tpm::ParseResponse_PCR_Reset(
20617    const std::string& response,
20618    AuthorizationDelegate* authorization_delegate) {
20619  VLOG(3) << __func__;
20620  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20621  TPM_RC rc = TPM_RC_SUCCESS;
20622  std::string buffer(response);
20623  TPM_ST tag;
20624  std::string tag_bytes;
20625  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20626  if (rc != TPM_RC_SUCCESS) {
20627    return rc;
20628  }
20629  UINT32 response_size;
20630  std::string response_size_bytes;
20631  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20632  if (rc != TPM_RC_SUCCESS) {
20633    return rc;
20634  }
20635  TPM_RC response_code;
20636  std::string response_code_bytes;
20637  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20638  if (rc != TPM_RC_SUCCESS) {
20639    return rc;
20640  }
20641  if (response_size != response.size()) {
20642    return TPM_RC_SIZE;
20643  }
20644  if (response_code != TPM_RC_SUCCESS) {
20645    return response_code;
20646  }
20647  TPM_CC command_code = TPM_CC_PCR_Reset;
20648  std::string command_code_bytes;
20649  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20650  if (rc != TPM_RC_SUCCESS) {
20651    return rc;
20652  }
20653  std::string authorization_section_bytes;
20654  if (tag == TPM_ST_SESSIONS) {
20655    UINT32 parameter_section_size = buffer.size();
20656    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20657    if (rc != TPM_RC_SUCCESS) {
20658      return rc;
20659    }
20660    if (parameter_section_size > buffer.size()) {
20661      return TPM_RC_INSUFFICIENT;
20662    }
20663    authorization_section_bytes = buffer.substr(parameter_section_size);
20664    // Keep the parameter section in |buffer|.
20665    buffer.erase(parameter_section_size);
20666  }
20667  std::unique_ptr<crypto::SecureHash> hash(
20668      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20669  hash->Update(response_code_bytes.data(), response_code_bytes.size());
20670  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20671  hash->Update(buffer.data(), buffer.size());
20672  std::string response_hash(32, 0);
20673  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
20674  if (tag == TPM_ST_SESSIONS) {
20675    CHECK(authorization_delegate) << "Authorization delegate missing!";
20676    if (!authorization_delegate->CheckResponseAuthorization(
20677            response_hash, authorization_section_bytes)) {
20678      return TRUNKS_RC_AUTHORIZATION_FAILED;
20679    }
20680  }
20681  return TPM_RC_SUCCESS;
20682}
20683
20684void PCR_ResetErrorCallback(const Tpm::PCR_ResetResponse& callback,
20685                            TPM_RC response_code) {
20686  VLOG(1) << __func__;
20687  callback.Run(response_code);
20688}
20689
20690void PCR_ResetResponseParser(const Tpm::PCR_ResetResponse& callback,
20691                             AuthorizationDelegate* authorization_delegate,
20692                             const std::string& response) {
20693  VLOG(1) << __func__;
20694  base::Callback<void(TPM_RC)> error_reporter =
20695      base::Bind(PCR_ResetErrorCallback, callback);
20696  TPM_RC rc = Tpm::ParseResponse_PCR_Reset(response, authorization_delegate);
20697  if (rc != TPM_RC_SUCCESS) {
20698    error_reporter.Run(rc);
20699    return;
20700  }
20701  callback.Run(rc);
20702}
20703
20704void Tpm::PCR_Reset(const TPMI_DH_PCR& pcr_handle,
20705                    const std::string& pcr_handle_name,
20706                    AuthorizationDelegate* authorization_delegate,
20707                    const PCR_ResetResponse& callback) {
20708  VLOG(1) << __func__;
20709  base::Callback<void(TPM_RC)> error_reporter =
20710      base::Bind(PCR_ResetErrorCallback, callback);
20711  base::Callback<void(const std::string&)> parser =
20712      base::Bind(PCR_ResetResponseParser, callback, authorization_delegate);
20713  std::string command;
20714  TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
20715                                         authorization_delegate);
20716  if (rc != TPM_RC_SUCCESS) {
20717    error_reporter.Run(rc);
20718    return;
20719  }
20720  transceiver_->SendCommand(command, parser);
20721}
20722
20723TPM_RC Tpm::PCR_ResetSync(const TPMI_DH_PCR& pcr_handle,
20724                          const std::string& pcr_handle_name,
20725                          AuthorizationDelegate* authorization_delegate) {
20726  VLOG(1) << __func__;
20727  std::string command;
20728  TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
20729                                         authorization_delegate);
20730  if (rc != TPM_RC_SUCCESS) {
20731    return rc;
20732  }
20733  std::string response = transceiver_->SendCommandAndWait(command);
20734  rc = ParseResponse_PCR_Reset(response, authorization_delegate);
20735  return rc;
20736}
20737
20738TPM_RC Tpm::SerializeCommand_PolicySigned(
20739    const TPMI_DH_OBJECT& auth_object,
20740    const std::string& auth_object_name,
20741    const TPMI_SH_POLICY& policy_session,
20742    const std::string& policy_session_name,
20743    const TPM2B_NONCE& nonce_tpm,
20744    const TPM2B_DIGEST& cp_hash_a,
20745    const TPM2B_NONCE& policy_ref,
20746    const INT32& expiration,
20747    const TPMT_SIGNATURE& auth,
20748    std::string* serialized_command,
20749    AuthorizationDelegate* authorization_delegate) {
20750  VLOG(3) << __func__;
20751  TPM_RC rc = TPM_RC_SUCCESS;
20752  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20753  UINT32 command_size = 10;  // Header size.
20754  std::string handle_section_bytes;
20755  std::string parameter_section_bytes;
20756  TPM_CC command_code = TPM_CC_PolicySigned;
20757  bool is_command_parameter_encryption_possible = true;
20758  bool is_response_parameter_encryption_possible = true;
20759  std::string command_code_bytes;
20760  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20761  if (rc != TPM_RC_SUCCESS) {
20762    return rc;
20763  }
20764  std::string auth_object_bytes;
20765  rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
20766  if (rc != TPM_RC_SUCCESS) {
20767    return rc;
20768  }
20769  std::string policy_session_bytes;
20770  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
20771  if (rc != TPM_RC_SUCCESS) {
20772    return rc;
20773  }
20774  std::string nonce_tpm_bytes;
20775  rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
20776  if (rc != TPM_RC_SUCCESS) {
20777    return rc;
20778  }
20779  std::string cp_hash_a_bytes;
20780  rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
20781  if (rc != TPM_RC_SUCCESS) {
20782    return rc;
20783  }
20784  std::string policy_ref_bytes;
20785  rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
20786  if (rc != TPM_RC_SUCCESS) {
20787    return rc;
20788  }
20789  std::string expiration_bytes;
20790  rc = Serialize_INT32(expiration, &expiration_bytes);
20791  if (rc != TPM_RC_SUCCESS) {
20792    return rc;
20793  }
20794  std::string auth_bytes;
20795  rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
20796  if (rc != TPM_RC_SUCCESS) {
20797    return rc;
20798  }
20799  if (authorization_delegate) {
20800    // Encrypt just the parameter data, not the size.
20801    std::string tmp = nonce_tpm_bytes.substr(2);
20802    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20803      return TRUNKS_RC_ENCRYPTION_FAILED;
20804    }
20805    nonce_tpm_bytes.replace(2, std::string::npos, tmp);
20806  }
20807  std::unique_ptr<crypto::SecureHash> hash(
20808      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20809  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20810  hash->Update(auth_object_name.data(), auth_object_name.size());
20811  handle_section_bytes += auth_object_bytes;
20812  command_size += auth_object_bytes.size();
20813  hash->Update(policy_session_name.data(), policy_session_name.size());
20814  handle_section_bytes += policy_session_bytes;
20815  command_size += policy_session_bytes.size();
20816  hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
20817  parameter_section_bytes += nonce_tpm_bytes;
20818  command_size += nonce_tpm_bytes.size();
20819  hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
20820  parameter_section_bytes += cp_hash_a_bytes;
20821  command_size += cp_hash_a_bytes.size();
20822  hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
20823  parameter_section_bytes += policy_ref_bytes;
20824  command_size += policy_ref_bytes.size();
20825  hash->Update(expiration_bytes.data(), expiration_bytes.size());
20826  parameter_section_bytes += expiration_bytes;
20827  command_size += expiration_bytes.size();
20828  hash->Update(auth_bytes.data(), auth_bytes.size());
20829  parameter_section_bytes += auth_bytes;
20830  command_size += auth_bytes.size();
20831  std::string command_hash(32, 0);
20832  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
20833  std::string authorization_section_bytes;
20834  std::string authorization_size_bytes;
20835  if (authorization_delegate) {
20836    if (!authorization_delegate->GetCommandAuthorization(
20837            command_hash, is_command_parameter_encryption_possible,
20838            is_response_parameter_encryption_possible,
20839            &authorization_section_bytes)) {
20840      return TRUNKS_RC_AUTHORIZATION_FAILED;
20841    }
20842    if (!authorization_section_bytes.empty()) {
20843      tag = TPM_ST_SESSIONS;
20844      std::string tmp;
20845      rc = Serialize_UINT32(authorization_section_bytes.size(),
20846                            &authorization_size_bytes);
20847      if (rc != TPM_RC_SUCCESS) {
20848        return rc;
20849      }
20850      command_size +=
20851          authorization_size_bytes.size() + authorization_section_bytes.size();
20852    }
20853  }
20854  std::string tag_bytes;
20855  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20856  if (rc != TPM_RC_SUCCESS) {
20857    return rc;
20858  }
20859  std::string command_size_bytes;
20860  rc = Serialize_UINT32(command_size, &command_size_bytes);
20861  if (rc != TPM_RC_SUCCESS) {
20862    return rc;
20863  }
20864  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20865                        handle_section_bytes + authorization_size_bytes +
20866                        authorization_section_bytes + parameter_section_bytes;
20867  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20868  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
20869                                            serialized_command->size());
20870  return TPM_RC_SUCCESS;
20871}
20872
20873TPM_RC Tpm::ParseResponse_PolicySigned(
20874    const std::string& response,
20875    TPM2B_TIMEOUT* timeout,
20876    TPMT_TK_AUTH* policy_ticket,
20877    AuthorizationDelegate* authorization_delegate) {
20878  VLOG(3) << __func__;
20879  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20880  TPM_RC rc = TPM_RC_SUCCESS;
20881  std::string buffer(response);
20882  TPM_ST tag;
20883  std::string tag_bytes;
20884  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20885  if (rc != TPM_RC_SUCCESS) {
20886    return rc;
20887  }
20888  UINT32 response_size;
20889  std::string response_size_bytes;
20890  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20891  if (rc != TPM_RC_SUCCESS) {
20892    return rc;
20893  }
20894  TPM_RC response_code;
20895  std::string response_code_bytes;
20896  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20897  if (rc != TPM_RC_SUCCESS) {
20898    return rc;
20899  }
20900  if (response_size != response.size()) {
20901    return TPM_RC_SIZE;
20902  }
20903  if (response_code != TPM_RC_SUCCESS) {
20904    return response_code;
20905  }
20906  TPM_CC command_code = TPM_CC_PolicySigned;
20907  std::string command_code_bytes;
20908  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20909  if (rc != TPM_RC_SUCCESS) {
20910    return rc;
20911  }
20912  std::string authorization_section_bytes;
20913  if (tag == TPM_ST_SESSIONS) {
20914    UINT32 parameter_section_size = buffer.size();
20915    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20916    if (rc != TPM_RC_SUCCESS) {
20917      return rc;
20918    }
20919    if (parameter_section_size > buffer.size()) {
20920      return TPM_RC_INSUFFICIENT;
20921    }
20922    authorization_section_bytes = buffer.substr(parameter_section_size);
20923    // Keep the parameter section in |buffer|.
20924    buffer.erase(parameter_section_size);
20925  }
20926  std::unique_ptr<crypto::SecureHash> hash(
20927      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20928  hash->Update(response_code_bytes.data(), response_code_bytes.size());
20929  hash->Update(command_code_bytes.data(), command_code_bytes.size());
20930  hash->Update(buffer.data(), buffer.size());
20931  std::string response_hash(32, 0);
20932  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
20933  if (tag == TPM_ST_SESSIONS) {
20934    CHECK(authorization_delegate) << "Authorization delegate missing!";
20935    if (!authorization_delegate->CheckResponseAuthorization(
20936            response_hash, authorization_section_bytes)) {
20937      return TRUNKS_RC_AUTHORIZATION_FAILED;
20938    }
20939  }
20940  std::string timeout_bytes;
20941  rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
20942  if (rc != TPM_RC_SUCCESS) {
20943    return rc;
20944  }
20945  std::string policy_ticket_bytes;
20946  rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
20947  if (rc != TPM_RC_SUCCESS) {
20948    return rc;
20949  }
20950  if (tag == TPM_ST_SESSIONS) {
20951    CHECK(authorization_delegate) << "Authorization delegate missing!";
20952    // Decrypt just the parameter data, not the size.
20953    std::string tmp = timeout_bytes.substr(2);
20954    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
20955      return TRUNKS_RC_ENCRYPTION_FAILED;
20956    }
20957    timeout_bytes.replace(2, std::string::npos, tmp);
20958    rc = Parse_TPM2B_TIMEOUT(&timeout_bytes, timeout, nullptr);
20959    if (rc != TPM_RC_SUCCESS) {
20960      return rc;
20961    }
20962  }
20963  return TPM_RC_SUCCESS;
20964}
20965
20966void PolicySignedErrorCallback(const Tpm::PolicySignedResponse& callback,
20967                               TPM_RC response_code) {
20968  VLOG(1) << __func__;
20969  callback.Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
20970}
20971
20972void PolicySignedResponseParser(const Tpm::PolicySignedResponse& callback,
20973                                AuthorizationDelegate* authorization_delegate,
20974                                const std::string& response) {
20975  VLOG(1) << __func__;
20976  base::Callback<void(TPM_RC)> error_reporter =
20977      base::Bind(PolicySignedErrorCallback, callback);
20978  TPM2B_TIMEOUT timeout;
20979  TPMT_TK_AUTH policy_ticket;
20980  TPM_RC rc = Tpm::ParseResponse_PolicySigned(
20981      response, &timeout, &policy_ticket, authorization_delegate);
20982  if (rc != TPM_RC_SUCCESS) {
20983    error_reporter.Run(rc);
20984    return;
20985  }
20986  callback.Run(rc, timeout, policy_ticket);
20987}
20988
20989void Tpm::PolicySigned(const TPMI_DH_OBJECT& auth_object,
20990                       const std::string& auth_object_name,
20991                       const TPMI_SH_POLICY& policy_session,
20992                       const std::string& policy_session_name,
20993                       const TPM2B_NONCE& nonce_tpm,
20994                       const TPM2B_DIGEST& cp_hash_a,
20995                       const TPM2B_NONCE& policy_ref,
20996                       const INT32& expiration,
20997                       const TPMT_SIGNATURE& auth,
20998                       AuthorizationDelegate* authorization_delegate,
20999                       const PolicySignedResponse& callback) {
21000  VLOG(1) << __func__;
21001  base::Callback<void(TPM_RC)> error_reporter =
21002      base::Bind(PolicySignedErrorCallback, callback);
21003  base::Callback<void(const std::string&)> parser =
21004      base::Bind(PolicySignedResponseParser, callback, authorization_delegate);
21005  std::string command;
21006  TPM_RC rc = SerializeCommand_PolicySigned(
21007      auth_object, auth_object_name, policy_session, policy_session_name,
21008      nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21009      authorization_delegate);
21010  if (rc != TPM_RC_SUCCESS) {
21011    error_reporter.Run(rc);
21012    return;
21013  }
21014  transceiver_->SendCommand(command, parser);
21015}
21016
21017TPM_RC Tpm::PolicySignedSync(const TPMI_DH_OBJECT& auth_object,
21018                             const std::string& auth_object_name,
21019                             const TPMI_SH_POLICY& policy_session,
21020                             const std::string& policy_session_name,
21021                             const TPM2B_NONCE& nonce_tpm,
21022                             const TPM2B_DIGEST& cp_hash_a,
21023                             const TPM2B_NONCE& policy_ref,
21024                             const INT32& expiration,
21025                             const TPMT_SIGNATURE& auth,
21026                             TPM2B_TIMEOUT* timeout,
21027                             TPMT_TK_AUTH* policy_ticket,
21028                             AuthorizationDelegate* authorization_delegate) {
21029  VLOG(1) << __func__;
21030  std::string command;
21031  TPM_RC rc = SerializeCommand_PolicySigned(
21032      auth_object, auth_object_name, policy_session, policy_session_name,
21033      nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21034      authorization_delegate);
21035  if (rc != TPM_RC_SUCCESS) {
21036    return rc;
21037  }
21038  std::string response = transceiver_->SendCommandAndWait(command);
21039  rc = ParseResponse_PolicySigned(response, timeout, policy_ticket,
21040                                  authorization_delegate);
21041  return rc;
21042}
21043
21044TPM_RC Tpm::SerializeCommand_PolicySecret(
21045    const TPMI_DH_ENTITY& auth_handle,
21046    const std::string& auth_handle_name,
21047    const TPMI_SH_POLICY& policy_session,
21048    const std::string& policy_session_name,
21049    const TPM2B_NONCE& nonce_tpm,
21050    const TPM2B_DIGEST& cp_hash_a,
21051    const TPM2B_NONCE& policy_ref,
21052    const INT32& expiration,
21053    std::string* serialized_command,
21054    AuthorizationDelegate* authorization_delegate) {
21055  VLOG(3) << __func__;
21056  TPM_RC rc = TPM_RC_SUCCESS;
21057  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21058  UINT32 command_size = 10;  // Header size.
21059  std::string handle_section_bytes;
21060  std::string parameter_section_bytes;
21061  TPM_CC command_code = TPM_CC_PolicySecret;
21062  bool is_command_parameter_encryption_possible = true;
21063  bool is_response_parameter_encryption_possible = true;
21064  std::string command_code_bytes;
21065  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21066  if (rc != TPM_RC_SUCCESS) {
21067    return rc;
21068  }
21069  std::string auth_handle_bytes;
21070  rc = Serialize_TPMI_DH_ENTITY(auth_handle, &auth_handle_bytes);
21071  if (rc != TPM_RC_SUCCESS) {
21072    return rc;
21073  }
21074  std::string policy_session_bytes;
21075  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21076  if (rc != TPM_RC_SUCCESS) {
21077    return rc;
21078  }
21079  std::string nonce_tpm_bytes;
21080  rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21081  if (rc != TPM_RC_SUCCESS) {
21082    return rc;
21083  }
21084  std::string cp_hash_a_bytes;
21085  rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21086  if (rc != TPM_RC_SUCCESS) {
21087    return rc;
21088  }
21089  std::string policy_ref_bytes;
21090  rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21091  if (rc != TPM_RC_SUCCESS) {
21092    return rc;
21093  }
21094  std::string expiration_bytes;
21095  rc = Serialize_INT32(expiration, &expiration_bytes);
21096  if (rc != TPM_RC_SUCCESS) {
21097    return rc;
21098  }
21099  if (authorization_delegate) {
21100    // Encrypt just the parameter data, not the size.
21101    std::string tmp = nonce_tpm_bytes.substr(2);
21102    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21103      return TRUNKS_RC_ENCRYPTION_FAILED;
21104    }
21105    nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21106  }
21107  std::unique_ptr<crypto::SecureHash> hash(
21108      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21109  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21110  hash->Update(auth_handle_name.data(), auth_handle_name.size());
21111  handle_section_bytes += auth_handle_bytes;
21112  command_size += auth_handle_bytes.size();
21113  hash->Update(policy_session_name.data(), policy_session_name.size());
21114  handle_section_bytes += policy_session_bytes;
21115  command_size += policy_session_bytes.size();
21116  hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21117  parameter_section_bytes += nonce_tpm_bytes;
21118  command_size += nonce_tpm_bytes.size();
21119  hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21120  parameter_section_bytes += cp_hash_a_bytes;
21121  command_size += cp_hash_a_bytes.size();
21122  hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21123  parameter_section_bytes += policy_ref_bytes;
21124  command_size += policy_ref_bytes.size();
21125  hash->Update(expiration_bytes.data(), expiration_bytes.size());
21126  parameter_section_bytes += expiration_bytes;
21127  command_size += expiration_bytes.size();
21128  std::string command_hash(32, 0);
21129  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
21130  std::string authorization_section_bytes;
21131  std::string authorization_size_bytes;
21132  if (authorization_delegate) {
21133    if (!authorization_delegate->GetCommandAuthorization(
21134            command_hash, is_command_parameter_encryption_possible,
21135            is_response_parameter_encryption_possible,
21136            &authorization_section_bytes)) {
21137      return TRUNKS_RC_AUTHORIZATION_FAILED;
21138    }
21139    if (!authorization_section_bytes.empty()) {
21140      tag = TPM_ST_SESSIONS;
21141      std::string tmp;
21142      rc = Serialize_UINT32(authorization_section_bytes.size(),
21143                            &authorization_size_bytes);
21144      if (rc != TPM_RC_SUCCESS) {
21145        return rc;
21146      }
21147      command_size +=
21148          authorization_size_bytes.size() + authorization_section_bytes.size();
21149    }
21150  }
21151  std::string tag_bytes;
21152  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21153  if (rc != TPM_RC_SUCCESS) {
21154    return rc;
21155  }
21156  std::string command_size_bytes;
21157  rc = Serialize_UINT32(command_size, &command_size_bytes);
21158  if (rc != TPM_RC_SUCCESS) {
21159    return rc;
21160  }
21161  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21162                        handle_section_bytes + authorization_size_bytes +
21163                        authorization_section_bytes + parameter_section_bytes;
21164  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21165  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
21166                                            serialized_command->size());
21167  return TPM_RC_SUCCESS;
21168}
21169
21170TPM_RC Tpm::ParseResponse_PolicySecret(
21171    const std::string& response,
21172    TPM2B_TIMEOUT* timeout,
21173    TPMT_TK_AUTH* policy_ticket,
21174    AuthorizationDelegate* authorization_delegate) {
21175  VLOG(3) << __func__;
21176  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21177  TPM_RC rc = TPM_RC_SUCCESS;
21178  std::string buffer(response);
21179  TPM_ST tag;
21180  std::string tag_bytes;
21181  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21182  if (rc != TPM_RC_SUCCESS) {
21183    return rc;
21184  }
21185  UINT32 response_size;
21186  std::string response_size_bytes;
21187  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21188  if (rc != TPM_RC_SUCCESS) {
21189    return rc;
21190  }
21191  TPM_RC response_code;
21192  std::string response_code_bytes;
21193  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21194  if (rc != TPM_RC_SUCCESS) {
21195    return rc;
21196  }
21197  if (response_size != response.size()) {
21198    return TPM_RC_SIZE;
21199  }
21200  if (response_code != TPM_RC_SUCCESS) {
21201    return response_code;
21202  }
21203  TPM_CC command_code = TPM_CC_PolicySecret;
21204  std::string command_code_bytes;
21205  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21206  if (rc != TPM_RC_SUCCESS) {
21207    return rc;
21208  }
21209  std::string authorization_section_bytes;
21210  if (tag == TPM_ST_SESSIONS) {
21211    UINT32 parameter_section_size = buffer.size();
21212    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21213    if (rc != TPM_RC_SUCCESS) {
21214      return rc;
21215    }
21216    if (parameter_section_size > buffer.size()) {
21217      return TPM_RC_INSUFFICIENT;
21218    }
21219    authorization_section_bytes = buffer.substr(parameter_section_size);
21220    // Keep the parameter section in |buffer|.
21221    buffer.erase(parameter_section_size);
21222  }
21223  std::unique_ptr<crypto::SecureHash> hash(
21224      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21225  hash->Update(response_code_bytes.data(), response_code_bytes.size());
21226  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21227  hash->Update(buffer.data(), buffer.size());
21228  std::string response_hash(32, 0);
21229  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
21230  if (tag == TPM_ST_SESSIONS) {
21231    CHECK(authorization_delegate) << "Authorization delegate missing!";
21232    if (!authorization_delegate->CheckResponseAuthorization(
21233            response_hash, authorization_section_bytes)) {
21234      return TRUNKS_RC_AUTHORIZATION_FAILED;
21235    }
21236  }
21237  std::string timeout_bytes;
21238  rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21239  if (rc != TPM_RC_SUCCESS) {
21240    return rc;
21241  }
21242  std::string policy_ticket_bytes;
21243  rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21244  if (rc != TPM_RC_SUCCESS) {
21245    return rc;
21246  }
21247  if (tag == TPM_ST_SESSIONS) {
21248    CHECK(authorization_delegate) << "Authorization delegate missing!";
21249    // Decrypt just the parameter data, not the size.
21250    std::string tmp = timeout_bytes.substr(2);
21251    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
21252      return TRUNKS_RC_ENCRYPTION_FAILED;
21253    }
21254    timeout_bytes.replace(2, std::string::npos, tmp);
21255    rc = Parse_TPM2B_TIMEOUT(&timeout_bytes, timeout, nullptr);
21256    if (rc != TPM_RC_SUCCESS) {
21257      return rc;
21258    }
21259  }
21260  return TPM_RC_SUCCESS;
21261}
21262
21263void PolicySecretErrorCallback(const Tpm::PolicySecretResponse& callback,
21264                               TPM_RC response_code) {
21265  VLOG(1) << __func__;
21266  callback.Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21267}
21268
21269void PolicySecretResponseParser(const Tpm::PolicySecretResponse& callback,
21270                                AuthorizationDelegate* authorization_delegate,
21271                                const std::string& response) {
21272  VLOG(1) << __func__;
21273  base::Callback<void(TPM_RC)> error_reporter =
21274      base::Bind(PolicySecretErrorCallback, callback);
21275  TPM2B_TIMEOUT timeout;
21276  TPMT_TK_AUTH policy_ticket;
21277  TPM_RC rc = Tpm::ParseResponse_PolicySecret(
21278      response, &timeout, &policy_ticket, authorization_delegate);
21279  if (rc != TPM_RC_SUCCESS) {
21280    error_reporter.Run(rc);
21281    return;
21282  }
21283  callback.Run(rc, timeout, policy_ticket);
21284}
21285
21286void Tpm::PolicySecret(const TPMI_DH_ENTITY& auth_handle,
21287                       const std::string& auth_handle_name,
21288                       const TPMI_SH_POLICY& policy_session,
21289                       const std::string& policy_session_name,
21290                       const TPM2B_NONCE& nonce_tpm,
21291                       const TPM2B_DIGEST& cp_hash_a,
21292                       const TPM2B_NONCE& policy_ref,
21293                       const INT32& expiration,
21294                       AuthorizationDelegate* authorization_delegate,
21295                       const PolicySecretResponse& callback) {
21296  VLOG(1) << __func__;
21297  base::Callback<void(TPM_RC)> error_reporter =
21298      base::Bind(PolicySecretErrorCallback, callback);
21299  base::Callback<void(const std::string&)> parser =
21300      base::Bind(PolicySecretResponseParser, callback, authorization_delegate);
21301  std::string command;
21302  TPM_RC rc = SerializeCommand_PolicySecret(
21303      auth_handle, auth_handle_name, policy_session, policy_session_name,
21304      nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21305      authorization_delegate);
21306  if (rc != TPM_RC_SUCCESS) {
21307    error_reporter.Run(rc);
21308    return;
21309  }
21310  transceiver_->SendCommand(command, parser);
21311}
21312
21313TPM_RC Tpm::PolicySecretSync(const TPMI_DH_ENTITY& auth_handle,
21314                             const std::string& auth_handle_name,
21315                             const TPMI_SH_POLICY& policy_session,
21316                             const std::string& policy_session_name,
21317                             const TPM2B_NONCE& nonce_tpm,
21318                             const TPM2B_DIGEST& cp_hash_a,
21319                             const TPM2B_NONCE& policy_ref,
21320                             const INT32& expiration,
21321                             TPM2B_TIMEOUT* timeout,
21322                             TPMT_TK_AUTH* policy_ticket,
21323                             AuthorizationDelegate* authorization_delegate) {
21324  VLOG(1) << __func__;
21325  std::string command;
21326  TPM_RC rc = SerializeCommand_PolicySecret(
21327      auth_handle, auth_handle_name, policy_session, policy_session_name,
21328      nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21329      authorization_delegate);
21330  if (rc != TPM_RC_SUCCESS) {
21331    return rc;
21332  }
21333  std::string response = transceiver_->SendCommandAndWait(command);
21334  rc = ParseResponse_PolicySecret(response, timeout, policy_ticket,
21335                                  authorization_delegate);
21336  return rc;
21337}
21338
21339TPM_RC Tpm::SerializeCommand_PolicyTicket(
21340    const TPMI_SH_POLICY& policy_session,
21341    const std::string& policy_session_name,
21342    const TPM2B_TIMEOUT& timeout,
21343    const TPM2B_DIGEST& cp_hash_a,
21344    const TPM2B_NONCE& policy_ref,
21345    const TPM2B_NAME& auth_name,
21346    const TPMT_TK_AUTH& ticket,
21347    std::string* serialized_command,
21348    AuthorizationDelegate* authorization_delegate) {
21349  VLOG(3) << __func__;
21350  TPM_RC rc = TPM_RC_SUCCESS;
21351  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21352  UINT32 command_size = 10;  // Header size.
21353  std::string handle_section_bytes;
21354  std::string parameter_section_bytes;
21355  TPM_CC command_code = TPM_CC_PolicyTicket;
21356  bool is_command_parameter_encryption_possible = true;
21357  bool is_response_parameter_encryption_possible = false;
21358  std::string command_code_bytes;
21359  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21360  if (rc != TPM_RC_SUCCESS) {
21361    return rc;
21362  }
21363  std::string policy_session_bytes;
21364  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21365  if (rc != TPM_RC_SUCCESS) {
21366    return rc;
21367  }
21368  std::string timeout_bytes;
21369  rc = Serialize_TPM2B_TIMEOUT(timeout, &timeout_bytes);
21370  if (rc != TPM_RC_SUCCESS) {
21371    return rc;
21372  }
21373  std::string cp_hash_a_bytes;
21374  rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21375  if (rc != TPM_RC_SUCCESS) {
21376    return rc;
21377  }
21378  std::string policy_ref_bytes;
21379  rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21380  if (rc != TPM_RC_SUCCESS) {
21381    return rc;
21382  }
21383  std::string auth_name_bytes;
21384  rc = Serialize_TPM2B_NAME(auth_name, &auth_name_bytes);
21385  if (rc != TPM_RC_SUCCESS) {
21386    return rc;
21387  }
21388  std::string ticket_bytes;
21389  rc = Serialize_TPMT_TK_AUTH(ticket, &ticket_bytes);
21390  if (rc != TPM_RC_SUCCESS) {
21391    return rc;
21392  }
21393  if (authorization_delegate) {
21394    // Encrypt just the parameter data, not the size.
21395    std::string tmp = timeout_bytes.substr(2);
21396    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21397      return TRUNKS_RC_ENCRYPTION_FAILED;
21398    }
21399    timeout_bytes.replace(2, std::string::npos, tmp);
21400  }
21401  std::unique_ptr<crypto::SecureHash> hash(
21402      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21403  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21404  hash->Update(policy_session_name.data(), policy_session_name.size());
21405  handle_section_bytes += policy_session_bytes;
21406  command_size += policy_session_bytes.size();
21407  hash->Update(timeout_bytes.data(), timeout_bytes.size());
21408  parameter_section_bytes += timeout_bytes;
21409  command_size += timeout_bytes.size();
21410  hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21411  parameter_section_bytes += cp_hash_a_bytes;
21412  command_size += cp_hash_a_bytes.size();
21413  hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21414  parameter_section_bytes += policy_ref_bytes;
21415  command_size += policy_ref_bytes.size();
21416  hash->Update(auth_name_bytes.data(), auth_name_bytes.size());
21417  parameter_section_bytes += auth_name_bytes;
21418  command_size += auth_name_bytes.size();
21419  hash->Update(ticket_bytes.data(), ticket_bytes.size());
21420  parameter_section_bytes += ticket_bytes;
21421  command_size += ticket_bytes.size();
21422  std::string command_hash(32, 0);
21423  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
21424  std::string authorization_section_bytes;
21425  std::string authorization_size_bytes;
21426  if (authorization_delegate) {
21427    if (!authorization_delegate->GetCommandAuthorization(
21428            command_hash, is_command_parameter_encryption_possible,
21429            is_response_parameter_encryption_possible,
21430            &authorization_section_bytes)) {
21431      return TRUNKS_RC_AUTHORIZATION_FAILED;
21432    }
21433    if (!authorization_section_bytes.empty()) {
21434      tag = TPM_ST_SESSIONS;
21435      std::string tmp;
21436      rc = Serialize_UINT32(authorization_section_bytes.size(),
21437                            &authorization_size_bytes);
21438      if (rc != TPM_RC_SUCCESS) {
21439        return rc;
21440      }
21441      command_size +=
21442          authorization_size_bytes.size() + authorization_section_bytes.size();
21443    }
21444  }
21445  std::string tag_bytes;
21446  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21447  if (rc != TPM_RC_SUCCESS) {
21448    return rc;
21449  }
21450  std::string command_size_bytes;
21451  rc = Serialize_UINT32(command_size, &command_size_bytes);
21452  if (rc != TPM_RC_SUCCESS) {
21453    return rc;
21454  }
21455  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21456                        handle_section_bytes + authorization_size_bytes +
21457                        authorization_section_bytes + parameter_section_bytes;
21458  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21459  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
21460                                            serialized_command->size());
21461  return TPM_RC_SUCCESS;
21462}
21463
21464TPM_RC Tpm::ParseResponse_PolicyTicket(
21465    const std::string& response,
21466    AuthorizationDelegate* authorization_delegate) {
21467  VLOG(3) << __func__;
21468  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21469  TPM_RC rc = TPM_RC_SUCCESS;
21470  std::string buffer(response);
21471  TPM_ST tag;
21472  std::string tag_bytes;
21473  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21474  if (rc != TPM_RC_SUCCESS) {
21475    return rc;
21476  }
21477  UINT32 response_size;
21478  std::string response_size_bytes;
21479  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21480  if (rc != TPM_RC_SUCCESS) {
21481    return rc;
21482  }
21483  TPM_RC response_code;
21484  std::string response_code_bytes;
21485  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21486  if (rc != TPM_RC_SUCCESS) {
21487    return rc;
21488  }
21489  if (response_size != response.size()) {
21490    return TPM_RC_SIZE;
21491  }
21492  if (response_code != TPM_RC_SUCCESS) {
21493    return response_code;
21494  }
21495  TPM_CC command_code = TPM_CC_PolicyTicket;
21496  std::string command_code_bytes;
21497  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21498  if (rc != TPM_RC_SUCCESS) {
21499    return rc;
21500  }
21501  std::string authorization_section_bytes;
21502  if (tag == TPM_ST_SESSIONS) {
21503    UINT32 parameter_section_size = buffer.size();
21504    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21505    if (rc != TPM_RC_SUCCESS) {
21506      return rc;
21507    }
21508    if (parameter_section_size > buffer.size()) {
21509      return TPM_RC_INSUFFICIENT;
21510    }
21511    authorization_section_bytes = buffer.substr(parameter_section_size);
21512    // Keep the parameter section in |buffer|.
21513    buffer.erase(parameter_section_size);
21514  }
21515  std::unique_ptr<crypto::SecureHash> hash(
21516      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21517  hash->Update(response_code_bytes.data(), response_code_bytes.size());
21518  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21519  hash->Update(buffer.data(), buffer.size());
21520  std::string response_hash(32, 0);
21521  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
21522  if (tag == TPM_ST_SESSIONS) {
21523    CHECK(authorization_delegate) << "Authorization delegate missing!";
21524    if (!authorization_delegate->CheckResponseAuthorization(
21525            response_hash, authorization_section_bytes)) {
21526      return TRUNKS_RC_AUTHORIZATION_FAILED;
21527    }
21528  }
21529  return TPM_RC_SUCCESS;
21530}
21531
21532void PolicyTicketErrorCallback(const Tpm::PolicyTicketResponse& callback,
21533                               TPM_RC response_code) {
21534  VLOG(1) << __func__;
21535  callback.Run(response_code);
21536}
21537
21538void PolicyTicketResponseParser(const Tpm::PolicyTicketResponse& callback,
21539                                AuthorizationDelegate* authorization_delegate,
21540                                const std::string& response) {
21541  VLOG(1) << __func__;
21542  base::Callback<void(TPM_RC)> error_reporter =
21543      base::Bind(PolicyTicketErrorCallback, callback);
21544  TPM_RC rc = Tpm::ParseResponse_PolicyTicket(response, authorization_delegate);
21545  if (rc != TPM_RC_SUCCESS) {
21546    error_reporter.Run(rc);
21547    return;
21548  }
21549  callback.Run(rc);
21550}
21551
21552void Tpm::PolicyTicket(const TPMI_SH_POLICY& policy_session,
21553                       const std::string& policy_session_name,
21554                       const TPM2B_TIMEOUT& timeout,
21555                       const TPM2B_DIGEST& cp_hash_a,
21556                       const TPM2B_NONCE& policy_ref,
21557                       const TPM2B_NAME& auth_name,
21558                       const TPMT_TK_AUTH& ticket,
21559                       AuthorizationDelegate* authorization_delegate,
21560                       const PolicyTicketResponse& callback) {
21561  VLOG(1) << __func__;
21562  base::Callback<void(TPM_RC)> error_reporter =
21563      base::Bind(PolicyTicketErrorCallback, callback);
21564  base::Callback<void(const std::string&)> parser =
21565      base::Bind(PolicyTicketResponseParser, callback, authorization_delegate);
21566  std::string command;
21567  TPM_RC rc = SerializeCommand_PolicyTicket(
21568      policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21569      auth_name, ticket, &command, authorization_delegate);
21570  if (rc != TPM_RC_SUCCESS) {
21571    error_reporter.Run(rc);
21572    return;
21573  }
21574  transceiver_->SendCommand(command, parser);
21575}
21576
21577TPM_RC Tpm::PolicyTicketSync(const TPMI_SH_POLICY& policy_session,
21578                             const std::string& policy_session_name,
21579                             const TPM2B_TIMEOUT& timeout,
21580                             const TPM2B_DIGEST& cp_hash_a,
21581                             const TPM2B_NONCE& policy_ref,
21582                             const TPM2B_NAME& auth_name,
21583                             const TPMT_TK_AUTH& ticket,
21584                             AuthorizationDelegate* authorization_delegate) {
21585  VLOG(1) << __func__;
21586  std::string command;
21587  TPM_RC rc = SerializeCommand_PolicyTicket(
21588      policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21589      auth_name, ticket, &command, authorization_delegate);
21590  if (rc != TPM_RC_SUCCESS) {
21591    return rc;
21592  }
21593  std::string response = transceiver_->SendCommandAndWait(command);
21594  rc = ParseResponse_PolicyTicket(response, authorization_delegate);
21595  return rc;
21596}
21597
21598TPM_RC Tpm::SerializeCommand_PolicyOR(
21599    const TPMI_SH_POLICY& policy_session,
21600    const std::string& policy_session_name,
21601    const TPML_DIGEST& p_hash_list,
21602    std::string* serialized_command,
21603    AuthorizationDelegate* authorization_delegate) {
21604  VLOG(3) << __func__;
21605  TPM_RC rc = TPM_RC_SUCCESS;
21606  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21607  UINT32 command_size = 10;  // Header size.
21608  std::string handle_section_bytes;
21609  std::string parameter_section_bytes;
21610  TPM_CC command_code = TPM_CC_PolicyOR;
21611  bool is_command_parameter_encryption_possible = false;
21612  bool is_response_parameter_encryption_possible = false;
21613  std::string command_code_bytes;
21614  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21615  if (rc != TPM_RC_SUCCESS) {
21616    return rc;
21617  }
21618  std::string policy_session_bytes;
21619  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21620  if (rc != TPM_RC_SUCCESS) {
21621    return rc;
21622  }
21623  std::string p_hash_list_bytes;
21624  rc = Serialize_TPML_DIGEST(p_hash_list, &p_hash_list_bytes);
21625  if (rc != TPM_RC_SUCCESS) {
21626    return rc;
21627  }
21628  std::unique_ptr<crypto::SecureHash> hash(
21629      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21630  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21631  hash->Update(policy_session_name.data(), policy_session_name.size());
21632  handle_section_bytes += policy_session_bytes;
21633  command_size += policy_session_bytes.size();
21634  hash->Update(p_hash_list_bytes.data(), p_hash_list_bytes.size());
21635  parameter_section_bytes += p_hash_list_bytes;
21636  command_size += p_hash_list_bytes.size();
21637  std::string command_hash(32, 0);
21638  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
21639  std::string authorization_section_bytes;
21640  std::string authorization_size_bytes;
21641  if (authorization_delegate) {
21642    if (!authorization_delegate->GetCommandAuthorization(
21643            command_hash, is_command_parameter_encryption_possible,
21644            is_response_parameter_encryption_possible,
21645            &authorization_section_bytes)) {
21646      return TRUNKS_RC_AUTHORIZATION_FAILED;
21647    }
21648    if (!authorization_section_bytes.empty()) {
21649      tag = TPM_ST_SESSIONS;
21650      std::string tmp;
21651      rc = Serialize_UINT32(authorization_section_bytes.size(),
21652                            &authorization_size_bytes);
21653      if (rc != TPM_RC_SUCCESS) {
21654        return rc;
21655      }
21656      command_size +=
21657          authorization_size_bytes.size() + authorization_section_bytes.size();
21658    }
21659  }
21660  std::string tag_bytes;
21661  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21662  if (rc != TPM_RC_SUCCESS) {
21663    return rc;
21664  }
21665  std::string command_size_bytes;
21666  rc = Serialize_UINT32(command_size, &command_size_bytes);
21667  if (rc != TPM_RC_SUCCESS) {
21668    return rc;
21669  }
21670  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21671                        handle_section_bytes + authorization_size_bytes +
21672                        authorization_section_bytes + parameter_section_bytes;
21673  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21674  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
21675                                            serialized_command->size());
21676  return TPM_RC_SUCCESS;
21677}
21678
21679TPM_RC Tpm::ParseResponse_PolicyOR(
21680    const std::string& response,
21681    AuthorizationDelegate* authorization_delegate) {
21682  VLOG(3) << __func__;
21683  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21684  TPM_RC rc = TPM_RC_SUCCESS;
21685  std::string buffer(response);
21686  TPM_ST tag;
21687  std::string tag_bytes;
21688  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21689  if (rc != TPM_RC_SUCCESS) {
21690    return rc;
21691  }
21692  UINT32 response_size;
21693  std::string response_size_bytes;
21694  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21695  if (rc != TPM_RC_SUCCESS) {
21696    return rc;
21697  }
21698  TPM_RC response_code;
21699  std::string response_code_bytes;
21700  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21701  if (rc != TPM_RC_SUCCESS) {
21702    return rc;
21703  }
21704  if (response_size != response.size()) {
21705    return TPM_RC_SIZE;
21706  }
21707  if (response_code != TPM_RC_SUCCESS) {
21708    return response_code;
21709  }
21710  TPM_CC command_code = TPM_CC_PolicyOR;
21711  std::string command_code_bytes;
21712  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21713  if (rc != TPM_RC_SUCCESS) {
21714    return rc;
21715  }
21716  std::string authorization_section_bytes;
21717  if (tag == TPM_ST_SESSIONS) {
21718    UINT32 parameter_section_size = buffer.size();
21719    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21720    if (rc != TPM_RC_SUCCESS) {
21721      return rc;
21722    }
21723    if (parameter_section_size > buffer.size()) {
21724      return TPM_RC_INSUFFICIENT;
21725    }
21726    authorization_section_bytes = buffer.substr(parameter_section_size);
21727    // Keep the parameter section in |buffer|.
21728    buffer.erase(parameter_section_size);
21729  }
21730  std::unique_ptr<crypto::SecureHash> hash(
21731      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21732  hash->Update(response_code_bytes.data(), response_code_bytes.size());
21733  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21734  hash->Update(buffer.data(), buffer.size());
21735  std::string response_hash(32, 0);
21736  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
21737  if (tag == TPM_ST_SESSIONS) {
21738    CHECK(authorization_delegate) << "Authorization delegate missing!";
21739    if (!authorization_delegate->CheckResponseAuthorization(
21740            response_hash, authorization_section_bytes)) {
21741      return TRUNKS_RC_AUTHORIZATION_FAILED;
21742    }
21743  }
21744  return TPM_RC_SUCCESS;
21745}
21746
21747void PolicyORErrorCallback(const Tpm::PolicyORResponse& callback,
21748                           TPM_RC response_code) {
21749  VLOG(1) << __func__;
21750  callback.Run(response_code);
21751}
21752
21753void PolicyORResponseParser(const Tpm::PolicyORResponse& callback,
21754                            AuthorizationDelegate* authorization_delegate,
21755                            const std::string& response) {
21756  VLOG(1) << __func__;
21757  base::Callback<void(TPM_RC)> error_reporter =
21758      base::Bind(PolicyORErrorCallback, callback);
21759  TPM_RC rc = Tpm::ParseResponse_PolicyOR(response, authorization_delegate);
21760  if (rc != TPM_RC_SUCCESS) {
21761    error_reporter.Run(rc);
21762    return;
21763  }
21764  callback.Run(rc);
21765}
21766
21767void Tpm::PolicyOR(const TPMI_SH_POLICY& policy_session,
21768                   const std::string& policy_session_name,
21769                   const TPML_DIGEST& p_hash_list,
21770                   AuthorizationDelegate* authorization_delegate,
21771                   const PolicyORResponse& callback) {
21772  VLOG(1) << __func__;
21773  base::Callback<void(TPM_RC)> error_reporter =
21774      base::Bind(PolicyORErrorCallback, callback);
21775  base::Callback<void(const std::string&)> parser =
21776      base::Bind(PolicyORResponseParser, callback, authorization_delegate);
21777  std::string command;
21778  TPM_RC rc =
21779      SerializeCommand_PolicyOR(policy_session, policy_session_name,
21780                                p_hash_list, &command, authorization_delegate);
21781  if (rc != TPM_RC_SUCCESS) {
21782    error_reporter.Run(rc);
21783    return;
21784  }
21785  transceiver_->SendCommand(command, parser);
21786}
21787
21788TPM_RC Tpm::PolicyORSync(const TPMI_SH_POLICY& policy_session,
21789                         const std::string& policy_session_name,
21790                         const TPML_DIGEST& p_hash_list,
21791                         AuthorizationDelegate* authorization_delegate) {
21792  VLOG(1) << __func__;
21793  std::string command;
21794  TPM_RC rc =
21795      SerializeCommand_PolicyOR(policy_session, policy_session_name,
21796                                p_hash_list, &command, authorization_delegate);
21797  if (rc != TPM_RC_SUCCESS) {
21798    return rc;
21799  }
21800  std::string response = transceiver_->SendCommandAndWait(command);
21801  rc = ParseResponse_PolicyOR(response, authorization_delegate);
21802  return rc;
21803}
21804
21805TPM_RC Tpm::SerializeCommand_PolicyPCR(
21806    const TPMI_SH_POLICY& policy_session,
21807    const std::string& policy_session_name,
21808    const TPM2B_DIGEST& pcr_digest,
21809    const TPML_PCR_SELECTION& pcrs,
21810    std::string* serialized_command,
21811    AuthorizationDelegate* authorization_delegate) {
21812  VLOG(3) << __func__;
21813  TPM_RC rc = TPM_RC_SUCCESS;
21814  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21815  UINT32 command_size = 10;  // Header size.
21816  std::string handle_section_bytes;
21817  std::string parameter_section_bytes;
21818  TPM_CC command_code = TPM_CC_PolicyPCR;
21819  bool is_command_parameter_encryption_possible = true;
21820  bool is_response_parameter_encryption_possible = false;
21821  std::string command_code_bytes;
21822  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21823  if (rc != TPM_RC_SUCCESS) {
21824    return rc;
21825  }
21826  std::string policy_session_bytes;
21827  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21828  if (rc != TPM_RC_SUCCESS) {
21829    return rc;
21830  }
21831  std::string pcr_digest_bytes;
21832  rc = Serialize_TPM2B_DIGEST(pcr_digest, &pcr_digest_bytes);
21833  if (rc != TPM_RC_SUCCESS) {
21834    return rc;
21835  }
21836  std::string pcrs_bytes;
21837  rc = Serialize_TPML_PCR_SELECTION(pcrs, &pcrs_bytes);
21838  if (rc != TPM_RC_SUCCESS) {
21839    return rc;
21840  }
21841  if (authorization_delegate) {
21842    // Encrypt just the parameter data, not the size.
21843    std::string tmp = pcr_digest_bytes.substr(2);
21844    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21845      return TRUNKS_RC_ENCRYPTION_FAILED;
21846    }
21847    pcr_digest_bytes.replace(2, std::string::npos, tmp);
21848  }
21849  std::unique_ptr<crypto::SecureHash> hash(
21850      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21851  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21852  hash->Update(policy_session_name.data(), policy_session_name.size());
21853  handle_section_bytes += policy_session_bytes;
21854  command_size += policy_session_bytes.size();
21855  hash->Update(pcr_digest_bytes.data(), pcr_digest_bytes.size());
21856  parameter_section_bytes += pcr_digest_bytes;
21857  command_size += pcr_digest_bytes.size();
21858  hash->Update(pcrs_bytes.data(), pcrs_bytes.size());
21859  parameter_section_bytes += pcrs_bytes;
21860  command_size += pcrs_bytes.size();
21861  std::string command_hash(32, 0);
21862  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
21863  std::string authorization_section_bytes;
21864  std::string authorization_size_bytes;
21865  if (authorization_delegate) {
21866    if (!authorization_delegate->GetCommandAuthorization(
21867            command_hash, is_command_parameter_encryption_possible,
21868            is_response_parameter_encryption_possible,
21869            &authorization_section_bytes)) {
21870      return TRUNKS_RC_AUTHORIZATION_FAILED;
21871    }
21872    if (!authorization_section_bytes.empty()) {
21873      tag = TPM_ST_SESSIONS;
21874      std::string tmp;
21875      rc = Serialize_UINT32(authorization_section_bytes.size(),
21876                            &authorization_size_bytes);
21877      if (rc != TPM_RC_SUCCESS) {
21878        return rc;
21879      }
21880      command_size +=
21881          authorization_size_bytes.size() + authorization_section_bytes.size();
21882    }
21883  }
21884  std::string tag_bytes;
21885  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21886  if (rc != TPM_RC_SUCCESS) {
21887    return rc;
21888  }
21889  std::string command_size_bytes;
21890  rc = Serialize_UINT32(command_size, &command_size_bytes);
21891  if (rc != TPM_RC_SUCCESS) {
21892    return rc;
21893  }
21894  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21895                        handle_section_bytes + authorization_size_bytes +
21896                        authorization_section_bytes + parameter_section_bytes;
21897  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21898  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
21899                                            serialized_command->size());
21900  return TPM_RC_SUCCESS;
21901}
21902
21903TPM_RC Tpm::ParseResponse_PolicyPCR(
21904    const std::string& response,
21905    AuthorizationDelegate* authorization_delegate) {
21906  VLOG(3) << __func__;
21907  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21908  TPM_RC rc = TPM_RC_SUCCESS;
21909  std::string buffer(response);
21910  TPM_ST tag;
21911  std::string tag_bytes;
21912  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21913  if (rc != TPM_RC_SUCCESS) {
21914    return rc;
21915  }
21916  UINT32 response_size;
21917  std::string response_size_bytes;
21918  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21919  if (rc != TPM_RC_SUCCESS) {
21920    return rc;
21921  }
21922  TPM_RC response_code;
21923  std::string response_code_bytes;
21924  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21925  if (rc != TPM_RC_SUCCESS) {
21926    return rc;
21927  }
21928  if (response_size != response.size()) {
21929    return TPM_RC_SIZE;
21930  }
21931  if (response_code != TPM_RC_SUCCESS) {
21932    return response_code;
21933  }
21934  TPM_CC command_code = TPM_CC_PolicyPCR;
21935  std::string command_code_bytes;
21936  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21937  if (rc != TPM_RC_SUCCESS) {
21938    return rc;
21939  }
21940  std::string authorization_section_bytes;
21941  if (tag == TPM_ST_SESSIONS) {
21942    UINT32 parameter_section_size = buffer.size();
21943    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21944    if (rc != TPM_RC_SUCCESS) {
21945      return rc;
21946    }
21947    if (parameter_section_size > buffer.size()) {
21948      return TPM_RC_INSUFFICIENT;
21949    }
21950    authorization_section_bytes = buffer.substr(parameter_section_size);
21951    // Keep the parameter section in |buffer|.
21952    buffer.erase(parameter_section_size);
21953  }
21954  std::unique_ptr<crypto::SecureHash> hash(
21955      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21956  hash->Update(response_code_bytes.data(), response_code_bytes.size());
21957  hash->Update(command_code_bytes.data(), command_code_bytes.size());
21958  hash->Update(buffer.data(), buffer.size());
21959  std::string response_hash(32, 0);
21960  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
21961  if (tag == TPM_ST_SESSIONS) {
21962    CHECK(authorization_delegate) << "Authorization delegate missing!";
21963    if (!authorization_delegate->CheckResponseAuthorization(
21964            response_hash, authorization_section_bytes)) {
21965      return TRUNKS_RC_AUTHORIZATION_FAILED;
21966    }
21967  }
21968  return TPM_RC_SUCCESS;
21969}
21970
21971void PolicyPCRErrorCallback(const Tpm::PolicyPCRResponse& callback,
21972                            TPM_RC response_code) {
21973  VLOG(1) << __func__;
21974  callback.Run(response_code);
21975}
21976
21977void PolicyPCRResponseParser(const Tpm::PolicyPCRResponse& callback,
21978                             AuthorizationDelegate* authorization_delegate,
21979                             const std::string& response) {
21980  VLOG(1) << __func__;
21981  base::Callback<void(TPM_RC)> error_reporter =
21982      base::Bind(PolicyPCRErrorCallback, callback);
21983  TPM_RC rc = Tpm::ParseResponse_PolicyPCR(response, authorization_delegate);
21984  if (rc != TPM_RC_SUCCESS) {
21985    error_reporter.Run(rc);
21986    return;
21987  }
21988  callback.Run(rc);
21989}
21990
21991void Tpm::PolicyPCR(const TPMI_SH_POLICY& policy_session,
21992                    const std::string& policy_session_name,
21993                    const TPM2B_DIGEST& pcr_digest,
21994                    const TPML_PCR_SELECTION& pcrs,
21995                    AuthorizationDelegate* authorization_delegate,
21996                    const PolicyPCRResponse& callback) {
21997  VLOG(1) << __func__;
21998  base::Callback<void(TPM_RC)> error_reporter =
21999      base::Bind(PolicyPCRErrorCallback, callback);
22000  base::Callback<void(const std::string&)> parser =
22001      base::Bind(PolicyPCRResponseParser, callback, authorization_delegate);
22002  std::string command;
22003  TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22004                                         pcr_digest, pcrs, &command,
22005                                         authorization_delegate);
22006  if (rc != TPM_RC_SUCCESS) {
22007    error_reporter.Run(rc);
22008    return;
22009  }
22010  transceiver_->SendCommand(command, parser);
22011}
22012
22013TPM_RC Tpm::PolicyPCRSync(const TPMI_SH_POLICY& policy_session,
22014                          const std::string& policy_session_name,
22015                          const TPM2B_DIGEST& pcr_digest,
22016                          const TPML_PCR_SELECTION& pcrs,
22017                          AuthorizationDelegate* authorization_delegate) {
22018  VLOG(1) << __func__;
22019  std::string command;
22020  TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22021                                         pcr_digest, pcrs, &command,
22022                                         authorization_delegate);
22023  if (rc != TPM_RC_SUCCESS) {
22024    return rc;
22025  }
22026  std::string response = transceiver_->SendCommandAndWait(command);
22027  rc = ParseResponse_PolicyPCR(response, authorization_delegate);
22028  return rc;
22029}
22030
22031TPM_RC Tpm::SerializeCommand_PolicyLocality(
22032    const TPMI_SH_POLICY& policy_session,
22033    const std::string& policy_session_name,
22034    const TPMA_LOCALITY& locality,
22035    std::string* serialized_command,
22036    AuthorizationDelegate* authorization_delegate) {
22037  VLOG(3) << __func__;
22038  TPM_RC rc = TPM_RC_SUCCESS;
22039  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22040  UINT32 command_size = 10;  // Header size.
22041  std::string handle_section_bytes;
22042  std::string parameter_section_bytes;
22043  TPM_CC command_code = TPM_CC_PolicyLocality;
22044  bool is_command_parameter_encryption_possible = false;
22045  bool is_response_parameter_encryption_possible = false;
22046  std::string command_code_bytes;
22047  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22048  if (rc != TPM_RC_SUCCESS) {
22049    return rc;
22050  }
22051  std::string policy_session_bytes;
22052  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22053  if (rc != TPM_RC_SUCCESS) {
22054    return rc;
22055  }
22056  std::string locality_bytes;
22057  rc = Serialize_TPMA_LOCALITY(locality, &locality_bytes);
22058  if (rc != TPM_RC_SUCCESS) {
22059    return rc;
22060  }
22061  std::unique_ptr<crypto::SecureHash> hash(
22062      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22063  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22064  hash->Update(policy_session_name.data(), policy_session_name.size());
22065  handle_section_bytes += policy_session_bytes;
22066  command_size += policy_session_bytes.size();
22067  hash->Update(locality_bytes.data(), locality_bytes.size());
22068  parameter_section_bytes += locality_bytes;
22069  command_size += locality_bytes.size();
22070  std::string command_hash(32, 0);
22071  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
22072  std::string authorization_section_bytes;
22073  std::string authorization_size_bytes;
22074  if (authorization_delegate) {
22075    if (!authorization_delegate->GetCommandAuthorization(
22076            command_hash, is_command_parameter_encryption_possible,
22077            is_response_parameter_encryption_possible,
22078            &authorization_section_bytes)) {
22079      return TRUNKS_RC_AUTHORIZATION_FAILED;
22080    }
22081    if (!authorization_section_bytes.empty()) {
22082      tag = TPM_ST_SESSIONS;
22083      std::string tmp;
22084      rc = Serialize_UINT32(authorization_section_bytes.size(),
22085                            &authorization_size_bytes);
22086      if (rc != TPM_RC_SUCCESS) {
22087        return rc;
22088      }
22089      command_size +=
22090          authorization_size_bytes.size() + authorization_section_bytes.size();
22091    }
22092  }
22093  std::string tag_bytes;
22094  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22095  if (rc != TPM_RC_SUCCESS) {
22096    return rc;
22097  }
22098  std::string command_size_bytes;
22099  rc = Serialize_UINT32(command_size, &command_size_bytes);
22100  if (rc != TPM_RC_SUCCESS) {
22101    return rc;
22102  }
22103  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22104                        handle_section_bytes + authorization_size_bytes +
22105                        authorization_section_bytes + parameter_section_bytes;
22106  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22107  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
22108                                            serialized_command->size());
22109  return TPM_RC_SUCCESS;
22110}
22111
22112TPM_RC Tpm::ParseResponse_PolicyLocality(
22113    const std::string& response,
22114    AuthorizationDelegate* authorization_delegate) {
22115  VLOG(3) << __func__;
22116  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22117  TPM_RC rc = TPM_RC_SUCCESS;
22118  std::string buffer(response);
22119  TPM_ST tag;
22120  std::string tag_bytes;
22121  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22122  if (rc != TPM_RC_SUCCESS) {
22123    return rc;
22124  }
22125  UINT32 response_size;
22126  std::string response_size_bytes;
22127  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22128  if (rc != TPM_RC_SUCCESS) {
22129    return rc;
22130  }
22131  TPM_RC response_code;
22132  std::string response_code_bytes;
22133  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22134  if (rc != TPM_RC_SUCCESS) {
22135    return rc;
22136  }
22137  if (response_size != response.size()) {
22138    return TPM_RC_SIZE;
22139  }
22140  if (response_code != TPM_RC_SUCCESS) {
22141    return response_code;
22142  }
22143  TPM_CC command_code = TPM_CC_PolicyLocality;
22144  std::string command_code_bytes;
22145  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22146  if (rc != TPM_RC_SUCCESS) {
22147    return rc;
22148  }
22149  std::string authorization_section_bytes;
22150  if (tag == TPM_ST_SESSIONS) {
22151    UINT32 parameter_section_size = buffer.size();
22152    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22153    if (rc != TPM_RC_SUCCESS) {
22154      return rc;
22155    }
22156    if (parameter_section_size > buffer.size()) {
22157      return TPM_RC_INSUFFICIENT;
22158    }
22159    authorization_section_bytes = buffer.substr(parameter_section_size);
22160    // Keep the parameter section in |buffer|.
22161    buffer.erase(parameter_section_size);
22162  }
22163  std::unique_ptr<crypto::SecureHash> hash(
22164      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22165  hash->Update(response_code_bytes.data(), response_code_bytes.size());
22166  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22167  hash->Update(buffer.data(), buffer.size());
22168  std::string response_hash(32, 0);
22169  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
22170  if (tag == TPM_ST_SESSIONS) {
22171    CHECK(authorization_delegate) << "Authorization delegate missing!";
22172    if (!authorization_delegate->CheckResponseAuthorization(
22173            response_hash, authorization_section_bytes)) {
22174      return TRUNKS_RC_AUTHORIZATION_FAILED;
22175    }
22176  }
22177  return TPM_RC_SUCCESS;
22178}
22179
22180void PolicyLocalityErrorCallback(const Tpm::PolicyLocalityResponse& callback,
22181                                 TPM_RC response_code) {
22182  VLOG(1) << __func__;
22183  callback.Run(response_code);
22184}
22185
22186void PolicyLocalityResponseParser(const Tpm::PolicyLocalityResponse& callback,
22187                                  AuthorizationDelegate* authorization_delegate,
22188                                  const std::string& response) {
22189  VLOG(1) << __func__;
22190  base::Callback<void(TPM_RC)> error_reporter =
22191      base::Bind(PolicyLocalityErrorCallback, callback);
22192  TPM_RC rc =
22193      Tpm::ParseResponse_PolicyLocality(response, authorization_delegate);
22194  if (rc != TPM_RC_SUCCESS) {
22195    error_reporter.Run(rc);
22196    return;
22197  }
22198  callback.Run(rc);
22199}
22200
22201void Tpm::PolicyLocality(const TPMI_SH_POLICY& policy_session,
22202                         const std::string& policy_session_name,
22203                         const TPMA_LOCALITY& locality,
22204                         AuthorizationDelegate* authorization_delegate,
22205                         const PolicyLocalityResponse& callback) {
22206  VLOG(1) << __func__;
22207  base::Callback<void(TPM_RC)> error_reporter =
22208      base::Bind(PolicyLocalityErrorCallback, callback);
22209  base::Callback<void(const std::string&)> parser = base::Bind(
22210      PolicyLocalityResponseParser, callback, authorization_delegate);
22211  std::string command;
22212  TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22213                                              policy_session_name, locality,
22214                                              &command, authorization_delegate);
22215  if (rc != TPM_RC_SUCCESS) {
22216    error_reporter.Run(rc);
22217    return;
22218  }
22219  transceiver_->SendCommand(command, parser);
22220}
22221
22222TPM_RC Tpm::PolicyLocalitySync(const TPMI_SH_POLICY& policy_session,
22223                               const std::string& policy_session_name,
22224                               const TPMA_LOCALITY& locality,
22225                               AuthorizationDelegate* authorization_delegate) {
22226  VLOG(1) << __func__;
22227  std::string command;
22228  TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22229                                              policy_session_name, locality,
22230                                              &command, authorization_delegate);
22231  if (rc != TPM_RC_SUCCESS) {
22232    return rc;
22233  }
22234  std::string response = transceiver_->SendCommandAndWait(command);
22235  rc = ParseResponse_PolicyLocality(response, authorization_delegate);
22236  return rc;
22237}
22238
22239TPM_RC Tpm::SerializeCommand_PolicyNV(
22240    const TPMI_RH_NV_AUTH& auth_handle,
22241    const std::string& auth_handle_name,
22242    const TPMI_RH_NV_INDEX& nv_index,
22243    const std::string& nv_index_name,
22244    const TPMI_SH_POLICY& policy_session,
22245    const std::string& policy_session_name,
22246    const TPM2B_OPERAND& operand_b,
22247    const UINT16& offset,
22248    const TPM_EO& operation,
22249    std::string* serialized_command,
22250    AuthorizationDelegate* authorization_delegate) {
22251  VLOG(3) << __func__;
22252  TPM_RC rc = TPM_RC_SUCCESS;
22253  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22254  UINT32 command_size = 10;  // Header size.
22255  std::string handle_section_bytes;
22256  std::string parameter_section_bytes;
22257  TPM_CC command_code = TPM_CC_PolicyNV;
22258  bool is_command_parameter_encryption_possible = true;
22259  bool is_response_parameter_encryption_possible = false;
22260  std::string command_code_bytes;
22261  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22262  if (rc != TPM_RC_SUCCESS) {
22263    return rc;
22264  }
22265  std::string auth_handle_bytes;
22266  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
22267  if (rc != TPM_RC_SUCCESS) {
22268    return rc;
22269  }
22270  std::string nv_index_bytes;
22271  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
22272  if (rc != TPM_RC_SUCCESS) {
22273    return rc;
22274  }
22275  std::string policy_session_bytes;
22276  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22277  if (rc != TPM_RC_SUCCESS) {
22278    return rc;
22279  }
22280  std::string operand_b_bytes;
22281  rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22282  if (rc != TPM_RC_SUCCESS) {
22283    return rc;
22284  }
22285  std::string offset_bytes;
22286  rc = Serialize_UINT16(offset, &offset_bytes);
22287  if (rc != TPM_RC_SUCCESS) {
22288    return rc;
22289  }
22290  std::string operation_bytes;
22291  rc = Serialize_TPM_EO(operation, &operation_bytes);
22292  if (rc != TPM_RC_SUCCESS) {
22293    return rc;
22294  }
22295  if (authorization_delegate) {
22296    // Encrypt just the parameter data, not the size.
22297    std::string tmp = operand_b_bytes.substr(2);
22298    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22299      return TRUNKS_RC_ENCRYPTION_FAILED;
22300    }
22301    operand_b_bytes.replace(2, std::string::npos, tmp);
22302  }
22303  std::unique_ptr<crypto::SecureHash> hash(
22304      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22305  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22306  hash->Update(auth_handle_name.data(), auth_handle_name.size());
22307  handle_section_bytes += auth_handle_bytes;
22308  command_size += auth_handle_bytes.size();
22309  hash->Update(nv_index_name.data(), nv_index_name.size());
22310  handle_section_bytes += nv_index_bytes;
22311  command_size += nv_index_bytes.size();
22312  hash->Update(policy_session_name.data(), policy_session_name.size());
22313  handle_section_bytes += policy_session_bytes;
22314  command_size += policy_session_bytes.size();
22315  hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22316  parameter_section_bytes += operand_b_bytes;
22317  command_size += operand_b_bytes.size();
22318  hash->Update(offset_bytes.data(), offset_bytes.size());
22319  parameter_section_bytes += offset_bytes;
22320  command_size += offset_bytes.size();
22321  hash->Update(operation_bytes.data(), operation_bytes.size());
22322  parameter_section_bytes += operation_bytes;
22323  command_size += operation_bytes.size();
22324  std::string command_hash(32, 0);
22325  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
22326  std::string authorization_section_bytes;
22327  std::string authorization_size_bytes;
22328  if (authorization_delegate) {
22329    if (!authorization_delegate->GetCommandAuthorization(
22330            command_hash, is_command_parameter_encryption_possible,
22331            is_response_parameter_encryption_possible,
22332            &authorization_section_bytes)) {
22333      return TRUNKS_RC_AUTHORIZATION_FAILED;
22334    }
22335    if (!authorization_section_bytes.empty()) {
22336      tag = TPM_ST_SESSIONS;
22337      std::string tmp;
22338      rc = Serialize_UINT32(authorization_section_bytes.size(),
22339                            &authorization_size_bytes);
22340      if (rc != TPM_RC_SUCCESS) {
22341        return rc;
22342      }
22343      command_size +=
22344          authorization_size_bytes.size() + authorization_section_bytes.size();
22345    }
22346  }
22347  std::string tag_bytes;
22348  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22349  if (rc != TPM_RC_SUCCESS) {
22350    return rc;
22351  }
22352  std::string command_size_bytes;
22353  rc = Serialize_UINT32(command_size, &command_size_bytes);
22354  if (rc != TPM_RC_SUCCESS) {
22355    return rc;
22356  }
22357  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22358                        handle_section_bytes + authorization_size_bytes +
22359                        authorization_section_bytes + parameter_section_bytes;
22360  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22361  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
22362                                            serialized_command->size());
22363  return TPM_RC_SUCCESS;
22364}
22365
22366TPM_RC Tpm::ParseResponse_PolicyNV(
22367    const std::string& response,
22368    AuthorizationDelegate* authorization_delegate) {
22369  VLOG(3) << __func__;
22370  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22371  TPM_RC rc = TPM_RC_SUCCESS;
22372  std::string buffer(response);
22373  TPM_ST tag;
22374  std::string tag_bytes;
22375  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22376  if (rc != TPM_RC_SUCCESS) {
22377    return rc;
22378  }
22379  UINT32 response_size;
22380  std::string response_size_bytes;
22381  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22382  if (rc != TPM_RC_SUCCESS) {
22383    return rc;
22384  }
22385  TPM_RC response_code;
22386  std::string response_code_bytes;
22387  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22388  if (rc != TPM_RC_SUCCESS) {
22389    return rc;
22390  }
22391  if (response_size != response.size()) {
22392    return TPM_RC_SIZE;
22393  }
22394  if (response_code != TPM_RC_SUCCESS) {
22395    return response_code;
22396  }
22397  TPM_CC command_code = TPM_CC_PolicyNV;
22398  std::string command_code_bytes;
22399  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22400  if (rc != TPM_RC_SUCCESS) {
22401    return rc;
22402  }
22403  std::string authorization_section_bytes;
22404  if (tag == TPM_ST_SESSIONS) {
22405    UINT32 parameter_section_size = buffer.size();
22406    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22407    if (rc != TPM_RC_SUCCESS) {
22408      return rc;
22409    }
22410    if (parameter_section_size > buffer.size()) {
22411      return TPM_RC_INSUFFICIENT;
22412    }
22413    authorization_section_bytes = buffer.substr(parameter_section_size);
22414    // Keep the parameter section in |buffer|.
22415    buffer.erase(parameter_section_size);
22416  }
22417  std::unique_ptr<crypto::SecureHash> hash(
22418      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22419  hash->Update(response_code_bytes.data(), response_code_bytes.size());
22420  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22421  hash->Update(buffer.data(), buffer.size());
22422  std::string response_hash(32, 0);
22423  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
22424  if (tag == TPM_ST_SESSIONS) {
22425    CHECK(authorization_delegate) << "Authorization delegate missing!";
22426    if (!authorization_delegate->CheckResponseAuthorization(
22427            response_hash, authorization_section_bytes)) {
22428      return TRUNKS_RC_AUTHORIZATION_FAILED;
22429    }
22430  }
22431  return TPM_RC_SUCCESS;
22432}
22433
22434void PolicyNVErrorCallback(const Tpm::PolicyNVResponse& callback,
22435                           TPM_RC response_code) {
22436  VLOG(1) << __func__;
22437  callback.Run(response_code);
22438}
22439
22440void PolicyNVResponseParser(const Tpm::PolicyNVResponse& callback,
22441                            AuthorizationDelegate* authorization_delegate,
22442                            const std::string& response) {
22443  VLOG(1) << __func__;
22444  base::Callback<void(TPM_RC)> error_reporter =
22445      base::Bind(PolicyNVErrorCallback, callback);
22446  TPM_RC rc = Tpm::ParseResponse_PolicyNV(response, authorization_delegate);
22447  if (rc != TPM_RC_SUCCESS) {
22448    error_reporter.Run(rc);
22449    return;
22450  }
22451  callback.Run(rc);
22452}
22453
22454void Tpm::PolicyNV(const TPMI_RH_NV_AUTH& auth_handle,
22455                   const std::string& auth_handle_name,
22456                   const TPMI_RH_NV_INDEX& nv_index,
22457                   const std::string& nv_index_name,
22458                   const TPMI_SH_POLICY& policy_session,
22459                   const std::string& policy_session_name,
22460                   const TPM2B_OPERAND& operand_b,
22461                   const UINT16& offset,
22462                   const TPM_EO& operation,
22463                   AuthorizationDelegate* authorization_delegate,
22464                   const PolicyNVResponse& callback) {
22465  VLOG(1) << __func__;
22466  base::Callback<void(TPM_RC)> error_reporter =
22467      base::Bind(PolicyNVErrorCallback, callback);
22468  base::Callback<void(const std::string&)> parser =
22469      base::Bind(PolicyNVResponseParser, callback, authorization_delegate);
22470  std::string command;
22471  TPM_RC rc = SerializeCommand_PolicyNV(
22472      auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22473      policy_session_name, operand_b, offset, operation, &command,
22474      authorization_delegate);
22475  if (rc != TPM_RC_SUCCESS) {
22476    error_reporter.Run(rc);
22477    return;
22478  }
22479  transceiver_->SendCommand(command, parser);
22480}
22481
22482TPM_RC Tpm::PolicyNVSync(const TPMI_RH_NV_AUTH& auth_handle,
22483                         const std::string& auth_handle_name,
22484                         const TPMI_RH_NV_INDEX& nv_index,
22485                         const std::string& nv_index_name,
22486                         const TPMI_SH_POLICY& policy_session,
22487                         const std::string& policy_session_name,
22488                         const TPM2B_OPERAND& operand_b,
22489                         const UINT16& offset,
22490                         const TPM_EO& operation,
22491                         AuthorizationDelegate* authorization_delegate) {
22492  VLOG(1) << __func__;
22493  std::string command;
22494  TPM_RC rc = SerializeCommand_PolicyNV(
22495      auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22496      policy_session_name, operand_b, offset, operation, &command,
22497      authorization_delegate);
22498  if (rc != TPM_RC_SUCCESS) {
22499    return rc;
22500  }
22501  std::string response = transceiver_->SendCommandAndWait(command);
22502  rc = ParseResponse_PolicyNV(response, authorization_delegate);
22503  return rc;
22504}
22505
22506TPM_RC Tpm::SerializeCommand_PolicyCounterTimer(
22507    const TPMI_SH_POLICY& policy_session,
22508    const std::string& policy_session_name,
22509    const TPM2B_OPERAND& operand_b,
22510    const UINT16& offset,
22511    const TPM_EO& operation,
22512    std::string* serialized_command,
22513    AuthorizationDelegate* authorization_delegate) {
22514  VLOG(3) << __func__;
22515  TPM_RC rc = TPM_RC_SUCCESS;
22516  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22517  UINT32 command_size = 10;  // Header size.
22518  std::string handle_section_bytes;
22519  std::string parameter_section_bytes;
22520  TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22521  bool is_command_parameter_encryption_possible = true;
22522  bool is_response_parameter_encryption_possible = false;
22523  std::string command_code_bytes;
22524  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22525  if (rc != TPM_RC_SUCCESS) {
22526    return rc;
22527  }
22528  std::string policy_session_bytes;
22529  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22530  if (rc != TPM_RC_SUCCESS) {
22531    return rc;
22532  }
22533  std::string operand_b_bytes;
22534  rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22535  if (rc != TPM_RC_SUCCESS) {
22536    return rc;
22537  }
22538  std::string offset_bytes;
22539  rc = Serialize_UINT16(offset, &offset_bytes);
22540  if (rc != TPM_RC_SUCCESS) {
22541    return rc;
22542  }
22543  std::string operation_bytes;
22544  rc = Serialize_TPM_EO(operation, &operation_bytes);
22545  if (rc != TPM_RC_SUCCESS) {
22546    return rc;
22547  }
22548  if (authorization_delegate) {
22549    // Encrypt just the parameter data, not the size.
22550    std::string tmp = operand_b_bytes.substr(2);
22551    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22552      return TRUNKS_RC_ENCRYPTION_FAILED;
22553    }
22554    operand_b_bytes.replace(2, std::string::npos, tmp);
22555  }
22556  std::unique_ptr<crypto::SecureHash> hash(
22557      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22558  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22559  hash->Update(policy_session_name.data(), policy_session_name.size());
22560  handle_section_bytes += policy_session_bytes;
22561  command_size += policy_session_bytes.size();
22562  hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22563  parameter_section_bytes += operand_b_bytes;
22564  command_size += operand_b_bytes.size();
22565  hash->Update(offset_bytes.data(), offset_bytes.size());
22566  parameter_section_bytes += offset_bytes;
22567  command_size += offset_bytes.size();
22568  hash->Update(operation_bytes.data(), operation_bytes.size());
22569  parameter_section_bytes += operation_bytes;
22570  command_size += operation_bytes.size();
22571  std::string command_hash(32, 0);
22572  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
22573  std::string authorization_section_bytes;
22574  std::string authorization_size_bytes;
22575  if (authorization_delegate) {
22576    if (!authorization_delegate->GetCommandAuthorization(
22577            command_hash, is_command_parameter_encryption_possible,
22578            is_response_parameter_encryption_possible,
22579            &authorization_section_bytes)) {
22580      return TRUNKS_RC_AUTHORIZATION_FAILED;
22581    }
22582    if (!authorization_section_bytes.empty()) {
22583      tag = TPM_ST_SESSIONS;
22584      std::string tmp;
22585      rc = Serialize_UINT32(authorization_section_bytes.size(),
22586                            &authorization_size_bytes);
22587      if (rc != TPM_RC_SUCCESS) {
22588        return rc;
22589      }
22590      command_size +=
22591          authorization_size_bytes.size() + authorization_section_bytes.size();
22592    }
22593  }
22594  std::string tag_bytes;
22595  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22596  if (rc != TPM_RC_SUCCESS) {
22597    return rc;
22598  }
22599  std::string command_size_bytes;
22600  rc = Serialize_UINT32(command_size, &command_size_bytes);
22601  if (rc != TPM_RC_SUCCESS) {
22602    return rc;
22603  }
22604  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22605                        handle_section_bytes + authorization_size_bytes +
22606                        authorization_section_bytes + parameter_section_bytes;
22607  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22608  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
22609                                            serialized_command->size());
22610  return TPM_RC_SUCCESS;
22611}
22612
22613TPM_RC Tpm::ParseResponse_PolicyCounterTimer(
22614    const std::string& response,
22615    AuthorizationDelegate* authorization_delegate) {
22616  VLOG(3) << __func__;
22617  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22618  TPM_RC rc = TPM_RC_SUCCESS;
22619  std::string buffer(response);
22620  TPM_ST tag;
22621  std::string tag_bytes;
22622  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22623  if (rc != TPM_RC_SUCCESS) {
22624    return rc;
22625  }
22626  UINT32 response_size;
22627  std::string response_size_bytes;
22628  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22629  if (rc != TPM_RC_SUCCESS) {
22630    return rc;
22631  }
22632  TPM_RC response_code;
22633  std::string response_code_bytes;
22634  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22635  if (rc != TPM_RC_SUCCESS) {
22636    return rc;
22637  }
22638  if (response_size != response.size()) {
22639    return TPM_RC_SIZE;
22640  }
22641  if (response_code != TPM_RC_SUCCESS) {
22642    return response_code;
22643  }
22644  TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22645  std::string command_code_bytes;
22646  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22647  if (rc != TPM_RC_SUCCESS) {
22648    return rc;
22649  }
22650  std::string authorization_section_bytes;
22651  if (tag == TPM_ST_SESSIONS) {
22652    UINT32 parameter_section_size = buffer.size();
22653    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22654    if (rc != TPM_RC_SUCCESS) {
22655      return rc;
22656    }
22657    if (parameter_section_size > buffer.size()) {
22658      return TPM_RC_INSUFFICIENT;
22659    }
22660    authorization_section_bytes = buffer.substr(parameter_section_size);
22661    // Keep the parameter section in |buffer|.
22662    buffer.erase(parameter_section_size);
22663  }
22664  std::unique_ptr<crypto::SecureHash> hash(
22665      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22666  hash->Update(response_code_bytes.data(), response_code_bytes.size());
22667  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22668  hash->Update(buffer.data(), buffer.size());
22669  std::string response_hash(32, 0);
22670  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
22671  if (tag == TPM_ST_SESSIONS) {
22672    CHECK(authorization_delegate) << "Authorization delegate missing!";
22673    if (!authorization_delegate->CheckResponseAuthorization(
22674            response_hash, authorization_section_bytes)) {
22675      return TRUNKS_RC_AUTHORIZATION_FAILED;
22676    }
22677  }
22678  return TPM_RC_SUCCESS;
22679}
22680
22681void PolicyCounterTimerErrorCallback(
22682    const Tpm::PolicyCounterTimerResponse& callback,
22683    TPM_RC response_code) {
22684  VLOG(1) << __func__;
22685  callback.Run(response_code);
22686}
22687
22688void PolicyCounterTimerResponseParser(
22689    const Tpm::PolicyCounterTimerResponse& callback,
22690    AuthorizationDelegate* authorization_delegate,
22691    const std::string& response) {
22692  VLOG(1) << __func__;
22693  base::Callback<void(TPM_RC)> error_reporter =
22694      base::Bind(PolicyCounterTimerErrorCallback, callback);
22695  TPM_RC rc =
22696      Tpm::ParseResponse_PolicyCounterTimer(response, authorization_delegate);
22697  if (rc != TPM_RC_SUCCESS) {
22698    error_reporter.Run(rc);
22699    return;
22700  }
22701  callback.Run(rc);
22702}
22703
22704void Tpm::PolicyCounterTimer(const TPMI_SH_POLICY& policy_session,
22705                             const std::string& policy_session_name,
22706                             const TPM2B_OPERAND& operand_b,
22707                             const UINT16& offset,
22708                             const TPM_EO& operation,
22709                             AuthorizationDelegate* authorization_delegate,
22710                             const PolicyCounterTimerResponse& callback) {
22711  VLOG(1) << __func__;
22712  base::Callback<void(TPM_RC)> error_reporter =
22713      base::Bind(PolicyCounterTimerErrorCallback, callback);
22714  base::Callback<void(const std::string&)> parser = base::Bind(
22715      PolicyCounterTimerResponseParser, callback, authorization_delegate);
22716  std::string command;
22717  TPM_RC rc = SerializeCommand_PolicyCounterTimer(
22718      policy_session, policy_session_name, operand_b, offset, operation,
22719      &command, authorization_delegate);
22720  if (rc != TPM_RC_SUCCESS) {
22721    error_reporter.Run(rc);
22722    return;
22723  }
22724  transceiver_->SendCommand(command, parser);
22725}
22726
22727TPM_RC Tpm::PolicyCounterTimerSync(
22728    const TPMI_SH_POLICY& policy_session,
22729    const std::string& policy_session_name,
22730    const TPM2B_OPERAND& operand_b,
22731    const UINT16& offset,
22732    const TPM_EO& operation,
22733    AuthorizationDelegate* authorization_delegate) {
22734  VLOG(1) << __func__;
22735  std::string command;
22736  TPM_RC rc = SerializeCommand_PolicyCounterTimer(
22737      policy_session, policy_session_name, operand_b, offset, operation,
22738      &command, authorization_delegate);
22739  if (rc != TPM_RC_SUCCESS) {
22740    return rc;
22741  }
22742  std::string response = transceiver_->SendCommandAndWait(command);
22743  rc = ParseResponse_PolicyCounterTimer(response, authorization_delegate);
22744  return rc;
22745}
22746
22747TPM_RC Tpm::SerializeCommand_PolicyCommandCode(
22748    const TPMI_SH_POLICY& policy_session,
22749    const std::string& policy_session_name,
22750    const TPM_CC& code,
22751    std::string* serialized_command,
22752    AuthorizationDelegate* authorization_delegate) {
22753  VLOG(3) << __func__;
22754  TPM_RC rc = TPM_RC_SUCCESS;
22755  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22756  UINT32 command_size = 10;  // Header size.
22757  std::string handle_section_bytes;
22758  std::string parameter_section_bytes;
22759  TPM_CC command_code = TPM_CC_PolicyCommandCode;
22760  bool is_command_parameter_encryption_possible = false;
22761  bool is_response_parameter_encryption_possible = false;
22762  std::string command_code_bytes;
22763  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22764  if (rc != TPM_RC_SUCCESS) {
22765    return rc;
22766  }
22767  std::string policy_session_bytes;
22768  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22769  if (rc != TPM_RC_SUCCESS) {
22770    return rc;
22771  }
22772  std::string code_bytes;
22773  rc = Serialize_TPM_CC(code, &code_bytes);
22774  if (rc != TPM_RC_SUCCESS) {
22775    return rc;
22776  }
22777  std::unique_ptr<crypto::SecureHash> hash(
22778      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22779  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22780  hash->Update(policy_session_name.data(), policy_session_name.size());
22781  handle_section_bytes += policy_session_bytes;
22782  command_size += policy_session_bytes.size();
22783  hash->Update(code_bytes.data(), code_bytes.size());
22784  parameter_section_bytes += code_bytes;
22785  command_size += code_bytes.size();
22786  std::string command_hash(32, 0);
22787  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
22788  std::string authorization_section_bytes;
22789  std::string authorization_size_bytes;
22790  if (authorization_delegate) {
22791    if (!authorization_delegate->GetCommandAuthorization(
22792            command_hash, is_command_parameter_encryption_possible,
22793            is_response_parameter_encryption_possible,
22794            &authorization_section_bytes)) {
22795      return TRUNKS_RC_AUTHORIZATION_FAILED;
22796    }
22797    if (!authorization_section_bytes.empty()) {
22798      tag = TPM_ST_SESSIONS;
22799      std::string tmp;
22800      rc = Serialize_UINT32(authorization_section_bytes.size(),
22801                            &authorization_size_bytes);
22802      if (rc != TPM_RC_SUCCESS) {
22803        return rc;
22804      }
22805      command_size +=
22806          authorization_size_bytes.size() + authorization_section_bytes.size();
22807    }
22808  }
22809  std::string tag_bytes;
22810  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22811  if (rc != TPM_RC_SUCCESS) {
22812    return rc;
22813  }
22814  std::string command_size_bytes;
22815  rc = Serialize_UINT32(command_size, &command_size_bytes);
22816  if (rc != TPM_RC_SUCCESS) {
22817    return rc;
22818  }
22819  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22820                        handle_section_bytes + authorization_size_bytes +
22821                        authorization_section_bytes + parameter_section_bytes;
22822  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22823  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
22824                                            serialized_command->size());
22825  return TPM_RC_SUCCESS;
22826}
22827
22828TPM_RC Tpm::ParseResponse_PolicyCommandCode(
22829    const std::string& response,
22830    AuthorizationDelegate* authorization_delegate) {
22831  VLOG(3) << __func__;
22832  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22833  TPM_RC rc = TPM_RC_SUCCESS;
22834  std::string buffer(response);
22835  TPM_ST tag;
22836  std::string tag_bytes;
22837  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22838  if (rc != TPM_RC_SUCCESS) {
22839    return rc;
22840  }
22841  UINT32 response_size;
22842  std::string response_size_bytes;
22843  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22844  if (rc != TPM_RC_SUCCESS) {
22845    return rc;
22846  }
22847  TPM_RC response_code;
22848  std::string response_code_bytes;
22849  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22850  if (rc != TPM_RC_SUCCESS) {
22851    return rc;
22852  }
22853  if (response_size != response.size()) {
22854    return TPM_RC_SIZE;
22855  }
22856  if (response_code != TPM_RC_SUCCESS) {
22857    return response_code;
22858  }
22859  TPM_CC command_code = TPM_CC_PolicyCommandCode;
22860  std::string command_code_bytes;
22861  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22862  if (rc != TPM_RC_SUCCESS) {
22863    return rc;
22864  }
22865  std::string authorization_section_bytes;
22866  if (tag == TPM_ST_SESSIONS) {
22867    UINT32 parameter_section_size = buffer.size();
22868    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22869    if (rc != TPM_RC_SUCCESS) {
22870      return rc;
22871    }
22872    if (parameter_section_size > buffer.size()) {
22873      return TPM_RC_INSUFFICIENT;
22874    }
22875    authorization_section_bytes = buffer.substr(parameter_section_size);
22876    // Keep the parameter section in |buffer|.
22877    buffer.erase(parameter_section_size);
22878  }
22879  std::unique_ptr<crypto::SecureHash> hash(
22880      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22881  hash->Update(response_code_bytes.data(), response_code_bytes.size());
22882  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22883  hash->Update(buffer.data(), buffer.size());
22884  std::string response_hash(32, 0);
22885  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
22886  if (tag == TPM_ST_SESSIONS) {
22887    CHECK(authorization_delegate) << "Authorization delegate missing!";
22888    if (!authorization_delegate->CheckResponseAuthorization(
22889            response_hash, authorization_section_bytes)) {
22890      return TRUNKS_RC_AUTHORIZATION_FAILED;
22891    }
22892  }
22893  return TPM_RC_SUCCESS;
22894}
22895
22896void PolicyCommandCodeErrorCallback(
22897    const Tpm::PolicyCommandCodeResponse& callback,
22898    TPM_RC response_code) {
22899  VLOG(1) << __func__;
22900  callback.Run(response_code);
22901}
22902
22903void PolicyCommandCodeResponseParser(
22904    const Tpm::PolicyCommandCodeResponse& callback,
22905    AuthorizationDelegate* authorization_delegate,
22906    const std::string& response) {
22907  VLOG(1) << __func__;
22908  base::Callback<void(TPM_RC)> error_reporter =
22909      base::Bind(PolicyCommandCodeErrorCallback, callback);
22910  TPM_RC rc =
22911      Tpm::ParseResponse_PolicyCommandCode(response, authorization_delegate);
22912  if (rc != TPM_RC_SUCCESS) {
22913    error_reporter.Run(rc);
22914    return;
22915  }
22916  callback.Run(rc);
22917}
22918
22919void Tpm::PolicyCommandCode(const TPMI_SH_POLICY& policy_session,
22920                            const std::string& policy_session_name,
22921                            const TPM_CC& code,
22922                            AuthorizationDelegate* authorization_delegate,
22923                            const PolicyCommandCodeResponse& callback) {
22924  VLOG(1) << __func__;
22925  base::Callback<void(TPM_RC)> error_reporter =
22926      base::Bind(PolicyCommandCodeErrorCallback, callback);
22927  base::Callback<void(const std::string&)> parser = base::Bind(
22928      PolicyCommandCodeResponseParser, callback, authorization_delegate);
22929  std::string command;
22930  TPM_RC rc = SerializeCommand_PolicyCommandCode(
22931      policy_session, policy_session_name, code, &command,
22932      authorization_delegate);
22933  if (rc != TPM_RC_SUCCESS) {
22934    error_reporter.Run(rc);
22935    return;
22936  }
22937  transceiver_->SendCommand(command, parser);
22938}
22939
22940TPM_RC Tpm::PolicyCommandCodeSync(
22941    const TPMI_SH_POLICY& policy_session,
22942    const std::string& policy_session_name,
22943    const TPM_CC& code,
22944    AuthorizationDelegate* authorization_delegate) {
22945  VLOG(1) << __func__;
22946  std::string command;
22947  TPM_RC rc = SerializeCommand_PolicyCommandCode(
22948      policy_session, policy_session_name, code, &command,
22949      authorization_delegate);
22950  if (rc != TPM_RC_SUCCESS) {
22951    return rc;
22952  }
22953  std::string response = transceiver_->SendCommandAndWait(command);
22954  rc = ParseResponse_PolicyCommandCode(response, authorization_delegate);
22955  return rc;
22956}
22957
22958TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence(
22959    const TPMI_SH_POLICY& policy_session,
22960    const std::string& policy_session_name,
22961    std::string* serialized_command,
22962    AuthorizationDelegate* authorization_delegate) {
22963  VLOG(3) << __func__;
22964  TPM_RC rc = TPM_RC_SUCCESS;
22965  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22966  UINT32 command_size = 10;  // Header size.
22967  std::string handle_section_bytes;
22968  std::string parameter_section_bytes;
22969  TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
22970  bool is_command_parameter_encryption_possible = false;
22971  bool is_response_parameter_encryption_possible = false;
22972  std::string command_code_bytes;
22973  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22974  if (rc != TPM_RC_SUCCESS) {
22975    return rc;
22976  }
22977  std::string policy_session_bytes;
22978  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22979  if (rc != TPM_RC_SUCCESS) {
22980    return rc;
22981  }
22982  std::unique_ptr<crypto::SecureHash> hash(
22983      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22984  hash->Update(command_code_bytes.data(), command_code_bytes.size());
22985  hash->Update(policy_session_name.data(), policy_session_name.size());
22986  handle_section_bytes += policy_session_bytes;
22987  command_size += policy_session_bytes.size();
22988  std::string command_hash(32, 0);
22989  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
22990  std::string authorization_section_bytes;
22991  std::string authorization_size_bytes;
22992  if (authorization_delegate) {
22993    if (!authorization_delegate->GetCommandAuthorization(
22994            command_hash, is_command_parameter_encryption_possible,
22995            is_response_parameter_encryption_possible,
22996            &authorization_section_bytes)) {
22997      return TRUNKS_RC_AUTHORIZATION_FAILED;
22998    }
22999    if (!authorization_section_bytes.empty()) {
23000      tag = TPM_ST_SESSIONS;
23001      std::string tmp;
23002      rc = Serialize_UINT32(authorization_section_bytes.size(),
23003                            &authorization_size_bytes);
23004      if (rc != TPM_RC_SUCCESS) {
23005        return rc;
23006      }
23007      command_size +=
23008          authorization_size_bytes.size() + authorization_section_bytes.size();
23009    }
23010  }
23011  std::string tag_bytes;
23012  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23013  if (rc != TPM_RC_SUCCESS) {
23014    return rc;
23015  }
23016  std::string command_size_bytes;
23017  rc = Serialize_UINT32(command_size, &command_size_bytes);
23018  if (rc != TPM_RC_SUCCESS) {
23019    return rc;
23020  }
23021  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23022                        handle_section_bytes + authorization_size_bytes +
23023                        authorization_section_bytes + parameter_section_bytes;
23024  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23025  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
23026                                            serialized_command->size());
23027  return TPM_RC_SUCCESS;
23028}
23029
23030TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence(
23031    const std::string& response,
23032    AuthorizationDelegate* authorization_delegate) {
23033  VLOG(3) << __func__;
23034  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23035  TPM_RC rc = TPM_RC_SUCCESS;
23036  std::string buffer(response);
23037  TPM_ST tag;
23038  std::string tag_bytes;
23039  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23040  if (rc != TPM_RC_SUCCESS) {
23041    return rc;
23042  }
23043  UINT32 response_size;
23044  std::string response_size_bytes;
23045  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23046  if (rc != TPM_RC_SUCCESS) {
23047    return rc;
23048  }
23049  TPM_RC response_code;
23050  std::string response_code_bytes;
23051  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23052  if (rc != TPM_RC_SUCCESS) {
23053    return rc;
23054  }
23055  if (response_size != response.size()) {
23056    return TPM_RC_SIZE;
23057  }
23058  if (response_code != TPM_RC_SUCCESS) {
23059    return response_code;
23060  }
23061  TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23062  std::string command_code_bytes;
23063  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23064  if (rc != TPM_RC_SUCCESS) {
23065    return rc;
23066  }
23067  std::string authorization_section_bytes;
23068  if (tag == TPM_ST_SESSIONS) {
23069    UINT32 parameter_section_size = buffer.size();
23070    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23071    if (rc != TPM_RC_SUCCESS) {
23072      return rc;
23073    }
23074    if (parameter_section_size > buffer.size()) {
23075      return TPM_RC_INSUFFICIENT;
23076    }
23077    authorization_section_bytes = buffer.substr(parameter_section_size);
23078    // Keep the parameter section in |buffer|.
23079    buffer.erase(parameter_section_size);
23080  }
23081  std::unique_ptr<crypto::SecureHash> hash(
23082      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23083  hash->Update(response_code_bytes.data(), response_code_bytes.size());
23084  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23085  hash->Update(buffer.data(), buffer.size());
23086  std::string response_hash(32, 0);
23087  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
23088  if (tag == TPM_ST_SESSIONS) {
23089    CHECK(authorization_delegate) << "Authorization delegate missing!";
23090    if (!authorization_delegate->CheckResponseAuthorization(
23091            response_hash, authorization_section_bytes)) {
23092      return TRUNKS_RC_AUTHORIZATION_FAILED;
23093    }
23094  }
23095  return TPM_RC_SUCCESS;
23096}
23097
23098void PolicyPhysicalPresenceErrorCallback(
23099    const Tpm::PolicyPhysicalPresenceResponse& callback,
23100    TPM_RC response_code) {
23101  VLOG(1) << __func__;
23102  callback.Run(response_code);
23103}
23104
23105void PolicyPhysicalPresenceResponseParser(
23106    const Tpm::PolicyPhysicalPresenceResponse& callback,
23107    AuthorizationDelegate* authorization_delegate,
23108    const std::string& response) {
23109  VLOG(1) << __func__;
23110  base::Callback<void(TPM_RC)> error_reporter =
23111      base::Bind(PolicyPhysicalPresenceErrorCallback, callback);
23112  TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence(response,
23113                                                        authorization_delegate);
23114  if (rc != TPM_RC_SUCCESS) {
23115    error_reporter.Run(rc);
23116    return;
23117  }
23118  callback.Run(rc);
23119}
23120
23121void Tpm::PolicyPhysicalPresence(
23122    const TPMI_SH_POLICY& policy_session,
23123    const std::string& policy_session_name,
23124    AuthorizationDelegate* authorization_delegate,
23125    const PolicyPhysicalPresenceResponse& callback) {
23126  VLOG(1) << __func__;
23127  base::Callback<void(TPM_RC)> error_reporter =
23128      base::Bind(PolicyPhysicalPresenceErrorCallback, callback);
23129  base::Callback<void(const std::string&)> parser = base::Bind(
23130      PolicyPhysicalPresenceResponseParser, callback, authorization_delegate);
23131  std::string command;
23132  TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23133      policy_session, policy_session_name, &command, authorization_delegate);
23134  if (rc != TPM_RC_SUCCESS) {
23135    error_reporter.Run(rc);
23136    return;
23137  }
23138  transceiver_->SendCommand(command, parser);
23139}
23140
23141TPM_RC Tpm::PolicyPhysicalPresenceSync(
23142    const TPMI_SH_POLICY& policy_session,
23143    const std::string& policy_session_name,
23144    AuthorizationDelegate* authorization_delegate) {
23145  VLOG(1) << __func__;
23146  std::string command;
23147  TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23148      policy_session, policy_session_name, &command, authorization_delegate);
23149  if (rc != TPM_RC_SUCCESS) {
23150    return rc;
23151  }
23152  std::string response = transceiver_->SendCommandAndWait(command);
23153  rc = ParseResponse_PolicyPhysicalPresence(response, authorization_delegate);
23154  return rc;
23155}
23156
23157TPM_RC Tpm::SerializeCommand_PolicyCpHash(
23158    const TPMI_SH_POLICY& policy_session,
23159    const std::string& policy_session_name,
23160    const TPM2B_DIGEST& cp_hash_a,
23161    std::string* serialized_command,
23162    AuthorizationDelegate* authorization_delegate) {
23163  VLOG(3) << __func__;
23164  TPM_RC rc = TPM_RC_SUCCESS;
23165  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23166  UINT32 command_size = 10;  // Header size.
23167  std::string handle_section_bytes;
23168  std::string parameter_section_bytes;
23169  TPM_CC command_code = TPM_CC_PolicyCpHash;
23170  bool is_command_parameter_encryption_possible = true;
23171  bool is_response_parameter_encryption_possible = false;
23172  std::string command_code_bytes;
23173  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23174  if (rc != TPM_RC_SUCCESS) {
23175    return rc;
23176  }
23177  std::string policy_session_bytes;
23178  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23179  if (rc != TPM_RC_SUCCESS) {
23180    return rc;
23181  }
23182  std::string cp_hash_a_bytes;
23183  rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
23184  if (rc != TPM_RC_SUCCESS) {
23185    return rc;
23186  }
23187  if (authorization_delegate) {
23188    // Encrypt just the parameter data, not the size.
23189    std::string tmp = cp_hash_a_bytes.substr(2);
23190    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23191      return TRUNKS_RC_ENCRYPTION_FAILED;
23192    }
23193    cp_hash_a_bytes.replace(2, std::string::npos, tmp);
23194  }
23195  std::unique_ptr<crypto::SecureHash> hash(
23196      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23197  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23198  hash->Update(policy_session_name.data(), policy_session_name.size());
23199  handle_section_bytes += policy_session_bytes;
23200  command_size += policy_session_bytes.size();
23201  hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
23202  parameter_section_bytes += cp_hash_a_bytes;
23203  command_size += cp_hash_a_bytes.size();
23204  std::string command_hash(32, 0);
23205  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
23206  std::string authorization_section_bytes;
23207  std::string authorization_size_bytes;
23208  if (authorization_delegate) {
23209    if (!authorization_delegate->GetCommandAuthorization(
23210            command_hash, is_command_parameter_encryption_possible,
23211            is_response_parameter_encryption_possible,
23212            &authorization_section_bytes)) {
23213      return TRUNKS_RC_AUTHORIZATION_FAILED;
23214    }
23215    if (!authorization_section_bytes.empty()) {
23216      tag = TPM_ST_SESSIONS;
23217      std::string tmp;
23218      rc = Serialize_UINT32(authorization_section_bytes.size(),
23219                            &authorization_size_bytes);
23220      if (rc != TPM_RC_SUCCESS) {
23221        return rc;
23222      }
23223      command_size +=
23224          authorization_size_bytes.size() + authorization_section_bytes.size();
23225    }
23226  }
23227  std::string tag_bytes;
23228  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23229  if (rc != TPM_RC_SUCCESS) {
23230    return rc;
23231  }
23232  std::string command_size_bytes;
23233  rc = Serialize_UINT32(command_size, &command_size_bytes);
23234  if (rc != TPM_RC_SUCCESS) {
23235    return rc;
23236  }
23237  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23238                        handle_section_bytes + authorization_size_bytes +
23239                        authorization_section_bytes + parameter_section_bytes;
23240  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23241  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
23242                                            serialized_command->size());
23243  return TPM_RC_SUCCESS;
23244}
23245
23246TPM_RC Tpm::ParseResponse_PolicyCpHash(
23247    const std::string& response,
23248    AuthorizationDelegate* authorization_delegate) {
23249  VLOG(3) << __func__;
23250  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23251  TPM_RC rc = TPM_RC_SUCCESS;
23252  std::string buffer(response);
23253  TPM_ST tag;
23254  std::string tag_bytes;
23255  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23256  if (rc != TPM_RC_SUCCESS) {
23257    return rc;
23258  }
23259  UINT32 response_size;
23260  std::string response_size_bytes;
23261  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23262  if (rc != TPM_RC_SUCCESS) {
23263    return rc;
23264  }
23265  TPM_RC response_code;
23266  std::string response_code_bytes;
23267  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23268  if (rc != TPM_RC_SUCCESS) {
23269    return rc;
23270  }
23271  if (response_size != response.size()) {
23272    return TPM_RC_SIZE;
23273  }
23274  if (response_code != TPM_RC_SUCCESS) {
23275    return response_code;
23276  }
23277  TPM_CC command_code = TPM_CC_PolicyCpHash;
23278  std::string command_code_bytes;
23279  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23280  if (rc != TPM_RC_SUCCESS) {
23281    return rc;
23282  }
23283  std::string authorization_section_bytes;
23284  if (tag == TPM_ST_SESSIONS) {
23285    UINT32 parameter_section_size = buffer.size();
23286    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23287    if (rc != TPM_RC_SUCCESS) {
23288      return rc;
23289    }
23290    if (parameter_section_size > buffer.size()) {
23291      return TPM_RC_INSUFFICIENT;
23292    }
23293    authorization_section_bytes = buffer.substr(parameter_section_size);
23294    // Keep the parameter section in |buffer|.
23295    buffer.erase(parameter_section_size);
23296  }
23297  std::unique_ptr<crypto::SecureHash> hash(
23298      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23299  hash->Update(response_code_bytes.data(), response_code_bytes.size());
23300  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23301  hash->Update(buffer.data(), buffer.size());
23302  std::string response_hash(32, 0);
23303  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
23304  if (tag == TPM_ST_SESSIONS) {
23305    CHECK(authorization_delegate) << "Authorization delegate missing!";
23306    if (!authorization_delegate->CheckResponseAuthorization(
23307            response_hash, authorization_section_bytes)) {
23308      return TRUNKS_RC_AUTHORIZATION_FAILED;
23309    }
23310  }
23311  return TPM_RC_SUCCESS;
23312}
23313
23314void PolicyCpHashErrorCallback(const Tpm::PolicyCpHashResponse& callback,
23315                               TPM_RC response_code) {
23316  VLOG(1) << __func__;
23317  callback.Run(response_code);
23318}
23319
23320void PolicyCpHashResponseParser(const Tpm::PolicyCpHashResponse& callback,
23321                                AuthorizationDelegate* authorization_delegate,
23322                                const std::string& response) {
23323  VLOG(1) << __func__;
23324  base::Callback<void(TPM_RC)> error_reporter =
23325      base::Bind(PolicyCpHashErrorCallback, callback);
23326  TPM_RC rc = Tpm::ParseResponse_PolicyCpHash(response, authorization_delegate);
23327  if (rc != TPM_RC_SUCCESS) {
23328    error_reporter.Run(rc);
23329    return;
23330  }
23331  callback.Run(rc);
23332}
23333
23334void Tpm::PolicyCpHash(const TPMI_SH_POLICY& policy_session,
23335                       const std::string& policy_session_name,
23336                       const TPM2B_DIGEST& cp_hash_a,
23337                       AuthorizationDelegate* authorization_delegate,
23338                       const PolicyCpHashResponse& callback) {
23339  VLOG(1) << __func__;
23340  base::Callback<void(TPM_RC)> error_reporter =
23341      base::Bind(PolicyCpHashErrorCallback, callback);
23342  base::Callback<void(const std::string&)> parser =
23343      base::Bind(PolicyCpHashResponseParser, callback, authorization_delegate);
23344  std::string command;
23345  TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23346                                            cp_hash_a, &command,
23347                                            authorization_delegate);
23348  if (rc != TPM_RC_SUCCESS) {
23349    error_reporter.Run(rc);
23350    return;
23351  }
23352  transceiver_->SendCommand(command, parser);
23353}
23354
23355TPM_RC Tpm::PolicyCpHashSync(const TPMI_SH_POLICY& policy_session,
23356                             const std::string& policy_session_name,
23357                             const TPM2B_DIGEST& cp_hash_a,
23358                             AuthorizationDelegate* authorization_delegate) {
23359  VLOG(1) << __func__;
23360  std::string command;
23361  TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23362                                            cp_hash_a, &command,
23363                                            authorization_delegate);
23364  if (rc != TPM_RC_SUCCESS) {
23365    return rc;
23366  }
23367  std::string response = transceiver_->SendCommandAndWait(command);
23368  rc = ParseResponse_PolicyCpHash(response, authorization_delegate);
23369  return rc;
23370}
23371
23372TPM_RC Tpm::SerializeCommand_PolicyNameHash(
23373    const TPMI_SH_POLICY& policy_session,
23374    const std::string& policy_session_name,
23375    const TPM2B_DIGEST& name_hash,
23376    std::string* serialized_command,
23377    AuthorizationDelegate* authorization_delegate) {
23378  VLOG(3) << __func__;
23379  TPM_RC rc = TPM_RC_SUCCESS;
23380  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23381  UINT32 command_size = 10;  // Header size.
23382  std::string handle_section_bytes;
23383  std::string parameter_section_bytes;
23384  TPM_CC command_code = TPM_CC_PolicyNameHash;
23385  bool is_command_parameter_encryption_possible = true;
23386  bool is_response_parameter_encryption_possible = false;
23387  std::string command_code_bytes;
23388  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23389  if (rc != TPM_RC_SUCCESS) {
23390    return rc;
23391  }
23392  std::string policy_session_bytes;
23393  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23394  if (rc != TPM_RC_SUCCESS) {
23395    return rc;
23396  }
23397  std::string name_hash_bytes;
23398  rc = Serialize_TPM2B_DIGEST(name_hash, &name_hash_bytes);
23399  if (rc != TPM_RC_SUCCESS) {
23400    return rc;
23401  }
23402  if (authorization_delegate) {
23403    // Encrypt just the parameter data, not the size.
23404    std::string tmp = name_hash_bytes.substr(2);
23405    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23406      return TRUNKS_RC_ENCRYPTION_FAILED;
23407    }
23408    name_hash_bytes.replace(2, std::string::npos, tmp);
23409  }
23410  std::unique_ptr<crypto::SecureHash> hash(
23411      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23412  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23413  hash->Update(policy_session_name.data(), policy_session_name.size());
23414  handle_section_bytes += policy_session_bytes;
23415  command_size += policy_session_bytes.size();
23416  hash->Update(name_hash_bytes.data(), name_hash_bytes.size());
23417  parameter_section_bytes += name_hash_bytes;
23418  command_size += name_hash_bytes.size();
23419  std::string command_hash(32, 0);
23420  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
23421  std::string authorization_section_bytes;
23422  std::string authorization_size_bytes;
23423  if (authorization_delegate) {
23424    if (!authorization_delegate->GetCommandAuthorization(
23425            command_hash, is_command_parameter_encryption_possible,
23426            is_response_parameter_encryption_possible,
23427            &authorization_section_bytes)) {
23428      return TRUNKS_RC_AUTHORIZATION_FAILED;
23429    }
23430    if (!authorization_section_bytes.empty()) {
23431      tag = TPM_ST_SESSIONS;
23432      std::string tmp;
23433      rc = Serialize_UINT32(authorization_section_bytes.size(),
23434                            &authorization_size_bytes);
23435      if (rc != TPM_RC_SUCCESS) {
23436        return rc;
23437      }
23438      command_size +=
23439          authorization_size_bytes.size() + authorization_section_bytes.size();
23440    }
23441  }
23442  std::string tag_bytes;
23443  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23444  if (rc != TPM_RC_SUCCESS) {
23445    return rc;
23446  }
23447  std::string command_size_bytes;
23448  rc = Serialize_UINT32(command_size, &command_size_bytes);
23449  if (rc != TPM_RC_SUCCESS) {
23450    return rc;
23451  }
23452  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23453                        handle_section_bytes + authorization_size_bytes +
23454                        authorization_section_bytes + parameter_section_bytes;
23455  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23456  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
23457                                            serialized_command->size());
23458  return TPM_RC_SUCCESS;
23459}
23460
23461TPM_RC Tpm::ParseResponse_PolicyNameHash(
23462    const std::string& response,
23463    AuthorizationDelegate* authorization_delegate) {
23464  VLOG(3) << __func__;
23465  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23466  TPM_RC rc = TPM_RC_SUCCESS;
23467  std::string buffer(response);
23468  TPM_ST tag;
23469  std::string tag_bytes;
23470  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23471  if (rc != TPM_RC_SUCCESS) {
23472    return rc;
23473  }
23474  UINT32 response_size;
23475  std::string response_size_bytes;
23476  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23477  if (rc != TPM_RC_SUCCESS) {
23478    return rc;
23479  }
23480  TPM_RC response_code;
23481  std::string response_code_bytes;
23482  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23483  if (rc != TPM_RC_SUCCESS) {
23484    return rc;
23485  }
23486  if (response_size != response.size()) {
23487    return TPM_RC_SIZE;
23488  }
23489  if (response_code != TPM_RC_SUCCESS) {
23490    return response_code;
23491  }
23492  TPM_CC command_code = TPM_CC_PolicyNameHash;
23493  std::string command_code_bytes;
23494  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23495  if (rc != TPM_RC_SUCCESS) {
23496    return rc;
23497  }
23498  std::string authorization_section_bytes;
23499  if (tag == TPM_ST_SESSIONS) {
23500    UINT32 parameter_section_size = buffer.size();
23501    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23502    if (rc != TPM_RC_SUCCESS) {
23503      return rc;
23504    }
23505    if (parameter_section_size > buffer.size()) {
23506      return TPM_RC_INSUFFICIENT;
23507    }
23508    authorization_section_bytes = buffer.substr(parameter_section_size);
23509    // Keep the parameter section in |buffer|.
23510    buffer.erase(parameter_section_size);
23511  }
23512  std::unique_ptr<crypto::SecureHash> hash(
23513      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23514  hash->Update(response_code_bytes.data(), response_code_bytes.size());
23515  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23516  hash->Update(buffer.data(), buffer.size());
23517  std::string response_hash(32, 0);
23518  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
23519  if (tag == TPM_ST_SESSIONS) {
23520    CHECK(authorization_delegate) << "Authorization delegate missing!";
23521    if (!authorization_delegate->CheckResponseAuthorization(
23522            response_hash, authorization_section_bytes)) {
23523      return TRUNKS_RC_AUTHORIZATION_FAILED;
23524    }
23525  }
23526  return TPM_RC_SUCCESS;
23527}
23528
23529void PolicyNameHashErrorCallback(const Tpm::PolicyNameHashResponse& callback,
23530                                 TPM_RC response_code) {
23531  VLOG(1) << __func__;
23532  callback.Run(response_code);
23533}
23534
23535void PolicyNameHashResponseParser(const Tpm::PolicyNameHashResponse& callback,
23536                                  AuthorizationDelegate* authorization_delegate,
23537                                  const std::string& response) {
23538  VLOG(1) << __func__;
23539  base::Callback<void(TPM_RC)> error_reporter =
23540      base::Bind(PolicyNameHashErrorCallback, callback);
23541  TPM_RC rc =
23542      Tpm::ParseResponse_PolicyNameHash(response, authorization_delegate);
23543  if (rc != TPM_RC_SUCCESS) {
23544    error_reporter.Run(rc);
23545    return;
23546  }
23547  callback.Run(rc);
23548}
23549
23550void Tpm::PolicyNameHash(const TPMI_SH_POLICY& policy_session,
23551                         const std::string& policy_session_name,
23552                         const TPM2B_DIGEST& name_hash,
23553                         AuthorizationDelegate* authorization_delegate,
23554                         const PolicyNameHashResponse& callback) {
23555  VLOG(1) << __func__;
23556  base::Callback<void(TPM_RC)> error_reporter =
23557      base::Bind(PolicyNameHashErrorCallback, callback);
23558  base::Callback<void(const std::string&)> parser = base::Bind(
23559      PolicyNameHashResponseParser, callback, authorization_delegate);
23560  std::string command;
23561  TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23562                                              policy_session_name, name_hash,
23563                                              &command, authorization_delegate);
23564  if (rc != TPM_RC_SUCCESS) {
23565    error_reporter.Run(rc);
23566    return;
23567  }
23568  transceiver_->SendCommand(command, parser);
23569}
23570
23571TPM_RC Tpm::PolicyNameHashSync(const TPMI_SH_POLICY& policy_session,
23572                               const std::string& policy_session_name,
23573                               const TPM2B_DIGEST& name_hash,
23574                               AuthorizationDelegate* authorization_delegate) {
23575  VLOG(1) << __func__;
23576  std::string command;
23577  TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23578                                              policy_session_name, name_hash,
23579                                              &command, authorization_delegate);
23580  if (rc != TPM_RC_SUCCESS) {
23581    return rc;
23582  }
23583  std::string response = transceiver_->SendCommandAndWait(command);
23584  rc = ParseResponse_PolicyNameHash(response, authorization_delegate);
23585  return rc;
23586}
23587
23588TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect(
23589    const TPMI_SH_POLICY& policy_session,
23590    const std::string& policy_session_name,
23591    const TPM2B_NAME& object_name,
23592    const TPM2B_NAME& new_parent_name,
23593    const TPMI_YES_NO& include_object,
23594    std::string* serialized_command,
23595    AuthorizationDelegate* authorization_delegate) {
23596  VLOG(3) << __func__;
23597  TPM_RC rc = TPM_RC_SUCCESS;
23598  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23599  UINT32 command_size = 10;  // Header size.
23600  std::string handle_section_bytes;
23601  std::string parameter_section_bytes;
23602  TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23603  bool is_command_parameter_encryption_possible = true;
23604  bool is_response_parameter_encryption_possible = false;
23605  std::string command_code_bytes;
23606  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23607  if (rc != TPM_RC_SUCCESS) {
23608    return rc;
23609  }
23610  std::string policy_session_bytes;
23611  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23612  if (rc != TPM_RC_SUCCESS) {
23613    return rc;
23614  }
23615  std::string object_name_bytes;
23616  rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
23617  if (rc != TPM_RC_SUCCESS) {
23618    return rc;
23619  }
23620  std::string new_parent_name_bytes;
23621  rc = Serialize_TPM2B_NAME(new_parent_name, &new_parent_name_bytes);
23622  if (rc != TPM_RC_SUCCESS) {
23623    return rc;
23624  }
23625  std::string include_object_bytes;
23626  rc = Serialize_TPMI_YES_NO(include_object, &include_object_bytes);
23627  if (rc != TPM_RC_SUCCESS) {
23628    return rc;
23629  }
23630  if (authorization_delegate) {
23631    // Encrypt just the parameter data, not the size.
23632    std::string tmp = object_name_bytes.substr(2);
23633    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23634      return TRUNKS_RC_ENCRYPTION_FAILED;
23635    }
23636    object_name_bytes.replace(2, std::string::npos, tmp);
23637  }
23638  std::unique_ptr<crypto::SecureHash> hash(
23639      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23640  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23641  hash->Update(policy_session_name.data(), policy_session_name.size());
23642  handle_section_bytes += policy_session_bytes;
23643  command_size += policy_session_bytes.size();
23644  hash->Update(object_name_bytes.data(), object_name_bytes.size());
23645  parameter_section_bytes += object_name_bytes;
23646  command_size += object_name_bytes.size();
23647  hash->Update(new_parent_name_bytes.data(), new_parent_name_bytes.size());
23648  parameter_section_bytes += new_parent_name_bytes;
23649  command_size += new_parent_name_bytes.size();
23650  hash->Update(include_object_bytes.data(), include_object_bytes.size());
23651  parameter_section_bytes += include_object_bytes;
23652  command_size += include_object_bytes.size();
23653  std::string command_hash(32, 0);
23654  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
23655  std::string authorization_section_bytes;
23656  std::string authorization_size_bytes;
23657  if (authorization_delegate) {
23658    if (!authorization_delegate->GetCommandAuthorization(
23659            command_hash, is_command_parameter_encryption_possible,
23660            is_response_parameter_encryption_possible,
23661            &authorization_section_bytes)) {
23662      return TRUNKS_RC_AUTHORIZATION_FAILED;
23663    }
23664    if (!authorization_section_bytes.empty()) {
23665      tag = TPM_ST_SESSIONS;
23666      std::string tmp;
23667      rc = Serialize_UINT32(authorization_section_bytes.size(),
23668                            &authorization_size_bytes);
23669      if (rc != TPM_RC_SUCCESS) {
23670        return rc;
23671      }
23672      command_size +=
23673          authorization_size_bytes.size() + authorization_section_bytes.size();
23674    }
23675  }
23676  std::string tag_bytes;
23677  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23678  if (rc != TPM_RC_SUCCESS) {
23679    return rc;
23680  }
23681  std::string command_size_bytes;
23682  rc = Serialize_UINT32(command_size, &command_size_bytes);
23683  if (rc != TPM_RC_SUCCESS) {
23684    return rc;
23685  }
23686  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23687                        handle_section_bytes + authorization_size_bytes +
23688                        authorization_section_bytes + parameter_section_bytes;
23689  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23690  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
23691                                            serialized_command->size());
23692  return TPM_RC_SUCCESS;
23693}
23694
23695TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect(
23696    const std::string& response,
23697    AuthorizationDelegate* authorization_delegate) {
23698  VLOG(3) << __func__;
23699  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23700  TPM_RC rc = TPM_RC_SUCCESS;
23701  std::string buffer(response);
23702  TPM_ST tag;
23703  std::string tag_bytes;
23704  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23705  if (rc != TPM_RC_SUCCESS) {
23706    return rc;
23707  }
23708  UINT32 response_size;
23709  std::string response_size_bytes;
23710  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23711  if (rc != TPM_RC_SUCCESS) {
23712    return rc;
23713  }
23714  TPM_RC response_code;
23715  std::string response_code_bytes;
23716  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23717  if (rc != TPM_RC_SUCCESS) {
23718    return rc;
23719  }
23720  if (response_size != response.size()) {
23721    return TPM_RC_SIZE;
23722  }
23723  if (response_code != TPM_RC_SUCCESS) {
23724    return response_code;
23725  }
23726  TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23727  std::string command_code_bytes;
23728  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23729  if (rc != TPM_RC_SUCCESS) {
23730    return rc;
23731  }
23732  std::string authorization_section_bytes;
23733  if (tag == TPM_ST_SESSIONS) {
23734    UINT32 parameter_section_size = buffer.size();
23735    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23736    if (rc != TPM_RC_SUCCESS) {
23737      return rc;
23738    }
23739    if (parameter_section_size > buffer.size()) {
23740      return TPM_RC_INSUFFICIENT;
23741    }
23742    authorization_section_bytes = buffer.substr(parameter_section_size);
23743    // Keep the parameter section in |buffer|.
23744    buffer.erase(parameter_section_size);
23745  }
23746  std::unique_ptr<crypto::SecureHash> hash(
23747      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23748  hash->Update(response_code_bytes.data(), response_code_bytes.size());
23749  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23750  hash->Update(buffer.data(), buffer.size());
23751  std::string response_hash(32, 0);
23752  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
23753  if (tag == TPM_ST_SESSIONS) {
23754    CHECK(authorization_delegate) << "Authorization delegate missing!";
23755    if (!authorization_delegate->CheckResponseAuthorization(
23756            response_hash, authorization_section_bytes)) {
23757      return TRUNKS_RC_AUTHORIZATION_FAILED;
23758    }
23759  }
23760  return TPM_RC_SUCCESS;
23761}
23762
23763void PolicyDuplicationSelectErrorCallback(
23764    const Tpm::PolicyDuplicationSelectResponse& callback,
23765    TPM_RC response_code) {
23766  VLOG(1) << __func__;
23767  callback.Run(response_code);
23768}
23769
23770void PolicyDuplicationSelectResponseParser(
23771    const Tpm::PolicyDuplicationSelectResponse& callback,
23772    AuthorizationDelegate* authorization_delegate,
23773    const std::string& response) {
23774  VLOG(1) << __func__;
23775  base::Callback<void(TPM_RC)> error_reporter =
23776      base::Bind(PolicyDuplicationSelectErrorCallback, callback);
23777  TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect(
23778      response, authorization_delegate);
23779  if (rc != TPM_RC_SUCCESS) {
23780    error_reporter.Run(rc);
23781    return;
23782  }
23783  callback.Run(rc);
23784}
23785
23786void Tpm::PolicyDuplicationSelect(
23787    const TPMI_SH_POLICY& policy_session,
23788    const std::string& policy_session_name,
23789    const TPM2B_NAME& object_name,
23790    const TPM2B_NAME& new_parent_name,
23791    const TPMI_YES_NO& include_object,
23792    AuthorizationDelegate* authorization_delegate,
23793    const PolicyDuplicationSelectResponse& callback) {
23794  VLOG(1) << __func__;
23795  base::Callback<void(TPM_RC)> error_reporter =
23796      base::Bind(PolicyDuplicationSelectErrorCallback, callback);
23797  base::Callback<void(const std::string&)> parser = base::Bind(
23798      PolicyDuplicationSelectResponseParser, callback, authorization_delegate);
23799  std::string command;
23800  TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
23801      policy_session, policy_session_name, object_name, new_parent_name,
23802      include_object, &command, authorization_delegate);
23803  if (rc != TPM_RC_SUCCESS) {
23804    error_reporter.Run(rc);
23805    return;
23806  }
23807  transceiver_->SendCommand(command, parser);
23808}
23809
23810TPM_RC Tpm::PolicyDuplicationSelectSync(
23811    const TPMI_SH_POLICY& policy_session,
23812    const std::string& policy_session_name,
23813    const TPM2B_NAME& object_name,
23814    const TPM2B_NAME& new_parent_name,
23815    const TPMI_YES_NO& include_object,
23816    AuthorizationDelegate* authorization_delegate) {
23817  VLOG(1) << __func__;
23818  std::string command;
23819  TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
23820      policy_session, policy_session_name, object_name, new_parent_name,
23821      include_object, &command, authorization_delegate);
23822  if (rc != TPM_RC_SUCCESS) {
23823    return rc;
23824  }
23825  std::string response = transceiver_->SendCommandAndWait(command);
23826  rc = ParseResponse_PolicyDuplicationSelect(response, authorization_delegate);
23827  return rc;
23828}
23829
23830TPM_RC Tpm::SerializeCommand_PolicyAuthorize(
23831    const TPMI_SH_POLICY& policy_session,
23832    const std::string& policy_session_name,
23833    const TPM2B_DIGEST& approved_policy,
23834    const TPM2B_NONCE& policy_ref,
23835    const TPM2B_NAME& key_sign,
23836    const TPMT_TK_VERIFIED& check_ticket,
23837    std::string* serialized_command,
23838    AuthorizationDelegate* authorization_delegate) {
23839  VLOG(3) << __func__;
23840  TPM_RC rc = TPM_RC_SUCCESS;
23841  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23842  UINT32 command_size = 10;  // Header size.
23843  std::string handle_section_bytes;
23844  std::string parameter_section_bytes;
23845  TPM_CC command_code = TPM_CC_PolicyAuthorize;
23846  bool is_command_parameter_encryption_possible = true;
23847  bool is_response_parameter_encryption_possible = false;
23848  std::string command_code_bytes;
23849  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23850  if (rc != TPM_RC_SUCCESS) {
23851    return rc;
23852  }
23853  std::string policy_session_bytes;
23854  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23855  if (rc != TPM_RC_SUCCESS) {
23856    return rc;
23857  }
23858  std::string approved_policy_bytes;
23859  rc = Serialize_TPM2B_DIGEST(approved_policy, &approved_policy_bytes);
23860  if (rc != TPM_RC_SUCCESS) {
23861    return rc;
23862  }
23863  std::string policy_ref_bytes;
23864  rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
23865  if (rc != TPM_RC_SUCCESS) {
23866    return rc;
23867  }
23868  std::string key_sign_bytes;
23869  rc = Serialize_TPM2B_NAME(key_sign, &key_sign_bytes);
23870  if (rc != TPM_RC_SUCCESS) {
23871    return rc;
23872  }
23873  std::string check_ticket_bytes;
23874  rc = Serialize_TPMT_TK_VERIFIED(check_ticket, &check_ticket_bytes);
23875  if (rc != TPM_RC_SUCCESS) {
23876    return rc;
23877  }
23878  if (authorization_delegate) {
23879    // Encrypt just the parameter data, not the size.
23880    std::string tmp = approved_policy_bytes.substr(2);
23881    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23882      return TRUNKS_RC_ENCRYPTION_FAILED;
23883    }
23884    approved_policy_bytes.replace(2, std::string::npos, tmp);
23885  }
23886  std::unique_ptr<crypto::SecureHash> hash(
23887      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23888  hash->Update(command_code_bytes.data(), command_code_bytes.size());
23889  hash->Update(policy_session_name.data(), policy_session_name.size());
23890  handle_section_bytes += policy_session_bytes;
23891  command_size += policy_session_bytes.size();
23892  hash->Update(approved_policy_bytes.data(), approved_policy_bytes.size());
23893  parameter_section_bytes += approved_policy_bytes;
23894  command_size += approved_policy_bytes.size();
23895  hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
23896  parameter_section_bytes += policy_ref_bytes;
23897  command_size += policy_ref_bytes.size();
23898  hash->Update(key_sign_bytes.data(), key_sign_bytes.size());
23899  parameter_section_bytes += key_sign_bytes;
23900  command_size += key_sign_bytes.size();
23901  hash->Update(check_ticket_bytes.data(), check_ticket_bytes.size());
23902  parameter_section_bytes += check_ticket_bytes;
23903  command_size += check_ticket_bytes.size();
23904  std::string command_hash(32, 0);
23905  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
23906  std::string authorization_section_bytes;
23907  std::string authorization_size_bytes;
23908  if (authorization_delegate) {
23909    if (!authorization_delegate->GetCommandAuthorization(
23910            command_hash, is_command_parameter_encryption_possible,
23911            is_response_parameter_encryption_possible,
23912            &authorization_section_bytes)) {
23913      return TRUNKS_RC_AUTHORIZATION_FAILED;
23914    }
23915    if (!authorization_section_bytes.empty()) {
23916      tag = TPM_ST_SESSIONS;
23917      std::string tmp;
23918      rc = Serialize_UINT32(authorization_section_bytes.size(),
23919                            &authorization_size_bytes);
23920      if (rc != TPM_RC_SUCCESS) {
23921        return rc;
23922      }
23923      command_size +=
23924          authorization_size_bytes.size() + authorization_section_bytes.size();
23925    }
23926  }
23927  std::string tag_bytes;
23928  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23929  if (rc != TPM_RC_SUCCESS) {
23930    return rc;
23931  }
23932  std::string command_size_bytes;
23933  rc = Serialize_UINT32(command_size, &command_size_bytes);
23934  if (rc != TPM_RC_SUCCESS) {
23935    return rc;
23936  }
23937  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23938                        handle_section_bytes + authorization_size_bytes +
23939                        authorization_section_bytes + parameter_section_bytes;
23940  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23941  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
23942                                            serialized_command->size());
23943  return TPM_RC_SUCCESS;
23944}
23945
23946TPM_RC Tpm::ParseResponse_PolicyAuthorize(
23947    const std::string& response,
23948    AuthorizationDelegate* authorization_delegate) {
23949  VLOG(3) << __func__;
23950  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23951  TPM_RC rc = TPM_RC_SUCCESS;
23952  std::string buffer(response);
23953  TPM_ST tag;
23954  std::string tag_bytes;
23955  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23956  if (rc != TPM_RC_SUCCESS) {
23957    return rc;
23958  }
23959  UINT32 response_size;
23960  std::string response_size_bytes;
23961  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23962  if (rc != TPM_RC_SUCCESS) {
23963    return rc;
23964  }
23965  TPM_RC response_code;
23966  std::string response_code_bytes;
23967  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23968  if (rc != TPM_RC_SUCCESS) {
23969    return rc;
23970  }
23971  if (response_size != response.size()) {
23972    return TPM_RC_SIZE;
23973  }
23974  if (response_code != TPM_RC_SUCCESS) {
23975    return response_code;
23976  }
23977  TPM_CC command_code = TPM_CC_PolicyAuthorize;
23978  std::string command_code_bytes;
23979  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23980  if (rc != TPM_RC_SUCCESS) {
23981    return rc;
23982  }
23983  std::string authorization_section_bytes;
23984  if (tag == TPM_ST_SESSIONS) {
23985    UINT32 parameter_section_size = buffer.size();
23986    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23987    if (rc != TPM_RC_SUCCESS) {
23988      return rc;
23989    }
23990    if (parameter_section_size > buffer.size()) {
23991      return TPM_RC_INSUFFICIENT;
23992    }
23993    authorization_section_bytes = buffer.substr(parameter_section_size);
23994    // Keep the parameter section in |buffer|.
23995    buffer.erase(parameter_section_size);
23996  }
23997  std::unique_ptr<crypto::SecureHash> hash(
23998      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23999  hash->Update(response_code_bytes.data(), response_code_bytes.size());
24000  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24001  hash->Update(buffer.data(), buffer.size());
24002  std::string response_hash(32, 0);
24003  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
24004  if (tag == TPM_ST_SESSIONS) {
24005    CHECK(authorization_delegate) << "Authorization delegate missing!";
24006    if (!authorization_delegate->CheckResponseAuthorization(
24007            response_hash, authorization_section_bytes)) {
24008      return TRUNKS_RC_AUTHORIZATION_FAILED;
24009    }
24010  }
24011  return TPM_RC_SUCCESS;
24012}
24013
24014void PolicyAuthorizeErrorCallback(const Tpm::PolicyAuthorizeResponse& callback,
24015                                  TPM_RC response_code) {
24016  VLOG(1) << __func__;
24017  callback.Run(response_code);
24018}
24019
24020void PolicyAuthorizeResponseParser(
24021    const Tpm::PolicyAuthorizeResponse& callback,
24022    AuthorizationDelegate* authorization_delegate,
24023    const std::string& response) {
24024  VLOG(1) << __func__;
24025  base::Callback<void(TPM_RC)> error_reporter =
24026      base::Bind(PolicyAuthorizeErrorCallback, callback);
24027  TPM_RC rc =
24028      Tpm::ParseResponse_PolicyAuthorize(response, authorization_delegate);
24029  if (rc != TPM_RC_SUCCESS) {
24030    error_reporter.Run(rc);
24031    return;
24032  }
24033  callback.Run(rc);
24034}
24035
24036void Tpm::PolicyAuthorize(const TPMI_SH_POLICY& policy_session,
24037                          const std::string& policy_session_name,
24038                          const TPM2B_DIGEST& approved_policy,
24039                          const TPM2B_NONCE& policy_ref,
24040                          const TPM2B_NAME& key_sign,
24041                          const TPMT_TK_VERIFIED& check_ticket,
24042                          AuthorizationDelegate* authorization_delegate,
24043                          const PolicyAuthorizeResponse& callback) {
24044  VLOG(1) << __func__;
24045  base::Callback<void(TPM_RC)> error_reporter =
24046      base::Bind(PolicyAuthorizeErrorCallback, callback);
24047  base::Callback<void(const std::string&)> parser = base::Bind(
24048      PolicyAuthorizeResponseParser, callback, authorization_delegate);
24049  std::string command;
24050  TPM_RC rc = SerializeCommand_PolicyAuthorize(
24051      policy_session, policy_session_name, approved_policy, policy_ref,
24052      key_sign, check_ticket, &command, authorization_delegate);
24053  if (rc != TPM_RC_SUCCESS) {
24054    error_reporter.Run(rc);
24055    return;
24056  }
24057  transceiver_->SendCommand(command, parser);
24058}
24059
24060TPM_RC Tpm::PolicyAuthorizeSync(const TPMI_SH_POLICY& policy_session,
24061                                const std::string& policy_session_name,
24062                                const TPM2B_DIGEST& approved_policy,
24063                                const TPM2B_NONCE& policy_ref,
24064                                const TPM2B_NAME& key_sign,
24065                                const TPMT_TK_VERIFIED& check_ticket,
24066                                AuthorizationDelegate* authorization_delegate) {
24067  VLOG(1) << __func__;
24068  std::string command;
24069  TPM_RC rc = SerializeCommand_PolicyAuthorize(
24070      policy_session, policy_session_name, approved_policy, policy_ref,
24071      key_sign, check_ticket, &command, authorization_delegate);
24072  if (rc != TPM_RC_SUCCESS) {
24073    return rc;
24074  }
24075  std::string response = transceiver_->SendCommandAndWait(command);
24076  rc = ParseResponse_PolicyAuthorize(response, authorization_delegate);
24077  return rc;
24078}
24079
24080TPM_RC Tpm::SerializeCommand_PolicyAuthValue(
24081    const TPMI_SH_POLICY& policy_session,
24082    const std::string& policy_session_name,
24083    std::string* serialized_command,
24084    AuthorizationDelegate* authorization_delegate) {
24085  VLOG(3) << __func__;
24086  TPM_RC rc = TPM_RC_SUCCESS;
24087  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24088  UINT32 command_size = 10;  // Header size.
24089  std::string handle_section_bytes;
24090  std::string parameter_section_bytes;
24091  TPM_CC command_code = TPM_CC_PolicyAuthValue;
24092  bool is_command_parameter_encryption_possible = false;
24093  bool is_response_parameter_encryption_possible = false;
24094  std::string command_code_bytes;
24095  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24096  if (rc != TPM_RC_SUCCESS) {
24097    return rc;
24098  }
24099  std::string policy_session_bytes;
24100  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24101  if (rc != TPM_RC_SUCCESS) {
24102    return rc;
24103  }
24104  std::unique_ptr<crypto::SecureHash> hash(
24105      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24106  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24107  hash->Update(policy_session_name.data(), policy_session_name.size());
24108  handle_section_bytes += policy_session_bytes;
24109  command_size += policy_session_bytes.size();
24110  std::string command_hash(32, 0);
24111  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
24112  std::string authorization_section_bytes;
24113  std::string authorization_size_bytes;
24114  if (authorization_delegate) {
24115    if (!authorization_delegate->GetCommandAuthorization(
24116            command_hash, is_command_parameter_encryption_possible,
24117            is_response_parameter_encryption_possible,
24118            &authorization_section_bytes)) {
24119      return TRUNKS_RC_AUTHORIZATION_FAILED;
24120    }
24121    if (!authorization_section_bytes.empty()) {
24122      tag = TPM_ST_SESSIONS;
24123      std::string tmp;
24124      rc = Serialize_UINT32(authorization_section_bytes.size(),
24125                            &authorization_size_bytes);
24126      if (rc != TPM_RC_SUCCESS) {
24127        return rc;
24128      }
24129      command_size +=
24130          authorization_size_bytes.size() + authorization_section_bytes.size();
24131    }
24132  }
24133  std::string tag_bytes;
24134  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24135  if (rc != TPM_RC_SUCCESS) {
24136    return rc;
24137  }
24138  std::string command_size_bytes;
24139  rc = Serialize_UINT32(command_size, &command_size_bytes);
24140  if (rc != TPM_RC_SUCCESS) {
24141    return rc;
24142  }
24143  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24144                        handle_section_bytes + authorization_size_bytes +
24145                        authorization_section_bytes + parameter_section_bytes;
24146  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24147  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
24148                                            serialized_command->size());
24149  return TPM_RC_SUCCESS;
24150}
24151
24152TPM_RC Tpm::ParseResponse_PolicyAuthValue(
24153    const std::string& response,
24154    AuthorizationDelegate* authorization_delegate) {
24155  VLOG(3) << __func__;
24156  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24157  TPM_RC rc = TPM_RC_SUCCESS;
24158  std::string buffer(response);
24159  TPM_ST tag;
24160  std::string tag_bytes;
24161  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24162  if (rc != TPM_RC_SUCCESS) {
24163    return rc;
24164  }
24165  UINT32 response_size;
24166  std::string response_size_bytes;
24167  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24168  if (rc != TPM_RC_SUCCESS) {
24169    return rc;
24170  }
24171  TPM_RC response_code;
24172  std::string response_code_bytes;
24173  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24174  if (rc != TPM_RC_SUCCESS) {
24175    return rc;
24176  }
24177  if (response_size != response.size()) {
24178    return TPM_RC_SIZE;
24179  }
24180  if (response_code != TPM_RC_SUCCESS) {
24181    return response_code;
24182  }
24183  TPM_CC command_code = TPM_CC_PolicyAuthValue;
24184  std::string command_code_bytes;
24185  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24186  if (rc != TPM_RC_SUCCESS) {
24187    return rc;
24188  }
24189  std::string authorization_section_bytes;
24190  if (tag == TPM_ST_SESSIONS) {
24191    UINT32 parameter_section_size = buffer.size();
24192    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24193    if (rc != TPM_RC_SUCCESS) {
24194      return rc;
24195    }
24196    if (parameter_section_size > buffer.size()) {
24197      return TPM_RC_INSUFFICIENT;
24198    }
24199    authorization_section_bytes = buffer.substr(parameter_section_size);
24200    // Keep the parameter section in |buffer|.
24201    buffer.erase(parameter_section_size);
24202  }
24203  std::unique_ptr<crypto::SecureHash> hash(
24204      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24205  hash->Update(response_code_bytes.data(), response_code_bytes.size());
24206  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24207  hash->Update(buffer.data(), buffer.size());
24208  std::string response_hash(32, 0);
24209  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
24210  if (tag == TPM_ST_SESSIONS) {
24211    CHECK(authorization_delegate) << "Authorization delegate missing!";
24212    if (!authorization_delegate->CheckResponseAuthorization(
24213            response_hash, authorization_section_bytes)) {
24214      return TRUNKS_RC_AUTHORIZATION_FAILED;
24215    }
24216  }
24217  return TPM_RC_SUCCESS;
24218}
24219
24220void PolicyAuthValueErrorCallback(const Tpm::PolicyAuthValueResponse& callback,
24221                                  TPM_RC response_code) {
24222  VLOG(1) << __func__;
24223  callback.Run(response_code);
24224}
24225
24226void PolicyAuthValueResponseParser(
24227    const Tpm::PolicyAuthValueResponse& callback,
24228    AuthorizationDelegate* authorization_delegate,
24229    const std::string& response) {
24230  VLOG(1) << __func__;
24231  base::Callback<void(TPM_RC)> error_reporter =
24232      base::Bind(PolicyAuthValueErrorCallback, callback);
24233  TPM_RC rc =
24234      Tpm::ParseResponse_PolicyAuthValue(response, authorization_delegate);
24235  if (rc != TPM_RC_SUCCESS) {
24236    error_reporter.Run(rc);
24237    return;
24238  }
24239  callback.Run(rc);
24240}
24241
24242void Tpm::PolicyAuthValue(const TPMI_SH_POLICY& policy_session,
24243                          const std::string& policy_session_name,
24244                          AuthorizationDelegate* authorization_delegate,
24245                          const PolicyAuthValueResponse& callback) {
24246  VLOG(1) << __func__;
24247  base::Callback<void(TPM_RC)> error_reporter =
24248      base::Bind(PolicyAuthValueErrorCallback, callback);
24249  base::Callback<void(const std::string&)> parser = base::Bind(
24250      PolicyAuthValueResponseParser, callback, authorization_delegate);
24251  std::string command;
24252  TPM_RC rc = SerializeCommand_PolicyAuthValue(
24253      policy_session, policy_session_name, &command, authorization_delegate);
24254  if (rc != TPM_RC_SUCCESS) {
24255    error_reporter.Run(rc);
24256    return;
24257  }
24258  transceiver_->SendCommand(command, parser);
24259}
24260
24261TPM_RC Tpm::PolicyAuthValueSync(const TPMI_SH_POLICY& policy_session,
24262                                const std::string& policy_session_name,
24263                                AuthorizationDelegate* authorization_delegate) {
24264  VLOG(1) << __func__;
24265  std::string command;
24266  TPM_RC rc = SerializeCommand_PolicyAuthValue(
24267      policy_session, policy_session_name, &command, authorization_delegate);
24268  if (rc != TPM_RC_SUCCESS) {
24269    return rc;
24270  }
24271  std::string response = transceiver_->SendCommandAndWait(command);
24272  rc = ParseResponse_PolicyAuthValue(response, authorization_delegate);
24273  return rc;
24274}
24275
24276TPM_RC Tpm::SerializeCommand_PolicyPassword(
24277    const TPMI_SH_POLICY& policy_session,
24278    const std::string& policy_session_name,
24279    std::string* serialized_command,
24280    AuthorizationDelegate* authorization_delegate) {
24281  VLOG(3) << __func__;
24282  TPM_RC rc = TPM_RC_SUCCESS;
24283  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24284  UINT32 command_size = 10;  // Header size.
24285  std::string handle_section_bytes;
24286  std::string parameter_section_bytes;
24287  TPM_CC command_code = TPM_CC_PolicyPassword;
24288  bool is_command_parameter_encryption_possible = false;
24289  bool is_response_parameter_encryption_possible = false;
24290  std::string command_code_bytes;
24291  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24292  if (rc != TPM_RC_SUCCESS) {
24293    return rc;
24294  }
24295  std::string policy_session_bytes;
24296  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24297  if (rc != TPM_RC_SUCCESS) {
24298    return rc;
24299  }
24300  std::unique_ptr<crypto::SecureHash> hash(
24301      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24302  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24303  hash->Update(policy_session_name.data(), policy_session_name.size());
24304  handle_section_bytes += policy_session_bytes;
24305  command_size += policy_session_bytes.size();
24306  std::string command_hash(32, 0);
24307  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
24308  std::string authorization_section_bytes;
24309  std::string authorization_size_bytes;
24310  if (authorization_delegate) {
24311    if (!authorization_delegate->GetCommandAuthorization(
24312            command_hash, is_command_parameter_encryption_possible,
24313            is_response_parameter_encryption_possible,
24314            &authorization_section_bytes)) {
24315      return TRUNKS_RC_AUTHORIZATION_FAILED;
24316    }
24317    if (!authorization_section_bytes.empty()) {
24318      tag = TPM_ST_SESSIONS;
24319      std::string tmp;
24320      rc = Serialize_UINT32(authorization_section_bytes.size(),
24321                            &authorization_size_bytes);
24322      if (rc != TPM_RC_SUCCESS) {
24323        return rc;
24324      }
24325      command_size +=
24326          authorization_size_bytes.size() + authorization_section_bytes.size();
24327    }
24328  }
24329  std::string tag_bytes;
24330  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24331  if (rc != TPM_RC_SUCCESS) {
24332    return rc;
24333  }
24334  std::string command_size_bytes;
24335  rc = Serialize_UINT32(command_size, &command_size_bytes);
24336  if (rc != TPM_RC_SUCCESS) {
24337    return rc;
24338  }
24339  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24340                        handle_section_bytes + authorization_size_bytes +
24341                        authorization_section_bytes + parameter_section_bytes;
24342  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24343  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
24344                                            serialized_command->size());
24345  return TPM_RC_SUCCESS;
24346}
24347
24348TPM_RC Tpm::ParseResponse_PolicyPassword(
24349    const std::string& response,
24350    AuthorizationDelegate* authorization_delegate) {
24351  VLOG(3) << __func__;
24352  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24353  TPM_RC rc = TPM_RC_SUCCESS;
24354  std::string buffer(response);
24355  TPM_ST tag;
24356  std::string tag_bytes;
24357  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24358  if (rc != TPM_RC_SUCCESS) {
24359    return rc;
24360  }
24361  UINT32 response_size;
24362  std::string response_size_bytes;
24363  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24364  if (rc != TPM_RC_SUCCESS) {
24365    return rc;
24366  }
24367  TPM_RC response_code;
24368  std::string response_code_bytes;
24369  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24370  if (rc != TPM_RC_SUCCESS) {
24371    return rc;
24372  }
24373  if (response_size != response.size()) {
24374    return TPM_RC_SIZE;
24375  }
24376  if (response_code != TPM_RC_SUCCESS) {
24377    return response_code;
24378  }
24379  TPM_CC command_code = TPM_CC_PolicyPassword;
24380  std::string command_code_bytes;
24381  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24382  if (rc != TPM_RC_SUCCESS) {
24383    return rc;
24384  }
24385  std::string authorization_section_bytes;
24386  if (tag == TPM_ST_SESSIONS) {
24387    UINT32 parameter_section_size = buffer.size();
24388    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24389    if (rc != TPM_RC_SUCCESS) {
24390      return rc;
24391    }
24392    if (parameter_section_size > buffer.size()) {
24393      return TPM_RC_INSUFFICIENT;
24394    }
24395    authorization_section_bytes = buffer.substr(parameter_section_size);
24396    // Keep the parameter section in |buffer|.
24397    buffer.erase(parameter_section_size);
24398  }
24399  std::unique_ptr<crypto::SecureHash> hash(
24400      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24401  hash->Update(response_code_bytes.data(), response_code_bytes.size());
24402  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24403  hash->Update(buffer.data(), buffer.size());
24404  std::string response_hash(32, 0);
24405  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
24406  if (tag == TPM_ST_SESSIONS) {
24407    CHECK(authorization_delegate) << "Authorization delegate missing!";
24408    if (!authorization_delegate->CheckResponseAuthorization(
24409            response_hash, authorization_section_bytes)) {
24410      return TRUNKS_RC_AUTHORIZATION_FAILED;
24411    }
24412  }
24413  return TPM_RC_SUCCESS;
24414}
24415
24416void PolicyPasswordErrorCallback(const Tpm::PolicyPasswordResponse& callback,
24417                                 TPM_RC response_code) {
24418  VLOG(1) << __func__;
24419  callback.Run(response_code);
24420}
24421
24422void PolicyPasswordResponseParser(const Tpm::PolicyPasswordResponse& callback,
24423                                  AuthorizationDelegate* authorization_delegate,
24424                                  const std::string& response) {
24425  VLOG(1) << __func__;
24426  base::Callback<void(TPM_RC)> error_reporter =
24427      base::Bind(PolicyPasswordErrorCallback, callback);
24428  TPM_RC rc =
24429      Tpm::ParseResponse_PolicyPassword(response, authorization_delegate);
24430  if (rc != TPM_RC_SUCCESS) {
24431    error_reporter.Run(rc);
24432    return;
24433  }
24434  callback.Run(rc);
24435}
24436
24437void Tpm::PolicyPassword(const TPMI_SH_POLICY& policy_session,
24438                         const std::string& policy_session_name,
24439                         AuthorizationDelegate* authorization_delegate,
24440                         const PolicyPasswordResponse& callback) {
24441  VLOG(1) << __func__;
24442  base::Callback<void(TPM_RC)> error_reporter =
24443      base::Bind(PolicyPasswordErrorCallback, callback);
24444  base::Callback<void(const std::string&)> parser = base::Bind(
24445      PolicyPasswordResponseParser, callback, authorization_delegate);
24446  std::string command;
24447  TPM_RC rc = SerializeCommand_PolicyPassword(
24448      policy_session, policy_session_name, &command, authorization_delegate);
24449  if (rc != TPM_RC_SUCCESS) {
24450    error_reporter.Run(rc);
24451    return;
24452  }
24453  transceiver_->SendCommand(command, parser);
24454}
24455
24456TPM_RC Tpm::PolicyPasswordSync(const TPMI_SH_POLICY& policy_session,
24457                               const std::string& policy_session_name,
24458                               AuthorizationDelegate* authorization_delegate) {
24459  VLOG(1) << __func__;
24460  std::string command;
24461  TPM_RC rc = SerializeCommand_PolicyPassword(
24462      policy_session, policy_session_name, &command, authorization_delegate);
24463  if (rc != TPM_RC_SUCCESS) {
24464    return rc;
24465  }
24466  std::string response = transceiver_->SendCommandAndWait(command);
24467  rc = ParseResponse_PolicyPassword(response, authorization_delegate);
24468  return rc;
24469}
24470
24471TPM_RC Tpm::SerializeCommand_PolicyGetDigest(
24472    const TPMI_SH_POLICY& policy_session,
24473    const std::string& policy_session_name,
24474    std::string* serialized_command,
24475    AuthorizationDelegate* authorization_delegate) {
24476  VLOG(3) << __func__;
24477  TPM_RC rc = TPM_RC_SUCCESS;
24478  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24479  UINT32 command_size = 10;  // Header size.
24480  std::string handle_section_bytes;
24481  std::string parameter_section_bytes;
24482  TPM_CC command_code = TPM_CC_PolicyGetDigest;
24483  bool is_command_parameter_encryption_possible = false;
24484  bool is_response_parameter_encryption_possible = true;
24485  std::string command_code_bytes;
24486  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24487  if (rc != TPM_RC_SUCCESS) {
24488    return rc;
24489  }
24490  std::string policy_session_bytes;
24491  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24492  if (rc != TPM_RC_SUCCESS) {
24493    return rc;
24494  }
24495  std::unique_ptr<crypto::SecureHash> hash(
24496      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24497  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24498  hash->Update(policy_session_name.data(), policy_session_name.size());
24499  handle_section_bytes += policy_session_bytes;
24500  command_size += policy_session_bytes.size();
24501  std::string command_hash(32, 0);
24502  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
24503  std::string authorization_section_bytes;
24504  std::string authorization_size_bytes;
24505  if (authorization_delegate) {
24506    if (!authorization_delegate->GetCommandAuthorization(
24507            command_hash, is_command_parameter_encryption_possible,
24508            is_response_parameter_encryption_possible,
24509            &authorization_section_bytes)) {
24510      return TRUNKS_RC_AUTHORIZATION_FAILED;
24511    }
24512    if (!authorization_section_bytes.empty()) {
24513      tag = TPM_ST_SESSIONS;
24514      std::string tmp;
24515      rc = Serialize_UINT32(authorization_section_bytes.size(),
24516                            &authorization_size_bytes);
24517      if (rc != TPM_RC_SUCCESS) {
24518        return rc;
24519      }
24520      command_size +=
24521          authorization_size_bytes.size() + authorization_section_bytes.size();
24522    }
24523  }
24524  std::string tag_bytes;
24525  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24526  if (rc != TPM_RC_SUCCESS) {
24527    return rc;
24528  }
24529  std::string command_size_bytes;
24530  rc = Serialize_UINT32(command_size, &command_size_bytes);
24531  if (rc != TPM_RC_SUCCESS) {
24532    return rc;
24533  }
24534  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24535                        handle_section_bytes + authorization_size_bytes +
24536                        authorization_section_bytes + parameter_section_bytes;
24537  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24538  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
24539                                            serialized_command->size());
24540  return TPM_RC_SUCCESS;
24541}
24542
24543TPM_RC Tpm::ParseResponse_PolicyGetDigest(
24544    const std::string& response,
24545    TPM2B_DIGEST* policy_digest,
24546    AuthorizationDelegate* authorization_delegate) {
24547  VLOG(3) << __func__;
24548  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24549  TPM_RC rc = TPM_RC_SUCCESS;
24550  std::string buffer(response);
24551  TPM_ST tag;
24552  std::string tag_bytes;
24553  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24554  if (rc != TPM_RC_SUCCESS) {
24555    return rc;
24556  }
24557  UINT32 response_size;
24558  std::string response_size_bytes;
24559  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24560  if (rc != TPM_RC_SUCCESS) {
24561    return rc;
24562  }
24563  TPM_RC response_code;
24564  std::string response_code_bytes;
24565  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24566  if (rc != TPM_RC_SUCCESS) {
24567    return rc;
24568  }
24569  if (response_size != response.size()) {
24570    return TPM_RC_SIZE;
24571  }
24572  if (response_code != TPM_RC_SUCCESS) {
24573    return response_code;
24574  }
24575  TPM_CC command_code = TPM_CC_PolicyGetDigest;
24576  std::string command_code_bytes;
24577  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24578  if (rc != TPM_RC_SUCCESS) {
24579    return rc;
24580  }
24581  std::string authorization_section_bytes;
24582  if (tag == TPM_ST_SESSIONS) {
24583    UINT32 parameter_section_size = buffer.size();
24584    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24585    if (rc != TPM_RC_SUCCESS) {
24586      return rc;
24587    }
24588    if (parameter_section_size > buffer.size()) {
24589      return TPM_RC_INSUFFICIENT;
24590    }
24591    authorization_section_bytes = buffer.substr(parameter_section_size);
24592    // Keep the parameter section in |buffer|.
24593    buffer.erase(parameter_section_size);
24594  }
24595  std::unique_ptr<crypto::SecureHash> hash(
24596      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24597  hash->Update(response_code_bytes.data(), response_code_bytes.size());
24598  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24599  hash->Update(buffer.data(), buffer.size());
24600  std::string response_hash(32, 0);
24601  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
24602  if (tag == TPM_ST_SESSIONS) {
24603    CHECK(authorization_delegate) << "Authorization delegate missing!";
24604    if (!authorization_delegate->CheckResponseAuthorization(
24605            response_hash, authorization_section_bytes)) {
24606      return TRUNKS_RC_AUTHORIZATION_FAILED;
24607    }
24608  }
24609  std::string policy_digest_bytes;
24610  rc = Parse_TPM2B_DIGEST(&buffer, policy_digest, &policy_digest_bytes);
24611  if (rc != TPM_RC_SUCCESS) {
24612    return rc;
24613  }
24614  if (tag == TPM_ST_SESSIONS) {
24615    CHECK(authorization_delegate) << "Authorization delegate missing!";
24616    // Decrypt just the parameter data, not the size.
24617    std::string tmp = policy_digest_bytes.substr(2);
24618    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
24619      return TRUNKS_RC_ENCRYPTION_FAILED;
24620    }
24621    policy_digest_bytes.replace(2, std::string::npos, tmp);
24622    rc = Parse_TPM2B_DIGEST(&policy_digest_bytes, policy_digest, nullptr);
24623    if (rc != TPM_RC_SUCCESS) {
24624      return rc;
24625    }
24626  }
24627  return TPM_RC_SUCCESS;
24628}
24629
24630void PolicyGetDigestErrorCallback(const Tpm::PolicyGetDigestResponse& callback,
24631                                  TPM_RC response_code) {
24632  VLOG(1) << __func__;
24633  callback.Run(response_code, TPM2B_DIGEST());
24634}
24635
24636void PolicyGetDigestResponseParser(
24637    const Tpm::PolicyGetDigestResponse& callback,
24638    AuthorizationDelegate* authorization_delegate,
24639    const std::string& response) {
24640  VLOG(1) << __func__;
24641  base::Callback<void(TPM_RC)> error_reporter =
24642      base::Bind(PolicyGetDigestErrorCallback, callback);
24643  TPM2B_DIGEST policy_digest;
24644  TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest(response, &policy_digest,
24645                                                 authorization_delegate);
24646  if (rc != TPM_RC_SUCCESS) {
24647    error_reporter.Run(rc);
24648    return;
24649  }
24650  callback.Run(rc, policy_digest);
24651}
24652
24653void Tpm::PolicyGetDigest(const TPMI_SH_POLICY& policy_session,
24654                          const std::string& policy_session_name,
24655                          AuthorizationDelegate* authorization_delegate,
24656                          const PolicyGetDigestResponse& callback) {
24657  VLOG(1) << __func__;
24658  base::Callback<void(TPM_RC)> error_reporter =
24659      base::Bind(PolicyGetDigestErrorCallback, callback);
24660  base::Callback<void(const std::string&)> parser = base::Bind(
24661      PolicyGetDigestResponseParser, callback, authorization_delegate);
24662  std::string command;
24663  TPM_RC rc = SerializeCommand_PolicyGetDigest(
24664      policy_session, policy_session_name, &command, authorization_delegate);
24665  if (rc != TPM_RC_SUCCESS) {
24666    error_reporter.Run(rc);
24667    return;
24668  }
24669  transceiver_->SendCommand(command, parser);
24670}
24671
24672TPM_RC Tpm::PolicyGetDigestSync(const TPMI_SH_POLICY& policy_session,
24673                                const std::string& policy_session_name,
24674                                TPM2B_DIGEST* policy_digest,
24675                                AuthorizationDelegate* authorization_delegate) {
24676  VLOG(1) << __func__;
24677  std::string command;
24678  TPM_RC rc = SerializeCommand_PolicyGetDigest(
24679      policy_session, policy_session_name, &command, authorization_delegate);
24680  if (rc != TPM_RC_SUCCESS) {
24681    return rc;
24682  }
24683  std::string response = transceiver_->SendCommandAndWait(command);
24684  rc = ParseResponse_PolicyGetDigest(response, policy_digest,
24685                                     authorization_delegate);
24686  return rc;
24687}
24688
24689TPM_RC Tpm::SerializeCommand_PolicyNvWritten(
24690    const TPMI_SH_POLICY& policy_session,
24691    const std::string& policy_session_name,
24692    const TPMI_YES_NO& written_set,
24693    std::string* serialized_command,
24694    AuthorizationDelegate* authorization_delegate) {
24695  VLOG(3) << __func__;
24696  TPM_RC rc = TPM_RC_SUCCESS;
24697  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24698  UINT32 command_size = 10;  // Header size.
24699  std::string handle_section_bytes;
24700  std::string parameter_section_bytes;
24701  TPM_CC command_code = TPM_CC_PolicyNvWritten;
24702  bool is_command_parameter_encryption_possible = false;
24703  bool is_response_parameter_encryption_possible = false;
24704  std::string command_code_bytes;
24705  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24706  if (rc != TPM_RC_SUCCESS) {
24707    return rc;
24708  }
24709  std::string policy_session_bytes;
24710  rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24711  if (rc != TPM_RC_SUCCESS) {
24712    return rc;
24713  }
24714  std::string written_set_bytes;
24715  rc = Serialize_TPMI_YES_NO(written_set, &written_set_bytes);
24716  if (rc != TPM_RC_SUCCESS) {
24717    return rc;
24718  }
24719  std::unique_ptr<crypto::SecureHash> hash(
24720      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24721  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24722  hash->Update(policy_session_name.data(), policy_session_name.size());
24723  handle_section_bytes += policy_session_bytes;
24724  command_size += policy_session_bytes.size();
24725  hash->Update(written_set_bytes.data(), written_set_bytes.size());
24726  parameter_section_bytes += written_set_bytes;
24727  command_size += written_set_bytes.size();
24728  std::string command_hash(32, 0);
24729  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
24730  std::string authorization_section_bytes;
24731  std::string authorization_size_bytes;
24732  if (authorization_delegate) {
24733    if (!authorization_delegate->GetCommandAuthorization(
24734            command_hash, is_command_parameter_encryption_possible,
24735            is_response_parameter_encryption_possible,
24736            &authorization_section_bytes)) {
24737      return TRUNKS_RC_AUTHORIZATION_FAILED;
24738    }
24739    if (!authorization_section_bytes.empty()) {
24740      tag = TPM_ST_SESSIONS;
24741      std::string tmp;
24742      rc = Serialize_UINT32(authorization_section_bytes.size(),
24743                            &authorization_size_bytes);
24744      if (rc != TPM_RC_SUCCESS) {
24745        return rc;
24746      }
24747      command_size +=
24748          authorization_size_bytes.size() + authorization_section_bytes.size();
24749    }
24750  }
24751  std::string tag_bytes;
24752  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24753  if (rc != TPM_RC_SUCCESS) {
24754    return rc;
24755  }
24756  std::string command_size_bytes;
24757  rc = Serialize_UINT32(command_size, &command_size_bytes);
24758  if (rc != TPM_RC_SUCCESS) {
24759    return rc;
24760  }
24761  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24762                        handle_section_bytes + authorization_size_bytes +
24763                        authorization_section_bytes + parameter_section_bytes;
24764  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24765  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
24766                                            serialized_command->size());
24767  return TPM_RC_SUCCESS;
24768}
24769
24770TPM_RC Tpm::ParseResponse_PolicyNvWritten(
24771    const std::string& response,
24772    AuthorizationDelegate* authorization_delegate) {
24773  VLOG(3) << __func__;
24774  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24775  TPM_RC rc = TPM_RC_SUCCESS;
24776  std::string buffer(response);
24777  TPM_ST tag;
24778  std::string tag_bytes;
24779  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24780  if (rc != TPM_RC_SUCCESS) {
24781    return rc;
24782  }
24783  UINT32 response_size;
24784  std::string response_size_bytes;
24785  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24786  if (rc != TPM_RC_SUCCESS) {
24787    return rc;
24788  }
24789  TPM_RC response_code;
24790  std::string response_code_bytes;
24791  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24792  if (rc != TPM_RC_SUCCESS) {
24793    return rc;
24794  }
24795  if (response_size != response.size()) {
24796    return TPM_RC_SIZE;
24797  }
24798  if (response_code != TPM_RC_SUCCESS) {
24799    return response_code;
24800  }
24801  TPM_CC command_code = TPM_CC_PolicyNvWritten;
24802  std::string command_code_bytes;
24803  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24804  if (rc != TPM_RC_SUCCESS) {
24805    return rc;
24806  }
24807  std::string authorization_section_bytes;
24808  if (tag == TPM_ST_SESSIONS) {
24809    UINT32 parameter_section_size = buffer.size();
24810    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24811    if (rc != TPM_RC_SUCCESS) {
24812      return rc;
24813    }
24814    if (parameter_section_size > buffer.size()) {
24815      return TPM_RC_INSUFFICIENT;
24816    }
24817    authorization_section_bytes = buffer.substr(parameter_section_size);
24818    // Keep the parameter section in |buffer|.
24819    buffer.erase(parameter_section_size);
24820  }
24821  std::unique_ptr<crypto::SecureHash> hash(
24822      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24823  hash->Update(response_code_bytes.data(), response_code_bytes.size());
24824  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24825  hash->Update(buffer.data(), buffer.size());
24826  std::string response_hash(32, 0);
24827  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
24828  if (tag == TPM_ST_SESSIONS) {
24829    CHECK(authorization_delegate) << "Authorization delegate missing!";
24830    if (!authorization_delegate->CheckResponseAuthorization(
24831            response_hash, authorization_section_bytes)) {
24832      return TRUNKS_RC_AUTHORIZATION_FAILED;
24833    }
24834  }
24835  return TPM_RC_SUCCESS;
24836}
24837
24838void PolicyNvWrittenErrorCallback(const Tpm::PolicyNvWrittenResponse& callback,
24839                                  TPM_RC response_code) {
24840  VLOG(1) << __func__;
24841  callback.Run(response_code);
24842}
24843
24844void PolicyNvWrittenResponseParser(
24845    const Tpm::PolicyNvWrittenResponse& callback,
24846    AuthorizationDelegate* authorization_delegate,
24847    const std::string& response) {
24848  VLOG(1) << __func__;
24849  base::Callback<void(TPM_RC)> error_reporter =
24850      base::Bind(PolicyNvWrittenErrorCallback, callback);
24851  TPM_RC rc =
24852      Tpm::ParseResponse_PolicyNvWritten(response, authorization_delegate);
24853  if (rc != TPM_RC_SUCCESS) {
24854    error_reporter.Run(rc);
24855    return;
24856  }
24857  callback.Run(rc);
24858}
24859
24860void Tpm::PolicyNvWritten(const TPMI_SH_POLICY& policy_session,
24861                          const std::string& policy_session_name,
24862                          const TPMI_YES_NO& written_set,
24863                          AuthorizationDelegate* authorization_delegate,
24864                          const PolicyNvWrittenResponse& callback) {
24865  VLOG(1) << __func__;
24866  base::Callback<void(TPM_RC)> error_reporter =
24867      base::Bind(PolicyNvWrittenErrorCallback, callback);
24868  base::Callback<void(const std::string&)> parser = base::Bind(
24869      PolicyNvWrittenResponseParser, callback, authorization_delegate);
24870  std::string command;
24871  TPM_RC rc = SerializeCommand_PolicyNvWritten(
24872      policy_session, policy_session_name, written_set, &command,
24873      authorization_delegate);
24874  if (rc != TPM_RC_SUCCESS) {
24875    error_reporter.Run(rc);
24876    return;
24877  }
24878  transceiver_->SendCommand(command, parser);
24879}
24880
24881TPM_RC Tpm::PolicyNvWrittenSync(const TPMI_SH_POLICY& policy_session,
24882                                const std::string& policy_session_name,
24883                                const TPMI_YES_NO& written_set,
24884                                AuthorizationDelegate* authorization_delegate) {
24885  VLOG(1) << __func__;
24886  std::string command;
24887  TPM_RC rc = SerializeCommand_PolicyNvWritten(
24888      policy_session, policy_session_name, written_set, &command,
24889      authorization_delegate);
24890  if (rc != TPM_RC_SUCCESS) {
24891    return rc;
24892  }
24893  std::string response = transceiver_->SendCommandAndWait(command);
24894  rc = ParseResponse_PolicyNvWritten(response, authorization_delegate);
24895  return rc;
24896}
24897
24898TPM_RC Tpm::SerializeCommand_CreatePrimary(
24899    const TPMI_RH_HIERARCHY& primary_handle,
24900    const std::string& primary_handle_name,
24901    const TPM2B_SENSITIVE_CREATE& in_sensitive,
24902    const TPM2B_PUBLIC& in_public,
24903    const TPM2B_DATA& outside_info,
24904    const TPML_PCR_SELECTION& creation_pcr,
24905    std::string* serialized_command,
24906    AuthorizationDelegate* authorization_delegate) {
24907  VLOG(3) << __func__;
24908  TPM_RC rc = TPM_RC_SUCCESS;
24909  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24910  UINT32 command_size = 10;  // Header size.
24911  std::string handle_section_bytes;
24912  std::string parameter_section_bytes;
24913  TPM_CC command_code = TPM_CC_CreatePrimary;
24914  bool is_command_parameter_encryption_possible = true;
24915  bool is_response_parameter_encryption_possible = true;
24916  std::string command_code_bytes;
24917  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24918  if (rc != TPM_RC_SUCCESS) {
24919    return rc;
24920  }
24921  std::string primary_handle_bytes;
24922  rc = Serialize_TPMI_RH_HIERARCHY(primary_handle, &primary_handle_bytes);
24923  if (rc != TPM_RC_SUCCESS) {
24924    return rc;
24925  }
24926  std::string in_sensitive_bytes;
24927  rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
24928  if (rc != TPM_RC_SUCCESS) {
24929    return rc;
24930  }
24931  std::string in_public_bytes;
24932  rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
24933  if (rc != TPM_RC_SUCCESS) {
24934    return rc;
24935  }
24936  std::string outside_info_bytes;
24937  rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
24938  if (rc != TPM_RC_SUCCESS) {
24939    return rc;
24940  }
24941  std::string creation_pcr_bytes;
24942  rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
24943  if (rc != TPM_RC_SUCCESS) {
24944    return rc;
24945  }
24946  if (authorization_delegate) {
24947    // Encrypt just the parameter data, not the size.
24948    std::string tmp = in_sensitive_bytes.substr(2);
24949    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24950      return TRUNKS_RC_ENCRYPTION_FAILED;
24951    }
24952    in_sensitive_bytes.replace(2, std::string::npos, tmp);
24953  }
24954  std::unique_ptr<crypto::SecureHash> hash(
24955      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24956  hash->Update(command_code_bytes.data(), command_code_bytes.size());
24957  hash->Update(primary_handle_name.data(), primary_handle_name.size());
24958  handle_section_bytes += primary_handle_bytes;
24959  command_size += primary_handle_bytes.size();
24960  hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
24961  parameter_section_bytes += in_sensitive_bytes;
24962  command_size += in_sensitive_bytes.size();
24963  hash->Update(in_public_bytes.data(), in_public_bytes.size());
24964  parameter_section_bytes += in_public_bytes;
24965  command_size += in_public_bytes.size();
24966  hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
24967  parameter_section_bytes += outside_info_bytes;
24968  command_size += outside_info_bytes.size();
24969  hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
24970  parameter_section_bytes += creation_pcr_bytes;
24971  command_size += creation_pcr_bytes.size();
24972  std::string command_hash(32, 0);
24973  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
24974  std::string authorization_section_bytes;
24975  std::string authorization_size_bytes;
24976  if (authorization_delegate) {
24977    if (!authorization_delegate->GetCommandAuthorization(
24978            command_hash, is_command_parameter_encryption_possible,
24979            is_response_parameter_encryption_possible,
24980            &authorization_section_bytes)) {
24981      return TRUNKS_RC_AUTHORIZATION_FAILED;
24982    }
24983    if (!authorization_section_bytes.empty()) {
24984      tag = TPM_ST_SESSIONS;
24985      std::string tmp;
24986      rc = Serialize_UINT32(authorization_section_bytes.size(),
24987                            &authorization_size_bytes);
24988      if (rc != TPM_RC_SUCCESS) {
24989        return rc;
24990      }
24991      command_size +=
24992          authorization_size_bytes.size() + authorization_section_bytes.size();
24993    }
24994  }
24995  std::string tag_bytes;
24996  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24997  if (rc != TPM_RC_SUCCESS) {
24998    return rc;
24999  }
25000  std::string command_size_bytes;
25001  rc = Serialize_UINT32(command_size, &command_size_bytes);
25002  if (rc != TPM_RC_SUCCESS) {
25003    return rc;
25004  }
25005  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25006                        handle_section_bytes + authorization_size_bytes +
25007                        authorization_section_bytes + parameter_section_bytes;
25008  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25009  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
25010                                            serialized_command->size());
25011  return TPM_RC_SUCCESS;
25012}
25013
25014TPM_RC Tpm::ParseResponse_CreatePrimary(
25015    const std::string& response,
25016    TPM_HANDLE* object_handle,
25017    TPM2B_PUBLIC* out_public,
25018    TPM2B_CREATION_DATA* creation_data,
25019    TPM2B_DIGEST* creation_hash,
25020    TPMT_TK_CREATION* creation_ticket,
25021    TPM2B_NAME* name,
25022    AuthorizationDelegate* authorization_delegate) {
25023  VLOG(3) << __func__;
25024  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25025  TPM_RC rc = TPM_RC_SUCCESS;
25026  std::string buffer(response);
25027  TPM_ST tag;
25028  std::string tag_bytes;
25029  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25030  if (rc != TPM_RC_SUCCESS) {
25031    return rc;
25032  }
25033  UINT32 response_size;
25034  std::string response_size_bytes;
25035  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25036  if (rc != TPM_RC_SUCCESS) {
25037    return rc;
25038  }
25039  TPM_RC response_code;
25040  std::string response_code_bytes;
25041  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25042  if (rc != TPM_RC_SUCCESS) {
25043    return rc;
25044  }
25045  if (response_size != response.size()) {
25046    return TPM_RC_SIZE;
25047  }
25048  if (response_code != TPM_RC_SUCCESS) {
25049    return response_code;
25050  }
25051  std::string object_handle_bytes;
25052  rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
25053  if (rc != TPM_RC_SUCCESS) {
25054    return rc;
25055  }
25056  TPM_CC command_code = TPM_CC_CreatePrimary;
25057  std::string command_code_bytes;
25058  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25059  if (rc != TPM_RC_SUCCESS) {
25060    return rc;
25061  }
25062  std::string authorization_section_bytes;
25063  if (tag == TPM_ST_SESSIONS) {
25064    UINT32 parameter_section_size = buffer.size();
25065    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25066    if (rc != TPM_RC_SUCCESS) {
25067      return rc;
25068    }
25069    if (parameter_section_size > buffer.size()) {
25070      return TPM_RC_INSUFFICIENT;
25071    }
25072    authorization_section_bytes = buffer.substr(parameter_section_size);
25073    // Keep the parameter section in |buffer|.
25074    buffer.erase(parameter_section_size);
25075  }
25076  std::unique_ptr<crypto::SecureHash> hash(
25077      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25078  hash->Update(response_code_bytes.data(), response_code_bytes.size());
25079  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25080  hash->Update(buffer.data(), buffer.size());
25081  std::string response_hash(32, 0);
25082  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
25083  if (tag == TPM_ST_SESSIONS) {
25084    CHECK(authorization_delegate) << "Authorization delegate missing!";
25085    if (!authorization_delegate->CheckResponseAuthorization(
25086            response_hash, authorization_section_bytes)) {
25087      return TRUNKS_RC_AUTHORIZATION_FAILED;
25088    }
25089  }
25090  std::string out_public_bytes;
25091  rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
25092  if (rc != TPM_RC_SUCCESS) {
25093    return rc;
25094  }
25095  std::string creation_data_bytes;
25096  rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
25097  if (rc != TPM_RC_SUCCESS) {
25098    return rc;
25099  }
25100  std::string creation_hash_bytes;
25101  rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
25102  if (rc != TPM_RC_SUCCESS) {
25103    return rc;
25104  }
25105  std::string creation_ticket_bytes;
25106  rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
25107  if (rc != TPM_RC_SUCCESS) {
25108    return rc;
25109  }
25110  std::string name_bytes;
25111  rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
25112  if (rc != TPM_RC_SUCCESS) {
25113    return rc;
25114  }
25115  if (tag == TPM_ST_SESSIONS) {
25116    CHECK(authorization_delegate) << "Authorization delegate missing!";
25117    // Decrypt just the parameter data, not the size.
25118    std::string tmp = out_public_bytes.substr(2);
25119    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
25120      return TRUNKS_RC_ENCRYPTION_FAILED;
25121    }
25122    out_public_bytes.replace(2, std::string::npos, tmp);
25123    rc = Parse_TPM2B_PUBLIC(&out_public_bytes, out_public, nullptr);
25124    if (rc != TPM_RC_SUCCESS) {
25125      return rc;
25126    }
25127  }
25128  return TPM_RC_SUCCESS;
25129}
25130
25131void CreatePrimaryErrorCallback(const Tpm::CreatePrimaryResponse& callback,
25132                                TPM_RC response_code) {
25133  VLOG(1) << __func__;
25134  callback.Run(response_code, TPM_HANDLE(), TPM2B_PUBLIC(),
25135               TPM2B_CREATION_DATA(), TPM2B_DIGEST(), TPMT_TK_CREATION(),
25136               TPM2B_NAME());
25137}
25138
25139void CreatePrimaryResponseParser(const Tpm::CreatePrimaryResponse& callback,
25140                                 AuthorizationDelegate* authorization_delegate,
25141                                 const std::string& response) {
25142  VLOG(1) << __func__;
25143  base::Callback<void(TPM_RC)> error_reporter =
25144      base::Bind(CreatePrimaryErrorCallback, callback);
25145  TPM_HANDLE object_handle;
25146  TPM2B_PUBLIC out_public;
25147  TPM2B_CREATION_DATA creation_data;
25148  TPM2B_DIGEST creation_hash;
25149  TPMT_TK_CREATION creation_ticket;
25150  TPM2B_NAME name;
25151  TPM_RC rc = Tpm::ParseResponse_CreatePrimary(
25152      response, &object_handle, &out_public, &creation_data, &creation_hash,
25153      &creation_ticket, &name, authorization_delegate);
25154  if (rc != TPM_RC_SUCCESS) {
25155    error_reporter.Run(rc);
25156    return;
25157  }
25158  callback.Run(rc, object_handle, out_public, creation_data, creation_hash,
25159               creation_ticket, name);
25160}
25161
25162void Tpm::CreatePrimary(const TPMI_RH_HIERARCHY& primary_handle,
25163                        const std::string& primary_handle_name,
25164                        const TPM2B_SENSITIVE_CREATE& in_sensitive,
25165                        const TPM2B_PUBLIC& in_public,
25166                        const TPM2B_DATA& outside_info,
25167                        const TPML_PCR_SELECTION& creation_pcr,
25168                        AuthorizationDelegate* authorization_delegate,
25169                        const CreatePrimaryResponse& callback) {
25170  VLOG(1) << __func__;
25171  base::Callback<void(TPM_RC)> error_reporter =
25172      base::Bind(CreatePrimaryErrorCallback, callback);
25173  base::Callback<void(const std::string&)> parser =
25174      base::Bind(CreatePrimaryResponseParser, callback, authorization_delegate);
25175  std::string command;
25176  TPM_RC rc = SerializeCommand_CreatePrimary(
25177      primary_handle, primary_handle_name, in_sensitive, in_public,
25178      outside_info, creation_pcr, &command, authorization_delegate);
25179  if (rc != TPM_RC_SUCCESS) {
25180    error_reporter.Run(rc);
25181    return;
25182  }
25183  transceiver_->SendCommand(command, parser);
25184}
25185
25186TPM_RC Tpm::CreatePrimarySync(const TPMI_RH_HIERARCHY& primary_handle,
25187                              const std::string& primary_handle_name,
25188                              const TPM2B_SENSITIVE_CREATE& in_sensitive,
25189                              const TPM2B_PUBLIC& in_public,
25190                              const TPM2B_DATA& outside_info,
25191                              const TPML_PCR_SELECTION& creation_pcr,
25192                              TPM_HANDLE* object_handle,
25193                              TPM2B_PUBLIC* out_public,
25194                              TPM2B_CREATION_DATA* creation_data,
25195                              TPM2B_DIGEST* creation_hash,
25196                              TPMT_TK_CREATION* creation_ticket,
25197                              TPM2B_NAME* name,
25198                              AuthorizationDelegate* authorization_delegate) {
25199  VLOG(1) << __func__;
25200  std::string command;
25201  TPM_RC rc = SerializeCommand_CreatePrimary(
25202      primary_handle, primary_handle_name, in_sensitive, in_public,
25203      outside_info, creation_pcr, &command, authorization_delegate);
25204  if (rc != TPM_RC_SUCCESS) {
25205    return rc;
25206  }
25207  std::string response = transceiver_->SendCommandAndWait(command);
25208  rc = ParseResponse_CreatePrimary(
25209      response, object_handle, out_public, creation_data, creation_hash,
25210      creation_ticket, name, authorization_delegate);
25211  return rc;
25212}
25213
25214TPM_RC Tpm::SerializeCommand_HierarchyControl(
25215    const TPMI_RH_HIERARCHY& auth_handle,
25216    const std::string& auth_handle_name,
25217    const TPMI_RH_ENABLES& enable,
25218    const TPMI_YES_NO& state,
25219    std::string* serialized_command,
25220    AuthorizationDelegate* authorization_delegate) {
25221  VLOG(3) << __func__;
25222  TPM_RC rc = TPM_RC_SUCCESS;
25223  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25224  UINT32 command_size = 10;  // Header size.
25225  std::string handle_section_bytes;
25226  std::string parameter_section_bytes;
25227  TPM_CC command_code = TPM_CC_HierarchyControl;
25228  bool is_command_parameter_encryption_possible = false;
25229  bool is_response_parameter_encryption_possible = false;
25230  std::string command_code_bytes;
25231  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25232  if (rc != TPM_RC_SUCCESS) {
25233    return rc;
25234  }
25235  std::string auth_handle_bytes;
25236  rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25237  if (rc != TPM_RC_SUCCESS) {
25238    return rc;
25239  }
25240  std::string enable_bytes;
25241  rc = Serialize_TPMI_RH_ENABLES(enable, &enable_bytes);
25242  if (rc != TPM_RC_SUCCESS) {
25243    return rc;
25244  }
25245  std::string state_bytes;
25246  rc = Serialize_TPMI_YES_NO(state, &state_bytes);
25247  if (rc != TPM_RC_SUCCESS) {
25248    return rc;
25249  }
25250  std::unique_ptr<crypto::SecureHash> hash(
25251      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25252  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25253  hash->Update(auth_handle_name.data(), auth_handle_name.size());
25254  handle_section_bytes += auth_handle_bytes;
25255  command_size += auth_handle_bytes.size();
25256  hash->Update(enable_bytes.data(), enable_bytes.size());
25257  parameter_section_bytes += enable_bytes;
25258  command_size += enable_bytes.size();
25259  hash->Update(state_bytes.data(), state_bytes.size());
25260  parameter_section_bytes += state_bytes;
25261  command_size += state_bytes.size();
25262  std::string command_hash(32, 0);
25263  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
25264  std::string authorization_section_bytes;
25265  std::string authorization_size_bytes;
25266  if (authorization_delegate) {
25267    if (!authorization_delegate->GetCommandAuthorization(
25268            command_hash, is_command_parameter_encryption_possible,
25269            is_response_parameter_encryption_possible,
25270            &authorization_section_bytes)) {
25271      return TRUNKS_RC_AUTHORIZATION_FAILED;
25272    }
25273    if (!authorization_section_bytes.empty()) {
25274      tag = TPM_ST_SESSIONS;
25275      std::string tmp;
25276      rc = Serialize_UINT32(authorization_section_bytes.size(),
25277                            &authorization_size_bytes);
25278      if (rc != TPM_RC_SUCCESS) {
25279        return rc;
25280      }
25281      command_size +=
25282          authorization_size_bytes.size() + authorization_section_bytes.size();
25283    }
25284  }
25285  std::string tag_bytes;
25286  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25287  if (rc != TPM_RC_SUCCESS) {
25288    return rc;
25289  }
25290  std::string command_size_bytes;
25291  rc = Serialize_UINT32(command_size, &command_size_bytes);
25292  if (rc != TPM_RC_SUCCESS) {
25293    return rc;
25294  }
25295  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25296                        handle_section_bytes + authorization_size_bytes +
25297                        authorization_section_bytes + parameter_section_bytes;
25298  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25299  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
25300                                            serialized_command->size());
25301  return TPM_RC_SUCCESS;
25302}
25303
25304TPM_RC Tpm::ParseResponse_HierarchyControl(
25305    const std::string& response,
25306    AuthorizationDelegate* authorization_delegate) {
25307  VLOG(3) << __func__;
25308  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25309  TPM_RC rc = TPM_RC_SUCCESS;
25310  std::string buffer(response);
25311  TPM_ST tag;
25312  std::string tag_bytes;
25313  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25314  if (rc != TPM_RC_SUCCESS) {
25315    return rc;
25316  }
25317  UINT32 response_size;
25318  std::string response_size_bytes;
25319  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25320  if (rc != TPM_RC_SUCCESS) {
25321    return rc;
25322  }
25323  TPM_RC response_code;
25324  std::string response_code_bytes;
25325  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25326  if (rc != TPM_RC_SUCCESS) {
25327    return rc;
25328  }
25329  if (response_size != response.size()) {
25330    return TPM_RC_SIZE;
25331  }
25332  if (response_code != TPM_RC_SUCCESS) {
25333    return response_code;
25334  }
25335  TPM_CC command_code = TPM_CC_HierarchyControl;
25336  std::string command_code_bytes;
25337  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25338  if (rc != TPM_RC_SUCCESS) {
25339    return rc;
25340  }
25341  std::string authorization_section_bytes;
25342  if (tag == TPM_ST_SESSIONS) {
25343    UINT32 parameter_section_size = buffer.size();
25344    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25345    if (rc != TPM_RC_SUCCESS) {
25346      return rc;
25347    }
25348    if (parameter_section_size > buffer.size()) {
25349      return TPM_RC_INSUFFICIENT;
25350    }
25351    authorization_section_bytes = buffer.substr(parameter_section_size);
25352    // Keep the parameter section in |buffer|.
25353    buffer.erase(parameter_section_size);
25354  }
25355  std::unique_ptr<crypto::SecureHash> hash(
25356      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25357  hash->Update(response_code_bytes.data(), response_code_bytes.size());
25358  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25359  hash->Update(buffer.data(), buffer.size());
25360  std::string response_hash(32, 0);
25361  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
25362  if (tag == TPM_ST_SESSIONS) {
25363    CHECK(authorization_delegate) << "Authorization delegate missing!";
25364    if (!authorization_delegate->CheckResponseAuthorization(
25365            response_hash, authorization_section_bytes)) {
25366      return TRUNKS_RC_AUTHORIZATION_FAILED;
25367    }
25368  }
25369  return TPM_RC_SUCCESS;
25370}
25371
25372void HierarchyControlErrorCallback(
25373    const Tpm::HierarchyControlResponse& callback,
25374    TPM_RC response_code) {
25375  VLOG(1) << __func__;
25376  callback.Run(response_code);
25377}
25378
25379void HierarchyControlResponseParser(
25380    const Tpm::HierarchyControlResponse& callback,
25381    AuthorizationDelegate* authorization_delegate,
25382    const std::string& response) {
25383  VLOG(1) << __func__;
25384  base::Callback<void(TPM_RC)> error_reporter =
25385      base::Bind(HierarchyControlErrorCallback, callback);
25386  TPM_RC rc =
25387      Tpm::ParseResponse_HierarchyControl(response, authorization_delegate);
25388  if (rc != TPM_RC_SUCCESS) {
25389    error_reporter.Run(rc);
25390    return;
25391  }
25392  callback.Run(rc);
25393}
25394
25395void Tpm::HierarchyControl(const TPMI_RH_HIERARCHY& auth_handle,
25396                           const std::string& auth_handle_name,
25397                           const TPMI_RH_ENABLES& enable,
25398                           const TPMI_YES_NO& state,
25399                           AuthorizationDelegate* authorization_delegate,
25400                           const HierarchyControlResponse& callback) {
25401  VLOG(1) << __func__;
25402  base::Callback<void(TPM_RC)> error_reporter =
25403      base::Bind(HierarchyControlErrorCallback, callback);
25404  base::Callback<void(const std::string&)> parser = base::Bind(
25405      HierarchyControlResponseParser, callback, authorization_delegate);
25406  std::string command;
25407  TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25408                                                enable, state, &command,
25409                                                authorization_delegate);
25410  if (rc != TPM_RC_SUCCESS) {
25411    error_reporter.Run(rc);
25412    return;
25413  }
25414  transceiver_->SendCommand(command, parser);
25415}
25416
25417TPM_RC Tpm::HierarchyControlSync(
25418    const TPMI_RH_HIERARCHY& auth_handle,
25419    const std::string& auth_handle_name,
25420    const TPMI_RH_ENABLES& enable,
25421    const TPMI_YES_NO& state,
25422    AuthorizationDelegate* authorization_delegate) {
25423  VLOG(1) << __func__;
25424  std::string command;
25425  TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25426                                                enable, state, &command,
25427                                                authorization_delegate);
25428  if (rc != TPM_RC_SUCCESS) {
25429    return rc;
25430  }
25431  std::string response = transceiver_->SendCommandAndWait(command);
25432  rc = ParseResponse_HierarchyControl(response, authorization_delegate);
25433  return rc;
25434}
25435
25436TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy(
25437    const TPMI_RH_HIERARCHY& auth_handle,
25438    const std::string& auth_handle_name,
25439    const TPM2B_DIGEST& auth_policy,
25440    const TPMI_ALG_HASH& hash_alg,
25441    std::string* serialized_command,
25442    AuthorizationDelegate* authorization_delegate) {
25443  VLOG(3) << __func__;
25444  TPM_RC rc = TPM_RC_SUCCESS;
25445  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25446  UINT32 command_size = 10;  // Header size.
25447  std::string handle_section_bytes;
25448  std::string parameter_section_bytes;
25449  TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25450  bool is_command_parameter_encryption_possible = true;
25451  bool is_response_parameter_encryption_possible = false;
25452  std::string command_code_bytes;
25453  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25454  if (rc != TPM_RC_SUCCESS) {
25455    return rc;
25456  }
25457  std::string auth_handle_bytes;
25458  rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25459  if (rc != TPM_RC_SUCCESS) {
25460    return rc;
25461  }
25462  std::string auth_policy_bytes;
25463  rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
25464  if (rc != TPM_RC_SUCCESS) {
25465    return rc;
25466  }
25467  std::string hash_alg_bytes;
25468  rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
25469  if (rc != TPM_RC_SUCCESS) {
25470    return rc;
25471  }
25472  if (authorization_delegate) {
25473    // Encrypt just the parameter data, not the size.
25474    std::string tmp = auth_policy_bytes.substr(2);
25475    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25476      return TRUNKS_RC_ENCRYPTION_FAILED;
25477    }
25478    auth_policy_bytes.replace(2, std::string::npos, tmp);
25479  }
25480  std::unique_ptr<crypto::SecureHash> hash(
25481      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25482  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25483  hash->Update(auth_handle_name.data(), auth_handle_name.size());
25484  handle_section_bytes += auth_handle_bytes;
25485  command_size += auth_handle_bytes.size();
25486  hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
25487  parameter_section_bytes += auth_policy_bytes;
25488  command_size += auth_policy_bytes.size();
25489  hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
25490  parameter_section_bytes += hash_alg_bytes;
25491  command_size += hash_alg_bytes.size();
25492  std::string command_hash(32, 0);
25493  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
25494  std::string authorization_section_bytes;
25495  std::string authorization_size_bytes;
25496  if (authorization_delegate) {
25497    if (!authorization_delegate->GetCommandAuthorization(
25498            command_hash, is_command_parameter_encryption_possible,
25499            is_response_parameter_encryption_possible,
25500            &authorization_section_bytes)) {
25501      return TRUNKS_RC_AUTHORIZATION_FAILED;
25502    }
25503    if (!authorization_section_bytes.empty()) {
25504      tag = TPM_ST_SESSIONS;
25505      std::string tmp;
25506      rc = Serialize_UINT32(authorization_section_bytes.size(),
25507                            &authorization_size_bytes);
25508      if (rc != TPM_RC_SUCCESS) {
25509        return rc;
25510      }
25511      command_size +=
25512          authorization_size_bytes.size() + authorization_section_bytes.size();
25513    }
25514  }
25515  std::string tag_bytes;
25516  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25517  if (rc != TPM_RC_SUCCESS) {
25518    return rc;
25519  }
25520  std::string command_size_bytes;
25521  rc = Serialize_UINT32(command_size, &command_size_bytes);
25522  if (rc != TPM_RC_SUCCESS) {
25523    return rc;
25524  }
25525  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25526                        handle_section_bytes + authorization_size_bytes +
25527                        authorization_section_bytes + parameter_section_bytes;
25528  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25529  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
25530                                            serialized_command->size());
25531  return TPM_RC_SUCCESS;
25532}
25533
25534TPM_RC Tpm::ParseResponse_SetPrimaryPolicy(
25535    const std::string& response,
25536    AuthorizationDelegate* authorization_delegate) {
25537  VLOG(3) << __func__;
25538  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25539  TPM_RC rc = TPM_RC_SUCCESS;
25540  std::string buffer(response);
25541  TPM_ST tag;
25542  std::string tag_bytes;
25543  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25544  if (rc != TPM_RC_SUCCESS) {
25545    return rc;
25546  }
25547  UINT32 response_size;
25548  std::string response_size_bytes;
25549  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25550  if (rc != TPM_RC_SUCCESS) {
25551    return rc;
25552  }
25553  TPM_RC response_code;
25554  std::string response_code_bytes;
25555  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25556  if (rc != TPM_RC_SUCCESS) {
25557    return rc;
25558  }
25559  if (response_size != response.size()) {
25560    return TPM_RC_SIZE;
25561  }
25562  if (response_code != TPM_RC_SUCCESS) {
25563    return response_code;
25564  }
25565  TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25566  std::string command_code_bytes;
25567  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25568  if (rc != TPM_RC_SUCCESS) {
25569    return rc;
25570  }
25571  std::string authorization_section_bytes;
25572  if (tag == TPM_ST_SESSIONS) {
25573    UINT32 parameter_section_size = buffer.size();
25574    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25575    if (rc != TPM_RC_SUCCESS) {
25576      return rc;
25577    }
25578    if (parameter_section_size > buffer.size()) {
25579      return TPM_RC_INSUFFICIENT;
25580    }
25581    authorization_section_bytes = buffer.substr(parameter_section_size);
25582    // Keep the parameter section in |buffer|.
25583    buffer.erase(parameter_section_size);
25584  }
25585  std::unique_ptr<crypto::SecureHash> hash(
25586      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25587  hash->Update(response_code_bytes.data(), response_code_bytes.size());
25588  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25589  hash->Update(buffer.data(), buffer.size());
25590  std::string response_hash(32, 0);
25591  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
25592  if (tag == TPM_ST_SESSIONS) {
25593    CHECK(authorization_delegate) << "Authorization delegate missing!";
25594    if (!authorization_delegate->CheckResponseAuthorization(
25595            response_hash, authorization_section_bytes)) {
25596      return TRUNKS_RC_AUTHORIZATION_FAILED;
25597    }
25598  }
25599  return TPM_RC_SUCCESS;
25600}
25601
25602void SetPrimaryPolicyErrorCallback(
25603    const Tpm::SetPrimaryPolicyResponse& callback,
25604    TPM_RC response_code) {
25605  VLOG(1) << __func__;
25606  callback.Run(response_code);
25607}
25608
25609void SetPrimaryPolicyResponseParser(
25610    const Tpm::SetPrimaryPolicyResponse& callback,
25611    AuthorizationDelegate* authorization_delegate,
25612    const std::string& response) {
25613  VLOG(1) << __func__;
25614  base::Callback<void(TPM_RC)> error_reporter =
25615      base::Bind(SetPrimaryPolicyErrorCallback, callback);
25616  TPM_RC rc =
25617      Tpm::ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
25618  if (rc != TPM_RC_SUCCESS) {
25619    error_reporter.Run(rc);
25620    return;
25621  }
25622  callback.Run(rc);
25623}
25624
25625void Tpm::SetPrimaryPolicy(const TPMI_RH_HIERARCHY& auth_handle,
25626                           const std::string& auth_handle_name,
25627                           const TPM2B_DIGEST& auth_policy,
25628                           const TPMI_ALG_HASH& hash_alg,
25629                           AuthorizationDelegate* authorization_delegate,
25630                           const SetPrimaryPolicyResponse& callback) {
25631  VLOG(1) << __func__;
25632  base::Callback<void(TPM_RC)> error_reporter =
25633      base::Bind(SetPrimaryPolicyErrorCallback, callback);
25634  base::Callback<void(const std::string&)> parser = base::Bind(
25635      SetPrimaryPolicyResponseParser, callback, authorization_delegate);
25636  std::string command;
25637  TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
25638                                                auth_policy, hash_alg, &command,
25639                                                authorization_delegate);
25640  if (rc != TPM_RC_SUCCESS) {
25641    error_reporter.Run(rc);
25642    return;
25643  }
25644  transceiver_->SendCommand(command, parser);
25645}
25646
25647TPM_RC Tpm::SetPrimaryPolicySync(
25648    const TPMI_RH_HIERARCHY& auth_handle,
25649    const std::string& auth_handle_name,
25650    const TPM2B_DIGEST& auth_policy,
25651    const TPMI_ALG_HASH& hash_alg,
25652    AuthorizationDelegate* authorization_delegate) {
25653  VLOG(1) << __func__;
25654  std::string command;
25655  TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
25656                                                auth_policy, hash_alg, &command,
25657                                                authorization_delegate);
25658  if (rc != TPM_RC_SUCCESS) {
25659    return rc;
25660  }
25661  std::string response = transceiver_->SendCommandAndWait(command);
25662  rc = ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
25663  return rc;
25664}
25665
25666TPM_RC Tpm::SerializeCommand_ChangePPS(
25667    const TPMI_RH_PLATFORM& auth_handle,
25668    const std::string& auth_handle_name,
25669    std::string* serialized_command,
25670    AuthorizationDelegate* authorization_delegate) {
25671  VLOG(3) << __func__;
25672  TPM_RC rc = TPM_RC_SUCCESS;
25673  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25674  UINT32 command_size = 10;  // Header size.
25675  std::string handle_section_bytes;
25676  std::string parameter_section_bytes;
25677  TPM_CC command_code = TPM_CC_ChangePPS;
25678  bool is_command_parameter_encryption_possible = false;
25679  bool is_response_parameter_encryption_possible = false;
25680  std::string command_code_bytes;
25681  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25682  if (rc != TPM_RC_SUCCESS) {
25683    return rc;
25684  }
25685  std::string auth_handle_bytes;
25686  rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
25687  if (rc != TPM_RC_SUCCESS) {
25688    return rc;
25689  }
25690  std::unique_ptr<crypto::SecureHash> hash(
25691      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25692  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25693  hash->Update(auth_handle_name.data(), auth_handle_name.size());
25694  handle_section_bytes += auth_handle_bytes;
25695  command_size += auth_handle_bytes.size();
25696  std::string command_hash(32, 0);
25697  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
25698  std::string authorization_section_bytes;
25699  std::string authorization_size_bytes;
25700  if (authorization_delegate) {
25701    if (!authorization_delegate->GetCommandAuthorization(
25702            command_hash, is_command_parameter_encryption_possible,
25703            is_response_parameter_encryption_possible,
25704            &authorization_section_bytes)) {
25705      return TRUNKS_RC_AUTHORIZATION_FAILED;
25706    }
25707    if (!authorization_section_bytes.empty()) {
25708      tag = TPM_ST_SESSIONS;
25709      std::string tmp;
25710      rc = Serialize_UINT32(authorization_section_bytes.size(),
25711                            &authorization_size_bytes);
25712      if (rc != TPM_RC_SUCCESS) {
25713        return rc;
25714      }
25715      command_size +=
25716          authorization_size_bytes.size() + authorization_section_bytes.size();
25717    }
25718  }
25719  std::string tag_bytes;
25720  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25721  if (rc != TPM_RC_SUCCESS) {
25722    return rc;
25723  }
25724  std::string command_size_bytes;
25725  rc = Serialize_UINT32(command_size, &command_size_bytes);
25726  if (rc != TPM_RC_SUCCESS) {
25727    return rc;
25728  }
25729  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25730                        handle_section_bytes + authorization_size_bytes +
25731                        authorization_section_bytes + parameter_section_bytes;
25732  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25733  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
25734                                            serialized_command->size());
25735  return TPM_RC_SUCCESS;
25736}
25737
25738TPM_RC Tpm::ParseResponse_ChangePPS(
25739    const std::string& response,
25740    AuthorizationDelegate* authorization_delegate) {
25741  VLOG(3) << __func__;
25742  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25743  TPM_RC rc = TPM_RC_SUCCESS;
25744  std::string buffer(response);
25745  TPM_ST tag;
25746  std::string tag_bytes;
25747  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25748  if (rc != TPM_RC_SUCCESS) {
25749    return rc;
25750  }
25751  UINT32 response_size;
25752  std::string response_size_bytes;
25753  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25754  if (rc != TPM_RC_SUCCESS) {
25755    return rc;
25756  }
25757  TPM_RC response_code;
25758  std::string response_code_bytes;
25759  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25760  if (rc != TPM_RC_SUCCESS) {
25761    return rc;
25762  }
25763  if (response_size != response.size()) {
25764    return TPM_RC_SIZE;
25765  }
25766  if (response_code != TPM_RC_SUCCESS) {
25767    return response_code;
25768  }
25769  TPM_CC command_code = TPM_CC_ChangePPS;
25770  std::string command_code_bytes;
25771  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25772  if (rc != TPM_RC_SUCCESS) {
25773    return rc;
25774  }
25775  std::string authorization_section_bytes;
25776  if (tag == TPM_ST_SESSIONS) {
25777    UINT32 parameter_section_size = buffer.size();
25778    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25779    if (rc != TPM_RC_SUCCESS) {
25780      return rc;
25781    }
25782    if (parameter_section_size > buffer.size()) {
25783      return TPM_RC_INSUFFICIENT;
25784    }
25785    authorization_section_bytes = buffer.substr(parameter_section_size);
25786    // Keep the parameter section in |buffer|.
25787    buffer.erase(parameter_section_size);
25788  }
25789  std::unique_ptr<crypto::SecureHash> hash(
25790      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25791  hash->Update(response_code_bytes.data(), response_code_bytes.size());
25792  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25793  hash->Update(buffer.data(), buffer.size());
25794  std::string response_hash(32, 0);
25795  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
25796  if (tag == TPM_ST_SESSIONS) {
25797    CHECK(authorization_delegate) << "Authorization delegate missing!";
25798    if (!authorization_delegate->CheckResponseAuthorization(
25799            response_hash, authorization_section_bytes)) {
25800      return TRUNKS_RC_AUTHORIZATION_FAILED;
25801    }
25802  }
25803  return TPM_RC_SUCCESS;
25804}
25805
25806void ChangePPSErrorCallback(const Tpm::ChangePPSResponse& callback,
25807                            TPM_RC response_code) {
25808  VLOG(1) << __func__;
25809  callback.Run(response_code);
25810}
25811
25812void ChangePPSResponseParser(const Tpm::ChangePPSResponse& callback,
25813                             AuthorizationDelegate* authorization_delegate,
25814                             const std::string& response) {
25815  VLOG(1) << __func__;
25816  base::Callback<void(TPM_RC)> error_reporter =
25817      base::Bind(ChangePPSErrorCallback, callback);
25818  TPM_RC rc = Tpm::ParseResponse_ChangePPS(response, authorization_delegate);
25819  if (rc != TPM_RC_SUCCESS) {
25820    error_reporter.Run(rc);
25821    return;
25822  }
25823  callback.Run(rc);
25824}
25825
25826void Tpm::ChangePPS(const TPMI_RH_PLATFORM& auth_handle,
25827                    const std::string& auth_handle_name,
25828                    AuthorizationDelegate* authorization_delegate,
25829                    const ChangePPSResponse& callback) {
25830  VLOG(1) << __func__;
25831  base::Callback<void(TPM_RC)> error_reporter =
25832      base::Bind(ChangePPSErrorCallback, callback);
25833  base::Callback<void(const std::string&)> parser =
25834      base::Bind(ChangePPSResponseParser, callback, authorization_delegate);
25835  std::string command;
25836  TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
25837                                         &command, authorization_delegate);
25838  if (rc != TPM_RC_SUCCESS) {
25839    error_reporter.Run(rc);
25840    return;
25841  }
25842  transceiver_->SendCommand(command, parser);
25843}
25844
25845TPM_RC Tpm::ChangePPSSync(const TPMI_RH_PLATFORM& auth_handle,
25846                          const std::string& auth_handle_name,
25847                          AuthorizationDelegate* authorization_delegate) {
25848  VLOG(1) << __func__;
25849  std::string command;
25850  TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
25851                                         &command, authorization_delegate);
25852  if (rc != TPM_RC_SUCCESS) {
25853    return rc;
25854  }
25855  std::string response = transceiver_->SendCommandAndWait(command);
25856  rc = ParseResponse_ChangePPS(response, authorization_delegate);
25857  return rc;
25858}
25859
25860TPM_RC Tpm::SerializeCommand_ChangeEPS(
25861    const TPMI_RH_PLATFORM& auth_handle,
25862    const std::string& auth_handle_name,
25863    std::string* serialized_command,
25864    AuthorizationDelegate* authorization_delegate) {
25865  VLOG(3) << __func__;
25866  TPM_RC rc = TPM_RC_SUCCESS;
25867  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25868  UINT32 command_size = 10;  // Header size.
25869  std::string handle_section_bytes;
25870  std::string parameter_section_bytes;
25871  TPM_CC command_code = TPM_CC_ChangeEPS;
25872  bool is_command_parameter_encryption_possible = false;
25873  bool is_response_parameter_encryption_possible = false;
25874  std::string command_code_bytes;
25875  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25876  if (rc != TPM_RC_SUCCESS) {
25877    return rc;
25878  }
25879  std::string auth_handle_bytes;
25880  rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
25881  if (rc != TPM_RC_SUCCESS) {
25882    return rc;
25883  }
25884  std::unique_ptr<crypto::SecureHash> hash(
25885      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25886  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25887  hash->Update(auth_handle_name.data(), auth_handle_name.size());
25888  handle_section_bytes += auth_handle_bytes;
25889  command_size += auth_handle_bytes.size();
25890  std::string command_hash(32, 0);
25891  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
25892  std::string authorization_section_bytes;
25893  std::string authorization_size_bytes;
25894  if (authorization_delegate) {
25895    if (!authorization_delegate->GetCommandAuthorization(
25896            command_hash, is_command_parameter_encryption_possible,
25897            is_response_parameter_encryption_possible,
25898            &authorization_section_bytes)) {
25899      return TRUNKS_RC_AUTHORIZATION_FAILED;
25900    }
25901    if (!authorization_section_bytes.empty()) {
25902      tag = TPM_ST_SESSIONS;
25903      std::string tmp;
25904      rc = Serialize_UINT32(authorization_section_bytes.size(),
25905                            &authorization_size_bytes);
25906      if (rc != TPM_RC_SUCCESS) {
25907        return rc;
25908      }
25909      command_size +=
25910          authorization_size_bytes.size() + authorization_section_bytes.size();
25911    }
25912  }
25913  std::string tag_bytes;
25914  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25915  if (rc != TPM_RC_SUCCESS) {
25916    return rc;
25917  }
25918  std::string command_size_bytes;
25919  rc = Serialize_UINT32(command_size, &command_size_bytes);
25920  if (rc != TPM_RC_SUCCESS) {
25921    return rc;
25922  }
25923  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25924                        handle_section_bytes + authorization_size_bytes +
25925                        authorization_section_bytes + parameter_section_bytes;
25926  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25927  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
25928                                            serialized_command->size());
25929  return TPM_RC_SUCCESS;
25930}
25931
25932TPM_RC Tpm::ParseResponse_ChangeEPS(
25933    const std::string& response,
25934    AuthorizationDelegate* authorization_delegate) {
25935  VLOG(3) << __func__;
25936  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25937  TPM_RC rc = TPM_RC_SUCCESS;
25938  std::string buffer(response);
25939  TPM_ST tag;
25940  std::string tag_bytes;
25941  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25942  if (rc != TPM_RC_SUCCESS) {
25943    return rc;
25944  }
25945  UINT32 response_size;
25946  std::string response_size_bytes;
25947  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25948  if (rc != TPM_RC_SUCCESS) {
25949    return rc;
25950  }
25951  TPM_RC response_code;
25952  std::string response_code_bytes;
25953  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25954  if (rc != TPM_RC_SUCCESS) {
25955    return rc;
25956  }
25957  if (response_size != response.size()) {
25958    return TPM_RC_SIZE;
25959  }
25960  if (response_code != TPM_RC_SUCCESS) {
25961    return response_code;
25962  }
25963  TPM_CC command_code = TPM_CC_ChangeEPS;
25964  std::string command_code_bytes;
25965  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25966  if (rc != TPM_RC_SUCCESS) {
25967    return rc;
25968  }
25969  std::string authorization_section_bytes;
25970  if (tag == TPM_ST_SESSIONS) {
25971    UINT32 parameter_section_size = buffer.size();
25972    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25973    if (rc != TPM_RC_SUCCESS) {
25974      return rc;
25975    }
25976    if (parameter_section_size > buffer.size()) {
25977      return TPM_RC_INSUFFICIENT;
25978    }
25979    authorization_section_bytes = buffer.substr(parameter_section_size);
25980    // Keep the parameter section in |buffer|.
25981    buffer.erase(parameter_section_size);
25982  }
25983  std::unique_ptr<crypto::SecureHash> hash(
25984      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25985  hash->Update(response_code_bytes.data(), response_code_bytes.size());
25986  hash->Update(command_code_bytes.data(), command_code_bytes.size());
25987  hash->Update(buffer.data(), buffer.size());
25988  std::string response_hash(32, 0);
25989  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
25990  if (tag == TPM_ST_SESSIONS) {
25991    CHECK(authorization_delegate) << "Authorization delegate missing!";
25992    if (!authorization_delegate->CheckResponseAuthorization(
25993            response_hash, authorization_section_bytes)) {
25994      return TRUNKS_RC_AUTHORIZATION_FAILED;
25995    }
25996  }
25997  return TPM_RC_SUCCESS;
25998}
25999
26000void ChangeEPSErrorCallback(const Tpm::ChangeEPSResponse& callback,
26001                            TPM_RC response_code) {
26002  VLOG(1) << __func__;
26003  callback.Run(response_code);
26004}
26005
26006void ChangeEPSResponseParser(const Tpm::ChangeEPSResponse& callback,
26007                             AuthorizationDelegate* authorization_delegate,
26008                             const std::string& response) {
26009  VLOG(1) << __func__;
26010  base::Callback<void(TPM_RC)> error_reporter =
26011      base::Bind(ChangeEPSErrorCallback, callback);
26012  TPM_RC rc = Tpm::ParseResponse_ChangeEPS(response, authorization_delegate);
26013  if (rc != TPM_RC_SUCCESS) {
26014    error_reporter.Run(rc);
26015    return;
26016  }
26017  callback.Run(rc);
26018}
26019
26020void Tpm::ChangeEPS(const TPMI_RH_PLATFORM& auth_handle,
26021                    const std::string& auth_handle_name,
26022                    AuthorizationDelegate* authorization_delegate,
26023                    const ChangeEPSResponse& callback) {
26024  VLOG(1) << __func__;
26025  base::Callback<void(TPM_RC)> error_reporter =
26026      base::Bind(ChangeEPSErrorCallback, callback);
26027  base::Callback<void(const std::string&)> parser =
26028      base::Bind(ChangeEPSResponseParser, callback, authorization_delegate);
26029  std::string command;
26030  TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26031                                         &command, authorization_delegate);
26032  if (rc != TPM_RC_SUCCESS) {
26033    error_reporter.Run(rc);
26034    return;
26035  }
26036  transceiver_->SendCommand(command, parser);
26037}
26038
26039TPM_RC Tpm::ChangeEPSSync(const TPMI_RH_PLATFORM& auth_handle,
26040                          const std::string& auth_handle_name,
26041                          AuthorizationDelegate* authorization_delegate) {
26042  VLOG(1) << __func__;
26043  std::string command;
26044  TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26045                                         &command, authorization_delegate);
26046  if (rc != TPM_RC_SUCCESS) {
26047    return rc;
26048  }
26049  std::string response = transceiver_->SendCommandAndWait(command);
26050  rc = ParseResponse_ChangeEPS(response, authorization_delegate);
26051  return rc;
26052}
26053
26054TPM_RC Tpm::SerializeCommand_Clear(
26055    const TPMI_RH_CLEAR& auth_handle,
26056    const std::string& auth_handle_name,
26057    std::string* serialized_command,
26058    AuthorizationDelegate* authorization_delegate) {
26059  VLOG(3) << __func__;
26060  TPM_RC rc = TPM_RC_SUCCESS;
26061  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26062  UINT32 command_size = 10;  // Header size.
26063  std::string handle_section_bytes;
26064  std::string parameter_section_bytes;
26065  TPM_CC command_code = TPM_CC_Clear;
26066  bool is_command_parameter_encryption_possible = false;
26067  bool is_response_parameter_encryption_possible = false;
26068  std::string command_code_bytes;
26069  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26070  if (rc != TPM_RC_SUCCESS) {
26071    return rc;
26072  }
26073  std::string auth_handle_bytes;
26074  rc = Serialize_TPMI_RH_CLEAR(auth_handle, &auth_handle_bytes);
26075  if (rc != TPM_RC_SUCCESS) {
26076    return rc;
26077  }
26078  std::unique_ptr<crypto::SecureHash> hash(
26079      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26080  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26081  hash->Update(auth_handle_name.data(), auth_handle_name.size());
26082  handle_section_bytes += auth_handle_bytes;
26083  command_size += auth_handle_bytes.size();
26084  std::string command_hash(32, 0);
26085  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
26086  std::string authorization_section_bytes;
26087  std::string authorization_size_bytes;
26088  if (authorization_delegate) {
26089    if (!authorization_delegate->GetCommandAuthorization(
26090            command_hash, is_command_parameter_encryption_possible,
26091            is_response_parameter_encryption_possible,
26092            &authorization_section_bytes)) {
26093      return TRUNKS_RC_AUTHORIZATION_FAILED;
26094    }
26095    if (!authorization_section_bytes.empty()) {
26096      tag = TPM_ST_SESSIONS;
26097      std::string tmp;
26098      rc = Serialize_UINT32(authorization_section_bytes.size(),
26099                            &authorization_size_bytes);
26100      if (rc != TPM_RC_SUCCESS) {
26101        return rc;
26102      }
26103      command_size +=
26104          authorization_size_bytes.size() + authorization_section_bytes.size();
26105    }
26106  }
26107  std::string tag_bytes;
26108  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26109  if (rc != TPM_RC_SUCCESS) {
26110    return rc;
26111  }
26112  std::string command_size_bytes;
26113  rc = Serialize_UINT32(command_size, &command_size_bytes);
26114  if (rc != TPM_RC_SUCCESS) {
26115    return rc;
26116  }
26117  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26118                        handle_section_bytes + authorization_size_bytes +
26119                        authorization_section_bytes + parameter_section_bytes;
26120  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26121  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
26122                                            serialized_command->size());
26123  return TPM_RC_SUCCESS;
26124}
26125
26126TPM_RC Tpm::ParseResponse_Clear(const std::string& response,
26127                                AuthorizationDelegate* authorization_delegate) {
26128  VLOG(3) << __func__;
26129  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26130  TPM_RC rc = TPM_RC_SUCCESS;
26131  std::string buffer(response);
26132  TPM_ST tag;
26133  std::string tag_bytes;
26134  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26135  if (rc != TPM_RC_SUCCESS) {
26136    return rc;
26137  }
26138  UINT32 response_size;
26139  std::string response_size_bytes;
26140  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26141  if (rc != TPM_RC_SUCCESS) {
26142    return rc;
26143  }
26144  TPM_RC response_code;
26145  std::string response_code_bytes;
26146  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26147  if (rc != TPM_RC_SUCCESS) {
26148    return rc;
26149  }
26150  if (response_size != response.size()) {
26151    return TPM_RC_SIZE;
26152  }
26153  if (response_code != TPM_RC_SUCCESS) {
26154    return response_code;
26155  }
26156  TPM_CC command_code = TPM_CC_Clear;
26157  std::string command_code_bytes;
26158  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26159  if (rc != TPM_RC_SUCCESS) {
26160    return rc;
26161  }
26162  std::string authorization_section_bytes;
26163  if (tag == TPM_ST_SESSIONS) {
26164    UINT32 parameter_section_size = buffer.size();
26165    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26166    if (rc != TPM_RC_SUCCESS) {
26167      return rc;
26168    }
26169    if (parameter_section_size > buffer.size()) {
26170      return TPM_RC_INSUFFICIENT;
26171    }
26172    authorization_section_bytes = buffer.substr(parameter_section_size);
26173    // Keep the parameter section in |buffer|.
26174    buffer.erase(parameter_section_size);
26175  }
26176  std::unique_ptr<crypto::SecureHash> hash(
26177      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26178  hash->Update(response_code_bytes.data(), response_code_bytes.size());
26179  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26180  hash->Update(buffer.data(), buffer.size());
26181  std::string response_hash(32, 0);
26182  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
26183  if (tag == TPM_ST_SESSIONS) {
26184    CHECK(authorization_delegate) << "Authorization delegate missing!";
26185    if (!authorization_delegate->CheckResponseAuthorization(
26186            response_hash, authorization_section_bytes)) {
26187      return TRUNKS_RC_AUTHORIZATION_FAILED;
26188    }
26189  }
26190  return TPM_RC_SUCCESS;
26191}
26192
26193void ClearErrorCallback(const Tpm::ClearResponse& callback,
26194                        TPM_RC response_code) {
26195  VLOG(1) << __func__;
26196  callback.Run(response_code);
26197}
26198
26199void ClearResponseParser(const Tpm::ClearResponse& callback,
26200                         AuthorizationDelegate* authorization_delegate,
26201                         const std::string& response) {
26202  VLOG(1) << __func__;
26203  base::Callback<void(TPM_RC)> error_reporter =
26204      base::Bind(ClearErrorCallback, callback);
26205  TPM_RC rc = Tpm::ParseResponse_Clear(response, authorization_delegate);
26206  if (rc != TPM_RC_SUCCESS) {
26207    error_reporter.Run(rc);
26208    return;
26209  }
26210  callback.Run(rc);
26211}
26212
26213void Tpm::Clear(const TPMI_RH_CLEAR& auth_handle,
26214                const std::string& auth_handle_name,
26215                AuthorizationDelegate* authorization_delegate,
26216                const ClearResponse& callback) {
26217  VLOG(1) << __func__;
26218  base::Callback<void(TPM_RC)> error_reporter =
26219      base::Bind(ClearErrorCallback, callback);
26220  base::Callback<void(const std::string&)> parser =
26221      base::Bind(ClearResponseParser, callback, authorization_delegate);
26222  std::string command;
26223  TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26224                                     authorization_delegate);
26225  if (rc != TPM_RC_SUCCESS) {
26226    error_reporter.Run(rc);
26227    return;
26228  }
26229  transceiver_->SendCommand(command, parser);
26230}
26231
26232TPM_RC Tpm::ClearSync(const TPMI_RH_CLEAR& auth_handle,
26233                      const std::string& auth_handle_name,
26234                      AuthorizationDelegate* authorization_delegate) {
26235  VLOG(1) << __func__;
26236  std::string command;
26237  TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26238                                     authorization_delegate);
26239  if (rc != TPM_RC_SUCCESS) {
26240    return rc;
26241  }
26242  std::string response = transceiver_->SendCommandAndWait(command);
26243  rc = ParseResponse_Clear(response, authorization_delegate);
26244  return rc;
26245}
26246
26247TPM_RC Tpm::SerializeCommand_ClearControl(
26248    const TPMI_RH_CLEAR& auth,
26249    const std::string& auth_name,
26250    const TPMI_YES_NO& disable,
26251    std::string* serialized_command,
26252    AuthorizationDelegate* authorization_delegate) {
26253  VLOG(3) << __func__;
26254  TPM_RC rc = TPM_RC_SUCCESS;
26255  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26256  UINT32 command_size = 10;  // Header size.
26257  std::string handle_section_bytes;
26258  std::string parameter_section_bytes;
26259  TPM_CC command_code = TPM_CC_ClearControl;
26260  bool is_command_parameter_encryption_possible = false;
26261  bool is_response_parameter_encryption_possible = false;
26262  std::string command_code_bytes;
26263  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26264  if (rc != TPM_RC_SUCCESS) {
26265    return rc;
26266  }
26267  std::string auth_bytes;
26268  rc = Serialize_TPMI_RH_CLEAR(auth, &auth_bytes);
26269  if (rc != TPM_RC_SUCCESS) {
26270    return rc;
26271  }
26272  std::string disable_bytes;
26273  rc = Serialize_TPMI_YES_NO(disable, &disable_bytes);
26274  if (rc != TPM_RC_SUCCESS) {
26275    return rc;
26276  }
26277  std::unique_ptr<crypto::SecureHash> hash(
26278      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26279  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26280  hash->Update(auth_name.data(), auth_name.size());
26281  handle_section_bytes += auth_bytes;
26282  command_size += auth_bytes.size();
26283  hash->Update(disable_bytes.data(), disable_bytes.size());
26284  parameter_section_bytes += disable_bytes;
26285  command_size += disable_bytes.size();
26286  std::string command_hash(32, 0);
26287  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
26288  std::string authorization_section_bytes;
26289  std::string authorization_size_bytes;
26290  if (authorization_delegate) {
26291    if (!authorization_delegate->GetCommandAuthorization(
26292            command_hash, is_command_parameter_encryption_possible,
26293            is_response_parameter_encryption_possible,
26294            &authorization_section_bytes)) {
26295      return TRUNKS_RC_AUTHORIZATION_FAILED;
26296    }
26297    if (!authorization_section_bytes.empty()) {
26298      tag = TPM_ST_SESSIONS;
26299      std::string tmp;
26300      rc = Serialize_UINT32(authorization_section_bytes.size(),
26301                            &authorization_size_bytes);
26302      if (rc != TPM_RC_SUCCESS) {
26303        return rc;
26304      }
26305      command_size +=
26306          authorization_size_bytes.size() + authorization_section_bytes.size();
26307    }
26308  }
26309  std::string tag_bytes;
26310  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26311  if (rc != TPM_RC_SUCCESS) {
26312    return rc;
26313  }
26314  std::string command_size_bytes;
26315  rc = Serialize_UINT32(command_size, &command_size_bytes);
26316  if (rc != TPM_RC_SUCCESS) {
26317    return rc;
26318  }
26319  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26320                        handle_section_bytes + authorization_size_bytes +
26321                        authorization_section_bytes + parameter_section_bytes;
26322  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26323  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
26324                                            serialized_command->size());
26325  return TPM_RC_SUCCESS;
26326}
26327
26328TPM_RC Tpm::ParseResponse_ClearControl(
26329    const std::string& response,
26330    AuthorizationDelegate* authorization_delegate) {
26331  VLOG(3) << __func__;
26332  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26333  TPM_RC rc = TPM_RC_SUCCESS;
26334  std::string buffer(response);
26335  TPM_ST tag;
26336  std::string tag_bytes;
26337  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26338  if (rc != TPM_RC_SUCCESS) {
26339    return rc;
26340  }
26341  UINT32 response_size;
26342  std::string response_size_bytes;
26343  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26344  if (rc != TPM_RC_SUCCESS) {
26345    return rc;
26346  }
26347  TPM_RC response_code;
26348  std::string response_code_bytes;
26349  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26350  if (rc != TPM_RC_SUCCESS) {
26351    return rc;
26352  }
26353  if (response_size != response.size()) {
26354    return TPM_RC_SIZE;
26355  }
26356  if (response_code != TPM_RC_SUCCESS) {
26357    return response_code;
26358  }
26359  TPM_CC command_code = TPM_CC_ClearControl;
26360  std::string command_code_bytes;
26361  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26362  if (rc != TPM_RC_SUCCESS) {
26363    return rc;
26364  }
26365  std::string authorization_section_bytes;
26366  if (tag == TPM_ST_SESSIONS) {
26367    UINT32 parameter_section_size = buffer.size();
26368    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26369    if (rc != TPM_RC_SUCCESS) {
26370      return rc;
26371    }
26372    if (parameter_section_size > buffer.size()) {
26373      return TPM_RC_INSUFFICIENT;
26374    }
26375    authorization_section_bytes = buffer.substr(parameter_section_size);
26376    // Keep the parameter section in |buffer|.
26377    buffer.erase(parameter_section_size);
26378  }
26379  std::unique_ptr<crypto::SecureHash> hash(
26380      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26381  hash->Update(response_code_bytes.data(), response_code_bytes.size());
26382  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26383  hash->Update(buffer.data(), buffer.size());
26384  std::string response_hash(32, 0);
26385  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
26386  if (tag == TPM_ST_SESSIONS) {
26387    CHECK(authorization_delegate) << "Authorization delegate missing!";
26388    if (!authorization_delegate->CheckResponseAuthorization(
26389            response_hash, authorization_section_bytes)) {
26390      return TRUNKS_RC_AUTHORIZATION_FAILED;
26391    }
26392  }
26393  return TPM_RC_SUCCESS;
26394}
26395
26396void ClearControlErrorCallback(const Tpm::ClearControlResponse& callback,
26397                               TPM_RC response_code) {
26398  VLOG(1) << __func__;
26399  callback.Run(response_code);
26400}
26401
26402void ClearControlResponseParser(const Tpm::ClearControlResponse& callback,
26403                                AuthorizationDelegate* authorization_delegate,
26404                                const std::string& response) {
26405  VLOG(1) << __func__;
26406  base::Callback<void(TPM_RC)> error_reporter =
26407      base::Bind(ClearControlErrorCallback, callback);
26408  TPM_RC rc = Tpm::ParseResponse_ClearControl(response, authorization_delegate);
26409  if (rc != TPM_RC_SUCCESS) {
26410    error_reporter.Run(rc);
26411    return;
26412  }
26413  callback.Run(rc);
26414}
26415
26416void Tpm::ClearControl(const TPMI_RH_CLEAR& auth,
26417                       const std::string& auth_name,
26418                       const TPMI_YES_NO& disable,
26419                       AuthorizationDelegate* authorization_delegate,
26420                       const ClearControlResponse& callback) {
26421  VLOG(1) << __func__;
26422  base::Callback<void(TPM_RC)> error_reporter =
26423      base::Bind(ClearControlErrorCallback, callback);
26424  base::Callback<void(const std::string&)> parser =
26425      base::Bind(ClearControlResponseParser, callback, authorization_delegate);
26426  std::string command;
26427  TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26428                                            authorization_delegate);
26429  if (rc != TPM_RC_SUCCESS) {
26430    error_reporter.Run(rc);
26431    return;
26432  }
26433  transceiver_->SendCommand(command, parser);
26434}
26435
26436TPM_RC Tpm::ClearControlSync(const TPMI_RH_CLEAR& auth,
26437                             const std::string& auth_name,
26438                             const TPMI_YES_NO& disable,
26439                             AuthorizationDelegate* authorization_delegate) {
26440  VLOG(1) << __func__;
26441  std::string command;
26442  TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26443                                            authorization_delegate);
26444  if (rc != TPM_RC_SUCCESS) {
26445    return rc;
26446  }
26447  std::string response = transceiver_->SendCommandAndWait(command);
26448  rc = ParseResponse_ClearControl(response, authorization_delegate);
26449  return rc;
26450}
26451
26452TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth(
26453    const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26454    const std::string& auth_handle_name,
26455    const TPM2B_AUTH& new_auth,
26456    std::string* serialized_command,
26457    AuthorizationDelegate* authorization_delegate) {
26458  VLOG(3) << __func__;
26459  TPM_RC rc = TPM_RC_SUCCESS;
26460  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26461  UINT32 command_size = 10;  // Header size.
26462  std::string handle_section_bytes;
26463  std::string parameter_section_bytes;
26464  TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26465  bool is_command_parameter_encryption_possible = true;
26466  bool is_response_parameter_encryption_possible = false;
26467  std::string command_code_bytes;
26468  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26469  if (rc != TPM_RC_SUCCESS) {
26470    return rc;
26471  }
26472  std::string auth_handle_bytes;
26473  rc = Serialize_TPMI_RH_HIERARCHY_AUTH(auth_handle, &auth_handle_bytes);
26474  if (rc != TPM_RC_SUCCESS) {
26475    return rc;
26476  }
26477  std::string new_auth_bytes;
26478  rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
26479  if (rc != TPM_RC_SUCCESS) {
26480    return rc;
26481  }
26482  if (authorization_delegate) {
26483    // Encrypt just the parameter data, not the size.
26484    std::string tmp = new_auth_bytes.substr(2);
26485    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
26486      return TRUNKS_RC_ENCRYPTION_FAILED;
26487    }
26488    new_auth_bytes.replace(2, std::string::npos, tmp);
26489  }
26490  std::unique_ptr<crypto::SecureHash> hash(
26491      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26492  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26493  hash->Update(auth_handle_name.data(), auth_handle_name.size());
26494  handle_section_bytes += auth_handle_bytes;
26495  command_size += auth_handle_bytes.size();
26496  hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
26497  parameter_section_bytes += new_auth_bytes;
26498  command_size += new_auth_bytes.size();
26499  std::string command_hash(32, 0);
26500  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
26501  std::string authorization_section_bytes;
26502  std::string authorization_size_bytes;
26503  if (authorization_delegate) {
26504    if (!authorization_delegate->GetCommandAuthorization(
26505            command_hash, is_command_parameter_encryption_possible,
26506            is_response_parameter_encryption_possible,
26507            &authorization_section_bytes)) {
26508      return TRUNKS_RC_AUTHORIZATION_FAILED;
26509    }
26510    if (!authorization_section_bytes.empty()) {
26511      tag = TPM_ST_SESSIONS;
26512      std::string tmp;
26513      rc = Serialize_UINT32(authorization_section_bytes.size(),
26514                            &authorization_size_bytes);
26515      if (rc != TPM_RC_SUCCESS) {
26516        return rc;
26517      }
26518      command_size +=
26519          authorization_size_bytes.size() + authorization_section_bytes.size();
26520    }
26521  }
26522  std::string tag_bytes;
26523  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26524  if (rc != TPM_RC_SUCCESS) {
26525    return rc;
26526  }
26527  std::string command_size_bytes;
26528  rc = Serialize_UINT32(command_size, &command_size_bytes);
26529  if (rc != TPM_RC_SUCCESS) {
26530    return rc;
26531  }
26532  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26533                        handle_section_bytes + authorization_size_bytes +
26534                        authorization_section_bytes + parameter_section_bytes;
26535  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26536  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
26537                                            serialized_command->size());
26538  return TPM_RC_SUCCESS;
26539}
26540
26541TPM_RC Tpm::ParseResponse_HierarchyChangeAuth(
26542    const std::string& response,
26543    AuthorizationDelegate* authorization_delegate) {
26544  VLOG(3) << __func__;
26545  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26546  TPM_RC rc = TPM_RC_SUCCESS;
26547  std::string buffer(response);
26548  TPM_ST tag;
26549  std::string tag_bytes;
26550  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26551  if (rc != TPM_RC_SUCCESS) {
26552    return rc;
26553  }
26554  UINT32 response_size;
26555  std::string response_size_bytes;
26556  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26557  if (rc != TPM_RC_SUCCESS) {
26558    return rc;
26559  }
26560  TPM_RC response_code;
26561  std::string response_code_bytes;
26562  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26563  if (rc != TPM_RC_SUCCESS) {
26564    return rc;
26565  }
26566  if (response_size != response.size()) {
26567    return TPM_RC_SIZE;
26568  }
26569  if (response_code != TPM_RC_SUCCESS) {
26570    return response_code;
26571  }
26572  TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26573  std::string command_code_bytes;
26574  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26575  if (rc != TPM_RC_SUCCESS) {
26576    return rc;
26577  }
26578  std::string authorization_section_bytes;
26579  if (tag == TPM_ST_SESSIONS) {
26580    UINT32 parameter_section_size = buffer.size();
26581    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26582    if (rc != TPM_RC_SUCCESS) {
26583      return rc;
26584    }
26585    if (parameter_section_size > buffer.size()) {
26586      return TPM_RC_INSUFFICIENT;
26587    }
26588    authorization_section_bytes = buffer.substr(parameter_section_size);
26589    // Keep the parameter section in |buffer|.
26590    buffer.erase(parameter_section_size);
26591  }
26592  std::unique_ptr<crypto::SecureHash> hash(
26593      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26594  hash->Update(response_code_bytes.data(), response_code_bytes.size());
26595  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26596  hash->Update(buffer.data(), buffer.size());
26597  std::string response_hash(32, 0);
26598  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
26599  if (tag == TPM_ST_SESSIONS) {
26600    CHECK(authorization_delegate) << "Authorization delegate missing!";
26601    if (!authorization_delegate->CheckResponseAuthorization(
26602            response_hash, authorization_section_bytes)) {
26603      return TRUNKS_RC_AUTHORIZATION_FAILED;
26604    }
26605  }
26606  return TPM_RC_SUCCESS;
26607}
26608
26609void HierarchyChangeAuthErrorCallback(
26610    const Tpm::HierarchyChangeAuthResponse& callback,
26611    TPM_RC response_code) {
26612  VLOG(1) << __func__;
26613  callback.Run(response_code);
26614}
26615
26616void HierarchyChangeAuthResponseParser(
26617    const Tpm::HierarchyChangeAuthResponse& callback,
26618    AuthorizationDelegate* authorization_delegate,
26619    const std::string& response) {
26620  VLOG(1) << __func__;
26621  base::Callback<void(TPM_RC)> error_reporter =
26622      base::Bind(HierarchyChangeAuthErrorCallback, callback);
26623  TPM_RC rc =
26624      Tpm::ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
26625  if (rc != TPM_RC_SUCCESS) {
26626    error_reporter.Run(rc);
26627    return;
26628  }
26629  callback.Run(rc);
26630}
26631
26632void Tpm::HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26633                              const std::string& auth_handle_name,
26634                              const TPM2B_AUTH& new_auth,
26635                              AuthorizationDelegate* authorization_delegate,
26636                              const HierarchyChangeAuthResponse& callback) {
26637  VLOG(1) << __func__;
26638  base::Callback<void(TPM_RC)> error_reporter =
26639      base::Bind(HierarchyChangeAuthErrorCallback, callback);
26640  base::Callback<void(const std::string&)> parser = base::Bind(
26641      HierarchyChangeAuthResponseParser, callback, authorization_delegate);
26642  std::string command;
26643  TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
26644      auth_handle, auth_handle_name, new_auth, &command,
26645      authorization_delegate);
26646  if (rc != TPM_RC_SUCCESS) {
26647    error_reporter.Run(rc);
26648    return;
26649  }
26650  transceiver_->SendCommand(command, parser);
26651}
26652
26653TPM_RC Tpm::HierarchyChangeAuthSync(
26654    const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26655    const std::string& auth_handle_name,
26656    const TPM2B_AUTH& new_auth,
26657    AuthorizationDelegate* authorization_delegate) {
26658  VLOG(1) << __func__;
26659  std::string command;
26660  TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
26661      auth_handle, auth_handle_name, new_auth, &command,
26662      authorization_delegate);
26663  if (rc != TPM_RC_SUCCESS) {
26664    return rc;
26665  }
26666  std::string response = transceiver_->SendCommandAndWait(command);
26667  rc = ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
26668  return rc;
26669}
26670
26671TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset(
26672    const TPMI_RH_LOCKOUT& lock_handle,
26673    const std::string& lock_handle_name,
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_DictionaryAttackLockReset;
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 lock_handle_bytes;
26691  rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
26692  if (rc != TPM_RC_SUCCESS) {
26693    return rc;
26694  }
26695  std::unique_ptr<crypto::SecureHash> hash(
26696      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26697  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26698  hash->Update(lock_handle_name.data(), lock_handle_name.size());
26699  handle_section_bytes += lock_handle_bytes;
26700  command_size += lock_handle_bytes.size();
26701  std::string command_hash(32, 0);
26702  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
26703  std::string authorization_section_bytes;
26704  std::string authorization_size_bytes;
26705  if (authorization_delegate) {
26706    if (!authorization_delegate->GetCommandAuthorization(
26707            command_hash, is_command_parameter_encryption_possible,
26708            is_response_parameter_encryption_possible,
26709            &authorization_section_bytes)) {
26710      return TRUNKS_RC_AUTHORIZATION_FAILED;
26711    }
26712    if (!authorization_section_bytes.empty()) {
26713      tag = TPM_ST_SESSIONS;
26714      std::string tmp;
26715      rc = Serialize_UINT32(authorization_section_bytes.size(),
26716                            &authorization_size_bytes);
26717      if (rc != TPM_RC_SUCCESS) {
26718        return rc;
26719      }
26720      command_size +=
26721          authorization_size_bytes.size() + authorization_section_bytes.size();
26722    }
26723  }
26724  std::string tag_bytes;
26725  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26726  if (rc != TPM_RC_SUCCESS) {
26727    return rc;
26728  }
26729  std::string command_size_bytes;
26730  rc = Serialize_UINT32(command_size, &command_size_bytes);
26731  if (rc != TPM_RC_SUCCESS) {
26732    return rc;
26733  }
26734  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26735                        handle_section_bytes + authorization_size_bytes +
26736                        authorization_section_bytes + parameter_section_bytes;
26737  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26738  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
26739                                            serialized_command->size());
26740  return TPM_RC_SUCCESS;
26741}
26742
26743TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset(
26744    const std::string& response,
26745    AuthorizationDelegate* authorization_delegate) {
26746  VLOG(3) << __func__;
26747  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26748  TPM_RC rc = TPM_RC_SUCCESS;
26749  std::string buffer(response);
26750  TPM_ST tag;
26751  std::string tag_bytes;
26752  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26753  if (rc != TPM_RC_SUCCESS) {
26754    return rc;
26755  }
26756  UINT32 response_size;
26757  std::string response_size_bytes;
26758  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26759  if (rc != TPM_RC_SUCCESS) {
26760    return rc;
26761  }
26762  TPM_RC response_code;
26763  std::string response_code_bytes;
26764  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26765  if (rc != TPM_RC_SUCCESS) {
26766    return rc;
26767  }
26768  if (response_size != response.size()) {
26769    return TPM_RC_SIZE;
26770  }
26771  if (response_code != TPM_RC_SUCCESS) {
26772    return response_code;
26773  }
26774  TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
26775  std::string command_code_bytes;
26776  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26777  if (rc != TPM_RC_SUCCESS) {
26778    return rc;
26779  }
26780  std::string authorization_section_bytes;
26781  if (tag == TPM_ST_SESSIONS) {
26782    UINT32 parameter_section_size = buffer.size();
26783    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26784    if (rc != TPM_RC_SUCCESS) {
26785      return rc;
26786    }
26787    if (parameter_section_size > buffer.size()) {
26788      return TPM_RC_INSUFFICIENT;
26789    }
26790    authorization_section_bytes = buffer.substr(parameter_section_size);
26791    // Keep the parameter section in |buffer|.
26792    buffer.erase(parameter_section_size);
26793  }
26794  std::unique_ptr<crypto::SecureHash> hash(
26795      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26796  hash->Update(response_code_bytes.data(), response_code_bytes.size());
26797  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26798  hash->Update(buffer.data(), buffer.size());
26799  std::string response_hash(32, 0);
26800  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
26801  if (tag == TPM_ST_SESSIONS) {
26802    CHECK(authorization_delegate) << "Authorization delegate missing!";
26803    if (!authorization_delegate->CheckResponseAuthorization(
26804            response_hash, authorization_section_bytes)) {
26805      return TRUNKS_RC_AUTHORIZATION_FAILED;
26806    }
26807  }
26808  return TPM_RC_SUCCESS;
26809}
26810
26811void DictionaryAttackLockResetErrorCallback(
26812    const Tpm::DictionaryAttackLockResetResponse& callback,
26813    TPM_RC response_code) {
26814  VLOG(1) << __func__;
26815  callback.Run(response_code);
26816}
26817
26818void DictionaryAttackLockResetResponseParser(
26819    const Tpm::DictionaryAttackLockResetResponse& callback,
26820    AuthorizationDelegate* authorization_delegate,
26821    const std::string& response) {
26822  VLOG(1) << __func__;
26823  base::Callback<void(TPM_RC)> error_reporter =
26824      base::Bind(DictionaryAttackLockResetErrorCallback, callback);
26825  TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset(
26826      response, authorization_delegate);
26827  if (rc != TPM_RC_SUCCESS) {
26828    error_reporter.Run(rc);
26829    return;
26830  }
26831  callback.Run(rc);
26832}
26833
26834void Tpm::DictionaryAttackLockReset(
26835    const TPMI_RH_LOCKOUT& lock_handle,
26836    const std::string& lock_handle_name,
26837    AuthorizationDelegate* authorization_delegate,
26838    const DictionaryAttackLockResetResponse& callback) {
26839  VLOG(1) << __func__;
26840  base::Callback<void(TPM_RC)> error_reporter =
26841      base::Bind(DictionaryAttackLockResetErrorCallback, callback);
26842  base::Callback<void(const std::string&)> parser =
26843      base::Bind(DictionaryAttackLockResetResponseParser, callback,
26844                 authorization_delegate);
26845  std::string command;
26846  TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
26847      lock_handle, lock_handle_name, &command, authorization_delegate);
26848  if (rc != TPM_RC_SUCCESS) {
26849    error_reporter.Run(rc);
26850    return;
26851  }
26852  transceiver_->SendCommand(command, parser);
26853}
26854
26855TPM_RC Tpm::DictionaryAttackLockResetSync(
26856    const TPMI_RH_LOCKOUT& lock_handle,
26857    const std::string& lock_handle_name,
26858    AuthorizationDelegate* authorization_delegate) {
26859  VLOG(1) << __func__;
26860  std::string command;
26861  TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
26862      lock_handle, lock_handle_name, &command, authorization_delegate);
26863  if (rc != TPM_RC_SUCCESS) {
26864    return rc;
26865  }
26866  std::string response = transceiver_->SendCommandAndWait(command);
26867  rc =
26868      ParseResponse_DictionaryAttackLockReset(response, authorization_delegate);
26869  return rc;
26870}
26871
26872TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters(
26873    const TPMI_RH_LOCKOUT& lock_handle,
26874    const std::string& lock_handle_name,
26875    const UINT32& new_max_tries,
26876    const UINT32& new_recovery_time,
26877    const UINT32& lockout_recovery,
26878    std::string* serialized_command,
26879    AuthorizationDelegate* authorization_delegate) {
26880  VLOG(3) << __func__;
26881  TPM_RC rc = TPM_RC_SUCCESS;
26882  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26883  UINT32 command_size = 10;  // Header size.
26884  std::string handle_section_bytes;
26885  std::string parameter_section_bytes;
26886  TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
26887  bool is_command_parameter_encryption_possible = false;
26888  bool is_response_parameter_encryption_possible = false;
26889  std::string command_code_bytes;
26890  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26891  if (rc != TPM_RC_SUCCESS) {
26892    return rc;
26893  }
26894  std::string lock_handle_bytes;
26895  rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
26896  if (rc != TPM_RC_SUCCESS) {
26897    return rc;
26898  }
26899  std::string new_max_tries_bytes;
26900  rc = Serialize_UINT32(new_max_tries, &new_max_tries_bytes);
26901  if (rc != TPM_RC_SUCCESS) {
26902    return rc;
26903  }
26904  std::string new_recovery_time_bytes;
26905  rc = Serialize_UINT32(new_recovery_time, &new_recovery_time_bytes);
26906  if (rc != TPM_RC_SUCCESS) {
26907    return rc;
26908  }
26909  std::string lockout_recovery_bytes;
26910  rc = Serialize_UINT32(lockout_recovery, &lockout_recovery_bytes);
26911  if (rc != TPM_RC_SUCCESS) {
26912    return rc;
26913  }
26914  std::unique_ptr<crypto::SecureHash> hash(
26915      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26916  hash->Update(command_code_bytes.data(), command_code_bytes.size());
26917  hash->Update(lock_handle_name.data(), lock_handle_name.size());
26918  handle_section_bytes += lock_handle_bytes;
26919  command_size += lock_handle_bytes.size();
26920  hash->Update(new_max_tries_bytes.data(), new_max_tries_bytes.size());
26921  parameter_section_bytes += new_max_tries_bytes;
26922  command_size += new_max_tries_bytes.size();
26923  hash->Update(new_recovery_time_bytes.data(), new_recovery_time_bytes.size());
26924  parameter_section_bytes += new_recovery_time_bytes;
26925  command_size += new_recovery_time_bytes.size();
26926  hash->Update(lockout_recovery_bytes.data(), lockout_recovery_bytes.size());
26927  parameter_section_bytes += lockout_recovery_bytes;
26928  command_size += lockout_recovery_bytes.size();
26929  std::string command_hash(32, 0);
26930  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
26931  std::string authorization_section_bytes;
26932  std::string authorization_size_bytes;
26933  if (authorization_delegate) {
26934    if (!authorization_delegate->GetCommandAuthorization(
26935            command_hash, is_command_parameter_encryption_possible,
26936            is_response_parameter_encryption_possible,
26937            &authorization_section_bytes)) {
26938      return TRUNKS_RC_AUTHORIZATION_FAILED;
26939    }
26940    if (!authorization_section_bytes.empty()) {
26941      tag = TPM_ST_SESSIONS;
26942      std::string tmp;
26943      rc = Serialize_UINT32(authorization_section_bytes.size(),
26944                            &authorization_size_bytes);
26945      if (rc != TPM_RC_SUCCESS) {
26946        return rc;
26947      }
26948      command_size +=
26949          authorization_size_bytes.size() + authorization_section_bytes.size();
26950    }
26951  }
26952  std::string tag_bytes;
26953  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26954  if (rc != TPM_RC_SUCCESS) {
26955    return rc;
26956  }
26957  std::string command_size_bytes;
26958  rc = Serialize_UINT32(command_size, &command_size_bytes);
26959  if (rc != TPM_RC_SUCCESS) {
26960    return rc;
26961  }
26962  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26963                        handle_section_bytes + authorization_size_bytes +
26964                        authorization_section_bytes + parameter_section_bytes;
26965  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26966  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
26967                                            serialized_command->size());
26968  return TPM_RC_SUCCESS;
26969}
26970
26971TPM_RC Tpm::ParseResponse_DictionaryAttackParameters(
26972    const std::string& response,
26973    AuthorizationDelegate* authorization_delegate) {
26974  VLOG(3) << __func__;
26975  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26976  TPM_RC rc = TPM_RC_SUCCESS;
26977  std::string buffer(response);
26978  TPM_ST tag;
26979  std::string tag_bytes;
26980  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26981  if (rc != TPM_RC_SUCCESS) {
26982    return rc;
26983  }
26984  UINT32 response_size;
26985  std::string response_size_bytes;
26986  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26987  if (rc != TPM_RC_SUCCESS) {
26988    return rc;
26989  }
26990  TPM_RC response_code;
26991  std::string response_code_bytes;
26992  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26993  if (rc != TPM_RC_SUCCESS) {
26994    return rc;
26995  }
26996  if (response_size != response.size()) {
26997    return TPM_RC_SIZE;
26998  }
26999  if (response_code != TPM_RC_SUCCESS) {
27000    return response_code;
27001  }
27002  TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27003  std::string command_code_bytes;
27004  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27005  if (rc != TPM_RC_SUCCESS) {
27006    return rc;
27007  }
27008  std::string authorization_section_bytes;
27009  if (tag == TPM_ST_SESSIONS) {
27010    UINT32 parameter_section_size = buffer.size();
27011    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27012    if (rc != TPM_RC_SUCCESS) {
27013      return rc;
27014    }
27015    if (parameter_section_size > buffer.size()) {
27016      return TPM_RC_INSUFFICIENT;
27017    }
27018    authorization_section_bytes = buffer.substr(parameter_section_size);
27019    // Keep the parameter section in |buffer|.
27020    buffer.erase(parameter_section_size);
27021  }
27022  std::unique_ptr<crypto::SecureHash> hash(
27023      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27024  hash->Update(response_code_bytes.data(), response_code_bytes.size());
27025  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27026  hash->Update(buffer.data(), buffer.size());
27027  std::string response_hash(32, 0);
27028  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
27029  if (tag == TPM_ST_SESSIONS) {
27030    CHECK(authorization_delegate) << "Authorization delegate missing!";
27031    if (!authorization_delegate->CheckResponseAuthorization(
27032            response_hash, authorization_section_bytes)) {
27033      return TRUNKS_RC_AUTHORIZATION_FAILED;
27034    }
27035  }
27036  return TPM_RC_SUCCESS;
27037}
27038
27039void DictionaryAttackParametersErrorCallback(
27040    const Tpm::DictionaryAttackParametersResponse& callback,
27041    TPM_RC response_code) {
27042  VLOG(1) << __func__;
27043  callback.Run(response_code);
27044}
27045
27046void DictionaryAttackParametersResponseParser(
27047    const Tpm::DictionaryAttackParametersResponse& callback,
27048    AuthorizationDelegate* authorization_delegate,
27049    const std::string& response) {
27050  VLOG(1) << __func__;
27051  base::Callback<void(TPM_RC)> error_reporter =
27052      base::Bind(DictionaryAttackParametersErrorCallback, callback);
27053  TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters(
27054      response, authorization_delegate);
27055  if (rc != TPM_RC_SUCCESS) {
27056    error_reporter.Run(rc);
27057    return;
27058  }
27059  callback.Run(rc);
27060}
27061
27062void Tpm::DictionaryAttackParameters(
27063    const TPMI_RH_LOCKOUT& lock_handle,
27064    const std::string& lock_handle_name,
27065    const UINT32& new_max_tries,
27066    const UINT32& new_recovery_time,
27067    const UINT32& lockout_recovery,
27068    AuthorizationDelegate* authorization_delegate,
27069    const DictionaryAttackParametersResponse& callback) {
27070  VLOG(1) << __func__;
27071  base::Callback<void(TPM_RC)> error_reporter =
27072      base::Bind(DictionaryAttackParametersErrorCallback, callback);
27073  base::Callback<void(const std::string&)> parser =
27074      base::Bind(DictionaryAttackParametersResponseParser, callback,
27075                 authorization_delegate);
27076  std::string command;
27077  TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27078      lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27079      lockout_recovery, &command, authorization_delegate);
27080  if (rc != TPM_RC_SUCCESS) {
27081    error_reporter.Run(rc);
27082    return;
27083  }
27084  transceiver_->SendCommand(command, parser);
27085}
27086
27087TPM_RC Tpm::DictionaryAttackParametersSync(
27088    const TPMI_RH_LOCKOUT& lock_handle,
27089    const std::string& lock_handle_name,
27090    const UINT32& new_max_tries,
27091    const UINT32& new_recovery_time,
27092    const UINT32& lockout_recovery,
27093    AuthorizationDelegate* authorization_delegate) {
27094  VLOG(1) << __func__;
27095  std::string command;
27096  TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27097      lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27098      lockout_recovery, &command, authorization_delegate);
27099  if (rc != TPM_RC_SUCCESS) {
27100    return rc;
27101  }
27102  std::string response = transceiver_->SendCommandAndWait(command);
27103  rc = ParseResponse_DictionaryAttackParameters(response,
27104                                                authorization_delegate);
27105  return rc;
27106}
27107
27108TPM_RC Tpm::SerializeCommand_PP_Commands(
27109    const TPMI_RH_PLATFORM& auth,
27110    const std::string& auth_name,
27111    const TPML_CC& set_list,
27112    const TPML_CC& clear_list,
27113    std::string* serialized_command,
27114    AuthorizationDelegate* authorization_delegate) {
27115  VLOG(3) << __func__;
27116  TPM_RC rc = TPM_RC_SUCCESS;
27117  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27118  UINT32 command_size = 10;  // Header size.
27119  std::string handle_section_bytes;
27120  std::string parameter_section_bytes;
27121  TPM_CC command_code = TPM_CC_PP_Commands;
27122  bool is_command_parameter_encryption_possible = false;
27123  bool is_response_parameter_encryption_possible = false;
27124  std::string command_code_bytes;
27125  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27126  if (rc != TPM_RC_SUCCESS) {
27127    return rc;
27128  }
27129  std::string auth_bytes;
27130  rc = Serialize_TPMI_RH_PLATFORM(auth, &auth_bytes);
27131  if (rc != TPM_RC_SUCCESS) {
27132    return rc;
27133  }
27134  std::string set_list_bytes;
27135  rc = Serialize_TPML_CC(set_list, &set_list_bytes);
27136  if (rc != TPM_RC_SUCCESS) {
27137    return rc;
27138  }
27139  std::string clear_list_bytes;
27140  rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
27141  if (rc != TPM_RC_SUCCESS) {
27142    return rc;
27143  }
27144  std::unique_ptr<crypto::SecureHash> hash(
27145      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27146  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27147  hash->Update(auth_name.data(), auth_name.size());
27148  handle_section_bytes += auth_bytes;
27149  command_size += auth_bytes.size();
27150  hash->Update(set_list_bytes.data(), set_list_bytes.size());
27151  parameter_section_bytes += set_list_bytes;
27152  command_size += set_list_bytes.size();
27153  hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
27154  parameter_section_bytes += clear_list_bytes;
27155  command_size += clear_list_bytes.size();
27156  std::string command_hash(32, 0);
27157  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
27158  std::string authorization_section_bytes;
27159  std::string authorization_size_bytes;
27160  if (authorization_delegate) {
27161    if (!authorization_delegate->GetCommandAuthorization(
27162            command_hash, is_command_parameter_encryption_possible,
27163            is_response_parameter_encryption_possible,
27164            &authorization_section_bytes)) {
27165      return TRUNKS_RC_AUTHORIZATION_FAILED;
27166    }
27167    if (!authorization_section_bytes.empty()) {
27168      tag = TPM_ST_SESSIONS;
27169      std::string tmp;
27170      rc = Serialize_UINT32(authorization_section_bytes.size(),
27171                            &authorization_size_bytes);
27172      if (rc != TPM_RC_SUCCESS) {
27173        return rc;
27174      }
27175      command_size +=
27176          authorization_size_bytes.size() + authorization_section_bytes.size();
27177    }
27178  }
27179  std::string tag_bytes;
27180  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27181  if (rc != TPM_RC_SUCCESS) {
27182    return rc;
27183  }
27184  std::string command_size_bytes;
27185  rc = Serialize_UINT32(command_size, &command_size_bytes);
27186  if (rc != TPM_RC_SUCCESS) {
27187    return rc;
27188  }
27189  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27190                        handle_section_bytes + authorization_size_bytes +
27191                        authorization_section_bytes + parameter_section_bytes;
27192  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27193  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
27194                                            serialized_command->size());
27195  return TPM_RC_SUCCESS;
27196}
27197
27198TPM_RC Tpm::ParseResponse_PP_Commands(
27199    const std::string& response,
27200    AuthorizationDelegate* authorization_delegate) {
27201  VLOG(3) << __func__;
27202  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27203  TPM_RC rc = TPM_RC_SUCCESS;
27204  std::string buffer(response);
27205  TPM_ST tag;
27206  std::string tag_bytes;
27207  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27208  if (rc != TPM_RC_SUCCESS) {
27209    return rc;
27210  }
27211  UINT32 response_size;
27212  std::string response_size_bytes;
27213  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27214  if (rc != TPM_RC_SUCCESS) {
27215    return rc;
27216  }
27217  TPM_RC response_code;
27218  std::string response_code_bytes;
27219  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27220  if (rc != TPM_RC_SUCCESS) {
27221    return rc;
27222  }
27223  if (response_size != response.size()) {
27224    return TPM_RC_SIZE;
27225  }
27226  if (response_code != TPM_RC_SUCCESS) {
27227    return response_code;
27228  }
27229  TPM_CC command_code = TPM_CC_PP_Commands;
27230  std::string command_code_bytes;
27231  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27232  if (rc != TPM_RC_SUCCESS) {
27233    return rc;
27234  }
27235  std::string authorization_section_bytes;
27236  if (tag == TPM_ST_SESSIONS) {
27237    UINT32 parameter_section_size = buffer.size();
27238    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27239    if (rc != TPM_RC_SUCCESS) {
27240      return rc;
27241    }
27242    if (parameter_section_size > buffer.size()) {
27243      return TPM_RC_INSUFFICIENT;
27244    }
27245    authorization_section_bytes = buffer.substr(parameter_section_size);
27246    // Keep the parameter section in |buffer|.
27247    buffer.erase(parameter_section_size);
27248  }
27249  std::unique_ptr<crypto::SecureHash> hash(
27250      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27251  hash->Update(response_code_bytes.data(), response_code_bytes.size());
27252  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27253  hash->Update(buffer.data(), buffer.size());
27254  std::string response_hash(32, 0);
27255  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
27256  if (tag == TPM_ST_SESSIONS) {
27257    CHECK(authorization_delegate) << "Authorization delegate missing!";
27258    if (!authorization_delegate->CheckResponseAuthorization(
27259            response_hash, authorization_section_bytes)) {
27260      return TRUNKS_RC_AUTHORIZATION_FAILED;
27261    }
27262  }
27263  return TPM_RC_SUCCESS;
27264}
27265
27266void PP_CommandsErrorCallback(const Tpm::PP_CommandsResponse& callback,
27267                              TPM_RC response_code) {
27268  VLOG(1) << __func__;
27269  callback.Run(response_code);
27270}
27271
27272void PP_CommandsResponseParser(const Tpm::PP_CommandsResponse& callback,
27273                               AuthorizationDelegate* authorization_delegate,
27274                               const std::string& response) {
27275  VLOG(1) << __func__;
27276  base::Callback<void(TPM_RC)> error_reporter =
27277      base::Bind(PP_CommandsErrorCallback, callback);
27278  TPM_RC rc = Tpm::ParseResponse_PP_Commands(response, authorization_delegate);
27279  if (rc != TPM_RC_SUCCESS) {
27280    error_reporter.Run(rc);
27281    return;
27282  }
27283  callback.Run(rc);
27284}
27285
27286void Tpm::PP_Commands(const TPMI_RH_PLATFORM& auth,
27287                      const std::string& auth_name,
27288                      const TPML_CC& set_list,
27289                      const TPML_CC& clear_list,
27290                      AuthorizationDelegate* authorization_delegate,
27291                      const PP_CommandsResponse& callback) {
27292  VLOG(1) << __func__;
27293  base::Callback<void(TPM_RC)> error_reporter =
27294      base::Bind(PP_CommandsErrorCallback, callback);
27295  base::Callback<void(const std::string&)> parser =
27296      base::Bind(PP_CommandsResponseParser, callback, authorization_delegate);
27297  std::string command;
27298  TPM_RC rc = SerializeCommand_PP_Commands(
27299      auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27300  if (rc != TPM_RC_SUCCESS) {
27301    error_reporter.Run(rc);
27302    return;
27303  }
27304  transceiver_->SendCommand(command, parser);
27305}
27306
27307TPM_RC Tpm::PP_CommandsSync(const TPMI_RH_PLATFORM& auth,
27308                            const std::string& auth_name,
27309                            const TPML_CC& set_list,
27310                            const TPML_CC& clear_list,
27311                            AuthorizationDelegate* authorization_delegate) {
27312  VLOG(1) << __func__;
27313  std::string command;
27314  TPM_RC rc = SerializeCommand_PP_Commands(
27315      auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27316  if (rc != TPM_RC_SUCCESS) {
27317    return rc;
27318  }
27319  std::string response = transceiver_->SendCommandAndWait(command);
27320  rc = ParseResponse_PP_Commands(response, authorization_delegate);
27321  return rc;
27322}
27323
27324TPM_RC Tpm::SerializeCommand_SetAlgorithmSet(
27325    const TPMI_RH_PLATFORM& auth_handle,
27326    const std::string& auth_handle_name,
27327    const UINT32& algorithm_set,
27328    std::string* serialized_command,
27329    AuthorizationDelegate* authorization_delegate) {
27330  VLOG(3) << __func__;
27331  TPM_RC rc = TPM_RC_SUCCESS;
27332  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27333  UINT32 command_size = 10;  // Header size.
27334  std::string handle_section_bytes;
27335  std::string parameter_section_bytes;
27336  TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27337  bool is_command_parameter_encryption_possible = false;
27338  bool is_response_parameter_encryption_possible = false;
27339  std::string command_code_bytes;
27340  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27341  if (rc != TPM_RC_SUCCESS) {
27342    return rc;
27343  }
27344  std::string auth_handle_bytes;
27345  rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
27346  if (rc != TPM_RC_SUCCESS) {
27347    return rc;
27348  }
27349  std::string algorithm_set_bytes;
27350  rc = Serialize_UINT32(algorithm_set, &algorithm_set_bytes);
27351  if (rc != TPM_RC_SUCCESS) {
27352    return rc;
27353  }
27354  std::unique_ptr<crypto::SecureHash> hash(
27355      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27356  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27357  hash->Update(auth_handle_name.data(), auth_handle_name.size());
27358  handle_section_bytes += auth_handle_bytes;
27359  command_size += auth_handle_bytes.size();
27360  hash->Update(algorithm_set_bytes.data(), algorithm_set_bytes.size());
27361  parameter_section_bytes += algorithm_set_bytes;
27362  command_size += algorithm_set_bytes.size();
27363  std::string command_hash(32, 0);
27364  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
27365  std::string authorization_section_bytes;
27366  std::string authorization_size_bytes;
27367  if (authorization_delegate) {
27368    if (!authorization_delegate->GetCommandAuthorization(
27369            command_hash, is_command_parameter_encryption_possible,
27370            is_response_parameter_encryption_possible,
27371            &authorization_section_bytes)) {
27372      return TRUNKS_RC_AUTHORIZATION_FAILED;
27373    }
27374    if (!authorization_section_bytes.empty()) {
27375      tag = TPM_ST_SESSIONS;
27376      std::string tmp;
27377      rc = Serialize_UINT32(authorization_section_bytes.size(),
27378                            &authorization_size_bytes);
27379      if (rc != TPM_RC_SUCCESS) {
27380        return rc;
27381      }
27382      command_size +=
27383          authorization_size_bytes.size() + authorization_section_bytes.size();
27384    }
27385  }
27386  std::string tag_bytes;
27387  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27388  if (rc != TPM_RC_SUCCESS) {
27389    return rc;
27390  }
27391  std::string command_size_bytes;
27392  rc = Serialize_UINT32(command_size, &command_size_bytes);
27393  if (rc != TPM_RC_SUCCESS) {
27394    return rc;
27395  }
27396  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27397                        handle_section_bytes + authorization_size_bytes +
27398                        authorization_section_bytes + parameter_section_bytes;
27399  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27400  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
27401                                            serialized_command->size());
27402  return TPM_RC_SUCCESS;
27403}
27404
27405TPM_RC Tpm::ParseResponse_SetAlgorithmSet(
27406    const std::string& response,
27407    AuthorizationDelegate* authorization_delegate) {
27408  VLOG(3) << __func__;
27409  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27410  TPM_RC rc = TPM_RC_SUCCESS;
27411  std::string buffer(response);
27412  TPM_ST tag;
27413  std::string tag_bytes;
27414  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27415  if (rc != TPM_RC_SUCCESS) {
27416    return rc;
27417  }
27418  UINT32 response_size;
27419  std::string response_size_bytes;
27420  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27421  if (rc != TPM_RC_SUCCESS) {
27422    return rc;
27423  }
27424  TPM_RC response_code;
27425  std::string response_code_bytes;
27426  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27427  if (rc != TPM_RC_SUCCESS) {
27428    return rc;
27429  }
27430  if (response_size != response.size()) {
27431    return TPM_RC_SIZE;
27432  }
27433  if (response_code != TPM_RC_SUCCESS) {
27434    return response_code;
27435  }
27436  TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27437  std::string command_code_bytes;
27438  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27439  if (rc != TPM_RC_SUCCESS) {
27440    return rc;
27441  }
27442  std::string authorization_section_bytes;
27443  if (tag == TPM_ST_SESSIONS) {
27444    UINT32 parameter_section_size = buffer.size();
27445    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27446    if (rc != TPM_RC_SUCCESS) {
27447      return rc;
27448    }
27449    if (parameter_section_size > buffer.size()) {
27450      return TPM_RC_INSUFFICIENT;
27451    }
27452    authorization_section_bytes = buffer.substr(parameter_section_size);
27453    // Keep the parameter section in |buffer|.
27454    buffer.erase(parameter_section_size);
27455  }
27456  std::unique_ptr<crypto::SecureHash> hash(
27457      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27458  hash->Update(response_code_bytes.data(), response_code_bytes.size());
27459  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27460  hash->Update(buffer.data(), buffer.size());
27461  std::string response_hash(32, 0);
27462  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
27463  if (tag == TPM_ST_SESSIONS) {
27464    CHECK(authorization_delegate) << "Authorization delegate missing!";
27465    if (!authorization_delegate->CheckResponseAuthorization(
27466            response_hash, authorization_section_bytes)) {
27467      return TRUNKS_RC_AUTHORIZATION_FAILED;
27468    }
27469  }
27470  return TPM_RC_SUCCESS;
27471}
27472
27473void SetAlgorithmSetErrorCallback(const Tpm::SetAlgorithmSetResponse& callback,
27474                                  TPM_RC response_code) {
27475  VLOG(1) << __func__;
27476  callback.Run(response_code);
27477}
27478
27479void SetAlgorithmSetResponseParser(
27480    const Tpm::SetAlgorithmSetResponse& callback,
27481    AuthorizationDelegate* authorization_delegate,
27482    const std::string& response) {
27483  VLOG(1) << __func__;
27484  base::Callback<void(TPM_RC)> error_reporter =
27485      base::Bind(SetAlgorithmSetErrorCallback, callback);
27486  TPM_RC rc =
27487      Tpm::ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27488  if (rc != TPM_RC_SUCCESS) {
27489    error_reporter.Run(rc);
27490    return;
27491  }
27492  callback.Run(rc);
27493}
27494
27495void Tpm::SetAlgorithmSet(const TPMI_RH_PLATFORM& auth_handle,
27496                          const std::string& auth_handle_name,
27497                          const UINT32& algorithm_set,
27498                          AuthorizationDelegate* authorization_delegate,
27499                          const SetAlgorithmSetResponse& callback) {
27500  VLOG(1) << __func__;
27501  base::Callback<void(TPM_RC)> error_reporter =
27502      base::Bind(SetAlgorithmSetErrorCallback, callback);
27503  base::Callback<void(const std::string&)> parser = base::Bind(
27504      SetAlgorithmSetResponseParser, callback, authorization_delegate);
27505  std::string command;
27506  TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27507                                               algorithm_set, &command,
27508                                               authorization_delegate);
27509  if (rc != TPM_RC_SUCCESS) {
27510    error_reporter.Run(rc);
27511    return;
27512  }
27513  transceiver_->SendCommand(command, parser);
27514}
27515
27516TPM_RC Tpm::SetAlgorithmSetSync(const TPMI_RH_PLATFORM& auth_handle,
27517                                const std::string& auth_handle_name,
27518                                const UINT32& algorithm_set,
27519                                AuthorizationDelegate* authorization_delegate) {
27520  VLOG(1) << __func__;
27521  std::string command;
27522  TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27523                                               algorithm_set, &command,
27524                                               authorization_delegate);
27525  if (rc != TPM_RC_SUCCESS) {
27526    return rc;
27527  }
27528  std::string response = transceiver_->SendCommandAndWait(command);
27529  rc = ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27530  return rc;
27531}
27532
27533TPM_RC Tpm::SerializeCommand_FieldUpgradeStart(
27534    const TPMI_RH_PLATFORM& authorization,
27535    const std::string& authorization_name,
27536    const TPMI_DH_OBJECT& key_handle,
27537    const std::string& key_handle_name,
27538    const TPM2B_DIGEST& fu_digest,
27539    const TPMT_SIGNATURE& manifest_signature,
27540    std::string* serialized_command,
27541    AuthorizationDelegate* authorization_delegate) {
27542  VLOG(3) << __func__;
27543  TPM_RC rc = TPM_RC_SUCCESS;
27544  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27545  UINT32 command_size = 10;  // Header size.
27546  std::string handle_section_bytes;
27547  std::string parameter_section_bytes;
27548  TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27549  bool is_command_parameter_encryption_possible = true;
27550  bool is_response_parameter_encryption_possible = false;
27551  std::string command_code_bytes;
27552  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27553  if (rc != TPM_RC_SUCCESS) {
27554    return rc;
27555  }
27556  std::string authorization_bytes;
27557  rc = Serialize_TPMI_RH_PLATFORM(authorization, &authorization_bytes);
27558  if (rc != TPM_RC_SUCCESS) {
27559    return rc;
27560  }
27561  std::string key_handle_bytes;
27562  rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
27563  if (rc != TPM_RC_SUCCESS) {
27564    return rc;
27565  }
27566  std::string fu_digest_bytes;
27567  rc = Serialize_TPM2B_DIGEST(fu_digest, &fu_digest_bytes);
27568  if (rc != TPM_RC_SUCCESS) {
27569    return rc;
27570  }
27571  std::string manifest_signature_bytes;
27572  rc = Serialize_TPMT_SIGNATURE(manifest_signature, &manifest_signature_bytes);
27573  if (rc != TPM_RC_SUCCESS) {
27574    return rc;
27575  }
27576  if (authorization_delegate) {
27577    // Encrypt just the parameter data, not the size.
27578    std::string tmp = fu_digest_bytes.substr(2);
27579    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
27580      return TRUNKS_RC_ENCRYPTION_FAILED;
27581    }
27582    fu_digest_bytes.replace(2, std::string::npos, tmp);
27583  }
27584  std::unique_ptr<crypto::SecureHash> hash(
27585      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27586  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27587  hash->Update(authorization_name.data(), authorization_name.size());
27588  handle_section_bytes += authorization_bytes;
27589  command_size += authorization_bytes.size();
27590  hash->Update(key_handle_name.data(), key_handle_name.size());
27591  handle_section_bytes += key_handle_bytes;
27592  command_size += key_handle_bytes.size();
27593  hash->Update(fu_digest_bytes.data(), fu_digest_bytes.size());
27594  parameter_section_bytes += fu_digest_bytes;
27595  command_size += fu_digest_bytes.size();
27596  hash->Update(manifest_signature_bytes.data(),
27597               manifest_signature_bytes.size());
27598  parameter_section_bytes += manifest_signature_bytes;
27599  command_size += manifest_signature_bytes.size();
27600  std::string command_hash(32, 0);
27601  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
27602  std::string authorization_section_bytes;
27603  std::string authorization_size_bytes;
27604  if (authorization_delegate) {
27605    if (!authorization_delegate->GetCommandAuthorization(
27606            command_hash, is_command_parameter_encryption_possible,
27607            is_response_parameter_encryption_possible,
27608            &authorization_section_bytes)) {
27609      return TRUNKS_RC_AUTHORIZATION_FAILED;
27610    }
27611    if (!authorization_section_bytes.empty()) {
27612      tag = TPM_ST_SESSIONS;
27613      std::string tmp;
27614      rc = Serialize_UINT32(authorization_section_bytes.size(),
27615                            &authorization_size_bytes);
27616      if (rc != TPM_RC_SUCCESS) {
27617        return rc;
27618      }
27619      command_size +=
27620          authorization_size_bytes.size() + authorization_section_bytes.size();
27621    }
27622  }
27623  std::string tag_bytes;
27624  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27625  if (rc != TPM_RC_SUCCESS) {
27626    return rc;
27627  }
27628  std::string command_size_bytes;
27629  rc = Serialize_UINT32(command_size, &command_size_bytes);
27630  if (rc != TPM_RC_SUCCESS) {
27631    return rc;
27632  }
27633  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27634                        handle_section_bytes + authorization_size_bytes +
27635                        authorization_section_bytes + parameter_section_bytes;
27636  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27637  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
27638                                            serialized_command->size());
27639  return TPM_RC_SUCCESS;
27640}
27641
27642TPM_RC Tpm::ParseResponse_FieldUpgradeStart(
27643    const std::string& response,
27644    AuthorizationDelegate* authorization_delegate) {
27645  VLOG(3) << __func__;
27646  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27647  TPM_RC rc = TPM_RC_SUCCESS;
27648  std::string buffer(response);
27649  TPM_ST tag;
27650  std::string tag_bytes;
27651  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27652  if (rc != TPM_RC_SUCCESS) {
27653    return rc;
27654  }
27655  UINT32 response_size;
27656  std::string response_size_bytes;
27657  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27658  if (rc != TPM_RC_SUCCESS) {
27659    return rc;
27660  }
27661  TPM_RC response_code;
27662  std::string response_code_bytes;
27663  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27664  if (rc != TPM_RC_SUCCESS) {
27665    return rc;
27666  }
27667  if (response_size != response.size()) {
27668    return TPM_RC_SIZE;
27669  }
27670  if (response_code != TPM_RC_SUCCESS) {
27671    return response_code;
27672  }
27673  TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27674  std::string command_code_bytes;
27675  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27676  if (rc != TPM_RC_SUCCESS) {
27677    return rc;
27678  }
27679  std::string authorization_section_bytes;
27680  if (tag == TPM_ST_SESSIONS) {
27681    UINT32 parameter_section_size = buffer.size();
27682    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27683    if (rc != TPM_RC_SUCCESS) {
27684      return rc;
27685    }
27686    if (parameter_section_size > buffer.size()) {
27687      return TPM_RC_INSUFFICIENT;
27688    }
27689    authorization_section_bytes = buffer.substr(parameter_section_size);
27690    // Keep the parameter section in |buffer|.
27691    buffer.erase(parameter_section_size);
27692  }
27693  std::unique_ptr<crypto::SecureHash> hash(
27694      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27695  hash->Update(response_code_bytes.data(), response_code_bytes.size());
27696  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27697  hash->Update(buffer.data(), buffer.size());
27698  std::string response_hash(32, 0);
27699  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
27700  if (tag == TPM_ST_SESSIONS) {
27701    CHECK(authorization_delegate) << "Authorization delegate missing!";
27702    if (!authorization_delegate->CheckResponseAuthorization(
27703            response_hash, authorization_section_bytes)) {
27704      return TRUNKS_RC_AUTHORIZATION_FAILED;
27705    }
27706  }
27707  return TPM_RC_SUCCESS;
27708}
27709
27710void FieldUpgradeStartErrorCallback(
27711    const Tpm::FieldUpgradeStartResponse& callback,
27712    TPM_RC response_code) {
27713  VLOG(1) << __func__;
27714  callback.Run(response_code);
27715}
27716
27717void FieldUpgradeStartResponseParser(
27718    const Tpm::FieldUpgradeStartResponse& callback,
27719    AuthorizationDelegate* authorization_delegate,
27720    const std::string& response) {
27721  VLOG(1) << __func__;
27722  base::Callback<void(TPM_RC)> error_reporter =
27723      base::Bind(FieldUpgradeStartErrorCallback, callback);
27724  TPM_RC rc =
27725      Tpm::ParseResponse_FieldUpgradeStart(response, authorization_delegate);
27726  if (rc != TPM_RC_SUCCESS) {
27727    error_reporter.Run(rc);
27728    return;
27729  }
27730  callback.Run(rc);
27731}
27732
27733void Tpm::FieldUpgradeStart(const TPMI_RH_PLATFORM& authorization,
27734                            const std::string& authorization_name,
27735                            const TPMI_DH_OBJECT& key_handle,
27736                            const std::string& key_handle_name,
27737                            const TPM2B_DIGEST& fu_digest,
27738                            const TPMT_SIGNATURE& manifest_signature,
27739                            AuthorizationDelegate* authorization_delegate,
27740                            const FieldUpgradeStartResponse& callback) {
27741  VLOG(1) << __func__;
27742  base::Callback<void(TPM_RC)> error_reporter =
27743      base::Bind(FieldUpgradeStartErrorCallback, callback);
27744  base::Callback<void(const std::string&)> parser = base::Bind(
27745      FieldUpgradeStartResponseParser, callback, authorization_delegate);
27746  std::string command;
27747  TPM_RC rc = SerializeCommand_FieldUpgradeStart(
27748      authorization, authorization_name, key_handle, key_handle_name, fu_digest,
27749      manifest_signature, &command, authorization_delegate);
27750  if (rc != TPM_RC_SUCCESS) {
27751    error_reporter.Run(rc);
27752    return;
27753  }
27754  transceiver_->SendCommand(command, parser);
27755}
27756
27757TPM_RC Tpm::FieldUpgradeStartSync(
27758    const TPMI_RH_PLATFORM& authorization,
27759    const std::string& authorization_name,
27760    const TPMI_DH_OBJECT& key_handle,
27761    const std::string& key_handle_name,
27762    const TPM2B_DIGEST& fu_digest,
27763    const TPMT_SIGNATURE& manifest_signature,
27764    AuthorizationDelegate* authorization_delegate) {
27765  VLOG(1) << __func__;
27766  std::string command;
27767  TPM_RC rc = SerializeCommand_FieldUpgradeStart(
27768      authorization, authorization_name, key_handle, key_handle_name, fu_digest,
27769      manifest_signature, &command, authorization_delegate);
27770  if (rc != TPM_RC_SUCCESS) {
27771    return rc;
27772  }
27773  std::string response = transceiver_->SendCommandAndWait(command);
27774  rc = ParseResponse_FieldUpgradeStart(response, authorization_delegate);
27775  return rc;
27776}
27777
27778TPM_RC Tpm::SerializeCommand_FieldUpgradeData(
27779    const TPM2B_MAX_BUFFER& fu_data,
27780    std::string* serialized_command,
27781    AuthorizationDelegate* authorization_delegate) {
27782  VLOG(3) << __func__;
27783  TPM_RC rc = TPM_RC_SUCCESS;
27784  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27785  UINT32 command_size = 10;  // Header size.
27786  std::string handle_section_bytes;
27787  std::string parameter_section_bytes;
27788  TPM_CC command_code = TPM_CC_FieldUpgradeData;
27789  bool is_command_parameter_encryption_possible = true;
27790  bool is_response_parameter_encryption_possible = false;
27791  std::string command_code_bytes;
27792  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27793  if (rc != TPM_RC_SUCCESS) {
27794    return rc;
27795  }
27796  std::string fu_data_bytes;
27797  rc = Serialize_TPM2B_MAX_BUFFER(fu_data, &fu_data_bytes);
27798  if (rc != TPM_RC_SUCCESS) {
27799    return rc;
27800  }
27801  if (authorization_delegate) {
27802    // Encrypt just the parameter data, not the size.
27803    std::string tmp = fu_data_bytes.substr(2);
27804    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
27805      return TRUNKS_RC_ENCRYPTION_FAILED;
27806    }
27807    fu_data_bytes.replace(2, std::string::npos, tmp);
27808  }
27809  std::unique_ptr<crypto::SecureHash> hash(
27810      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27811  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27812  hash->Update(fu_data_bytes.data(), fu_data_bytes.size());
27813  parameter_section_bytes += fu_data_bytes;
27814  command_size += fu_data_bytes.size();
27815  std::string command_hash(32, 0);
27816  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
27817  std::string authorization_section_bytes;
27818  std::string authorization_size_bytes;
27819  if (authorization_delegate) {
27820    if (!authorization_delegate->GetCommandAuthorization(
27821            command_hash, is_command_parameter_encryption_possible,
27822            is_response_parameter_encryption_possible,
27823            &authorization_section_bytes)) {
27824      return TRUNKS_RC_AUTHORIZATION_FAILED;
27825    }
27826    if (!authorization_section_bytes.empty()) {
27827      tag = TPM_ST_SESSIONS;
27828      std::string tmp;
27829      rc = Serialize_UINT32(authorization_section_bytes.size(),
27830                            &authorization_size_bytes);
27831      if (rc != TPM_RC_SUCCESS) {
27832        return rc;
27833      }
27834      command_size +=
27835          authorization_size_bytes.size() + authorization_section_bytes.size();
27836    }
27837  }
27838  std::string tag_bytes;
27839  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27840  if (rc != TPM_RC_SUCCESS) {
27841    return rc;
27842  }
27843  std::string command_size_bytes;
27844  rc = Serialize_UINT32(command_size, &command_size_bytes);
27845  if (rc != TPM_RC_SUCCESS) {
27846    return rc;
27847  }
27848  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27849                        handle_section_bytes + authorization_size_bytes +
27850                        authorization_section_bytes + parameter_section_bytes;
27851  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27852  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
27853                                            serialized_command->size());
27854  return TPM_RC_SUCCESS;
27855}
27856
27857TPM_RC Tpm::ParseResponse_FieldUpgradeData(
27858    const std::string& response,
27859    TPMT_HA* next_digest,
27860    TPMT_HA* first_digest,
27861    AuthorizationDelegate* authorization_delegate) {
27862  VLOG(3) << __func__;
27863  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27864  TPM_RC rc = TPM_RC_SUCCESS;
27865  std::string buffer(response);
27866  TPM_ST tag;
27867  std::string tag_bytes;
27868  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27869  if (rc != TPM_RC_SUCCESS) {
27870    return rc;
27871  }
27872  UINT32 response_size;
27873  std::string response_size_bytes;
27874  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27875  if (rc != TPM_RC_SUCCESS) {
27876    return rc;
27877  }
27878  TPM_RC response_code;
27879  std::string response_code_bytes;
27880  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27881  if (rc != TPM_RC_SUCCESS) {
27882    return rc;
27883  }
27884  if (response_size != response.size()) {
27885    return TPM_RC_SIZE;
27886  }
27887  if (response_code != TPM_RC_SUCCESS) {
27888    return response_code;
27889  }
27890  TPM_CC command_code = TPM_CC_FieldUpgradeData;
27891  std::string command_code_bytes;
27892  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27893  if (rc != TPM_RC_SUCCESS) {
27894    return rc;
27895  }
27896  std::string authorization_section_bytes;
27897  if (tag == TPM_ST_SESSIONS) {
27898    UINT32 parameter_section_size = buffer.size();
27899    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27900    if (rc != TPM_RC_SUCCESS) {
27901      return rc;
27902    }
27903    if (parameter_section_size > buffer.size()) {
27904      return TPM_RC_INSUFFICIENT;
27905    }
27906    authorization_section_bytes = buffer.substr(parameter_section_size);
27907    // Keep the parameter section in |buffer|.
27908    buffer.erase(parameter_section_size);
27909  }
27910  std::unique_ptr<crypto::SecureHash> hash(
27911      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27912  hash->Update(response_code_bytes.data(), response_code_bytes.size());
27913  hash->Update(command_code_bytes.data(), command_code_bytes.size());
27914  hash->Update(buffer.data(), buffer.size());
27915  std::string response_hash(32, 0);
27916  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
27917  if (tag == TPM_ST_SESSIONS) {
27918    CHECK(authorization_delegate) << "Authorization delegate missing!";
27919    if (!authorization_delegate->CheckResponseAuthorization(
27920            response_hash, authorization_section_bytes)) {
27921      return TRUNKS_RC_AUTHORIZATION_FAILED;
27922    }
27923  }
27924  std::string next_digest_bytes;
27925  rc = Parse_TPMT_HA(&buffer, next_digest, &next_digest_bytes);
27926  if (rc != TPM_RC_SUCCESS) {
27927    return rc;
27928  }
27929  std::string first_digest_bytes;
27930  rc = Parse_TPMT_HA(&buffer, first_digest, &first_digest_bytes);
27931  if (rc != TPM_RC_SUCCESS) {
27932    return rc;
27933  }
27934  return TPM_RC_SUCCESS;
27935}
27936
27937void FieldUpgradeDataErrorCallback(
27938    const Tpm::FieldUpgradeDataResponse& callback,
27939    TPM_RC response_code) {
27940  VLOG(1) << __func__;
27941  callback.Run(response_code, TPMT_HA(), TPMT_HA());
27942}
27943
27944void FieldUpgradeDataResponseParser(
27945    const Tpm::FieldUpgradeDataResponse& callback,
27946    AuthorizationDelegate* authorization_delegate,
27947    const std::string& response) {
27948  VLOG(1) << __func__;
27949  base::Callback<void(TPM_RC)> error_reporter =
27950      base::Bind(FieldUpgradeDataErrorCallback, callback);
27951  TPMT_HA next_digest;
27952  TPMT_HA first_digest;
27953  TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData(
27954      response, &next_digest, &first_digest, authorization_delegate);
27955  if (rc != TPM_RC_SUCCESS) {
27956    error_reporter.Run(rc);
27957    return;
27958  }
27959  callback.Run(rc, next_digest, first_digest);
27960}
27961
27962void Tpm::FieldUpgradeData(const TPM2B_MAX_BUFFER& fu_data,
27963                           AuthorizationDelegate* authorization_delegate,
27964                           const FieldUpgradeDataResponse& callback) {
27965  VLOG(1) << __func__;
27966  base::Callback<void(TPM_RC)> error_reporter =
27967      base::Bind(FieldUpgradeDataErrorCallback, callback);
27968  base::Callback<void(const std::string&)> parser = base::Bind(
27969      FieldUpgradeDataResponseParser, callback, authorization_delegate);
27970  std::string command;
27971  TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
27972                                                authorization_delegate);
27973  if (rc != TPM_RC_SUCCESS) {
27974    error_reporter.Run(rc);
27975    return;
27976  }
27977  transceiver_->SendCommand(command, parser);
27978}
27979
27980TPM_RC Tpm::FieldUpgradeDataSync(
27981    const TPM2B_MAX_BUFFER& fu_data,
27982    TPMT_HA* next_digest,
27983    TPMT_HA* first_digest,
27984    AuthorizationDelegate* authorization_delegate) {
27985  VLOG(1) << __func__;
27986  std::string command;
27987  TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
27988                                                authorization_delegate);
27989  if (rc != TPM_RC_SUCCESS) {
27990    return rc;
27991  }
27992  std::string response = transceiver_->SendCommandAndWait(command);
27993  rc = ParseResponse_FieldUpgradeData(response, next_digest, first_digest,
27994                                      authorization_delegate);
27995  return rc;
27996}
27997
27998TPM_RC Tpm::SerializeCommand_FirmwareRead(
27999    const UINT32& sequence_number,
28000    std::string* serialized_command,
28001    AuthorizationDelegate* authorization_delegate) {
28002  VLOG(3) << __func__;
28003  TPM_RC rc = TPM_RC_SUCCESS;
28004  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28005  UINT32 command_size = 10;  // Header size.
28006  std::string handle_section_bytes;
28007  std::string parameter_section_bytes;
28008  TPM_CC command_code = TPM_CC_FirmwareRead;
28009  bool is_command_parameter_encryption_possible = false;
28010  bool is_response_parameter_encryption_possible = true;
28011  std::string command_code_bytes;
28012  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28013  if (rc != TPM_RC_SUCCESS) {
28014    return rc;
28015  }
28016  std::string sequence_number_bytes;
28017  rc = Serialize_UINT32(sequence_number, &sequence_number_bytes);
28018  if (rc != TPM_RC_SUCCESS) {
28019    return rc;
28020  }
28021  std::unique_ptr<crypto::SecureHash> hash(
28022      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28023  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28024  hash->Update(sequence_number_bytes.data(), sequence_number_bytes.size());
28025  parameter_section_bytes += sequence_number_bytes;
28026  command_size += sequence_number_bytes.size();
28027  std::string command_hash(32, 0);
28028  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
28029  std::string authorization_section_bytes;
28030  std::string authorization_size_bytes;
28031  if (authorization_delegate) {
28032    if (!authorization_delegate->GetCommandAuthorization(
28033            command_hash, is_command_parameter_encryption_possible,
28034            is_response_parameter_encryption_possible,
28035            &authorization_section_bytes)) {
28036      return TRUNKS_RC_AUTHORIZATION_FAILED;
28037    }
28038    if (!authorization_section_bytes.empty()) {
28039      tag = TPM_ST_SESSIONS;
28040      std::string tmp;
28041      rc = Serialize_UINT32(authorization_section_bytes.size(),
28042                            &authorization_size_bytes);
28043      if (rc != TPM_RC_SUCCESS) {
28044        return rc;
28045      }
28046      command_size +=
28047          authorization_size_bytes.size() + authorization_section_bytes.size();
28048    }
28049  }
28050  std::string tag_bytes;
28051  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28052  if (rc != TPM_RC_SUCCESS) {
28053    return rc;
28054  }
28055  std::string command_size_bytes;
28056  rc = Serialize_UINT32(command_size, &command_size_bytes);
28057  if (rc != TPM_RC_SUCCESS) {
28058    return rc;
28059  }
28060  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28061                        handle_section_bytes + authorization_size_bytes +
28062                        authorization_section_bytes + parameter_section_bytes;
28063  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28064  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
28065                                            serialized_command->size());
28066  return TPM_RC_SUCCESS;
28067}
28068
28069TPM_RC Tpm::ParseResponse_FirmwareRead(
28070    const std::string& response,
28071    TPM2B_MAX_BUFFER* fu_data,
28072    AuthorizationDelegate* authorization_delegate) {
28073  VLOG(3) << __func__;
28074  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28075  TPM_RC rc = TPM_RC_SUCCESS;
28076  std::string buffer(response);
28077  TPM_ST tag;
28078  std::string tag_bytes;
28079  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28080  if (rc != TPM_RC_SUCCESS) {
28081    return rc;
28082  }
28083  UINT32 response_size;
28084  std::string response_size_bytes;
28085  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28086  if (rc != TPM_RC_SUCCESS) {
28087    return rc;
28088  }
28089  TPM_RC response_code;
28090  std::string response_code_bytes;
28091  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28092  if (rc != TPM_RC_SUCCESS) {
28093    return rc;
28094  }
28095  if (response_size != response.size()) {
28096    return TPM_RC_SIZE;
28097  }
28098  if (response_code != TPM_RC_SUCCESS) {
28099    return response_code;
28100  }
28101  TPM_CC command_code = TPM_CC_FirmwareRead;
28102  std::string command_code_bytes;
28103  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28104  if (rc != TPM_RC_SUCCESS) {
28105    return rc;
28106  }
28107  std::string authorization_section_bytes;
28108  if (tag == TPM_ST_SESSIONS) {
28109    UINT32 parameter_section_size = buffer.size();
28110    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28111    if (rc != TPM_RC_SUCCESS) {
28112      return rc;
28113    }
28114    if (parameter_section_size > buffer.size()) {
28115      return TPM_RC_INSUFFICIENT;
28116    }
28117    authorization_section_bytes = buffer.substr(parameter_section_size);
28118    // Keep the parameter section in |buffer|.
28119    buffer.erase(parameter_section_size);
28120  }
28121  std::unique_ptr<crypto::SecureHash> hash(
28122      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28123  hash->Update(response_code_bytes.data(), response_code_bytes.size());
28124  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28125  hash->Update(buffer.data(), buffer.size());
28126  std::string response_hash(32, 0);
28127  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
28128  if (tag == TPM_ST_SESSIONS) {
28129    CHECK(authorization_delegate) << "Authorization delegate missing!";
28130    if (!authorization_delegate->CheckResponseAuthorization(
28131            response_hash, authorization_section_bytes)) {
28132      return TRUNKS_RC_AUTHORIZATION_FAILED;
28133    }
28134  }
28135  std::string fu_data_bytes;
28136  rc = Parse_TPM2B_MAX_BUFFER(&buffer, fu_data, &fu_data_bytes);
28137  if (rc != TPM_RC_SUCCESS) {
28138    return rc;
28139  }
28140  if (tag == TPM_ST_SESSIONS) {
28141    CHECK(authorization_delegate) << "Authorization delegate missing!";
28142    // Decrypt just the parameter data, not the size.
28143    std::string tmp = fu_data_bytes.substr(2);
28144    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
28145      return TRUNKS_RC_ENCRYPTION_FAILED;
28146    }
28147    fu_data_bytes.replace(2, std::string::npos, tmp);
28148    rc = Parse_TPM2B_MAX_BUFFER(&fu_data_bytes, fu_data, nullptr);
28149    if (rc != TPM_RC_SUCCESS) {
28150      return rc;
28151    }
28152  }
28153  return TPM_RC_SUCCESS;
28154}
28155
28156void FirmwareReadErrorCallback(const Tpm::FirmwareReadResponse& callback,
28157                               TPM_RC response_code) {
28158  VLOG(1) << __func__;
28159  callback.Run(response_code, TPM2B_MAX_BUFFER());
28160}
28161
28162void FirmwareReadResponseParser(const Tpm::FirmwareReadResponse& callback,
28163                                AuthorizationDelegate* authorization_delegate,
28164                                const std::string& response) {
28165  VLOG(1) << __func__;
28166  base::Callback<void(TPM_RC)> error_reporter =
28167      base::Bind(FirmwareReadErrorCallback, callback);
28168  TPM2B_MAX_BUFFER fu_data;
28169  TPM_RC rc = Tpm::ParseResponse_FirmwareRead(response, &fu_data,
28170                                              authorization_delegate);
28171  if (rc != TPM_RC_SUCCESS) {
28172    error_reporter.Run(rc);
28173    return;
28174  }
28175  callback.Run(rc, fu_data);
28176}
28177
28178void Tpm::FirmwareRead(const UINT32& sequence_number,
28179                       AuthorizationDelegate* authorization_delegate,
28180                       const FirmwareReadResponse& callback) {
28181  VLOG(1) << __func__;
28182  base::Callback<void(TPM_RC)> error_reporter =
28183      base::Bind(FirmwareReadErrorCallback, callback);
28184  base::Callback<void(const std::string&)> parser =
28185      base::Bind(FirmwareReadResponseParser, callback, authorization_delegate);
28186  std::string command;
28187  TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28188                                            authorization_delegate);
28189  if (rc != TPM_RC_SUCCESS) {
28190    error_reporter.Run(rc);
28191    return;
28192  }
28193  transceiver_->SendCommand(command, parser);
28194}
28195
28196TPM_RC Tpm::FirmwareReadSync(const UINT32& sequence_number,
28197                             TPM2B_MAX_BUFFER* fu_data,
28198                             AuthorizationDelegate* authorization_delegate) {
28199  VLOG(1) << __func__;
28200  std::string command;
28201  TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28202                                            authorization_delegate);
28203  if (rc != TPM_RC_SUCCESS) {
28204    return rc;
28205  }
28206  std::string response = transceiver_->SendCommandAndWait(command);
28207  rc = ParseResponse_FirmwareRead(response, fu_data, authorization_delegate);
28208  return rc;
28209}
28210
28211TPM_RC Tpm::SerializeCommand_ContextSave(
28212    const TPMI_DH_CONTEXT& save_handle,
28213    const std::string& save_handle_name,
28214    std::string* serialized_command,
28215    AuthorizationDelegate* authorization_delegate) {
28216  VLOG(3) << __func__;
28217  TPM_RC rc = TPM_RC_SUCCESS;
28218  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28219  UINT32 command_size = 10;  // Header size.
28220  std::string handle_section_bytes;
28221  std::string parameter_section_bytes;
28222  TPM_CC command_code = TPM_CC_ContextSave;
28223  bool is_command_parameter_encryption_possible = false;
28224  bool is_response_parameter_encryption_possible = false;
28225  std::string command_code_bytes;
28226  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28227  if (rc != TPM_RC_SUCCESS) {
28228    return rc;
28229  }
28230  std::string save_handle_bytes;
28231  rc = Serialize_TPMI_DH_CONTEXT(save_handle, &save_handle_bytes);
28232  if (rc != TPM_RC_SUCCESS) {
28233    return rc;
28234  }
28235  std::unique_ptr<crypto::SecureHash> hash(
28236      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28237  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28238  hash->Update(save_handle_name.data(), save_handle_name.size());
28239  handle_section_bytes += save_handle_bytes;
28240  command_size += save_handle_bytes.size();
28241  std::string command_hash(32, 0);
28242  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
28243  std::string authorization_section_bytes;
28244  std::string authorization_size_bytes;
28245  if (authorization_delegate) {
28246    if (!authorization_delegate->GetCommandAuthorization(
28247            command_hash, is_command_parameter_encryption_possible,
28248            is_response_parameter_encryption_possible,
28249            &authorization_section_bytes)) {
28250      return TRUNKS_RC_AUTHORIZATION_FAILED;
28251    }
28252    if (!authorization_section_bytes.empty()) {
28253      tag = TPM_ST_SESSIONS;
28254      std::string tmp;
28255      rc = Serialize_UINT32(authorization_section_bytes.size(),
28256                            &authorization_size_bytes);
28257      if (rc != TPM_RC_SUCCESS) {
28258        return rc;
28259      }
28260      command_size +=
28261          authorization_size_bytes.size() + authorization_section_bytes.size();
28262    }
28263  }
28264  std::string tag_bytes;
28265  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28266  if (rc != TPM_RC_SUCCESS) {
28267    return rc;
28268  }
28269  std::string command_size_bytes;
28270  rc = Serialize_UINT32(command_size, &command_size_bytes);
28271  if (rc != TPM_RC_SUCCESS) {
28272    return rc;
28273  }
28274  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28275                        handle_section_bytes + authorization_size_bytes +
28276                        authorization_section_bytes + parameter_section_bytes;
28277  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28278  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
28279                                            serialized_command->size());
28280  return TPM_RC_SUCCESS;
28281}
28282
28283TPM_RC Tpm::ParseResponse_ContextSave(
28284    const std::string& response,
28285    TPMS_CONTEXT* context,
28286    AuthorizationDelegate* authorization_delegate) {
28287  VLOG(3) << __func__;
28288  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28289  TPM_RC rc = TPM_RC_SUCCESS;
28290  std::string buffer(response);
28291  TPM_ST tag;
28292  std::string tag_bytes;
28293  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28294  if (rc != TPM_RC_SUCCESS) {
28295    return rc;
28296  }
28297  UINT32 response_size;
28298  std::string response_size_bytes;
28299  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28300  if (rc != TPM_RC_SUCCESS) {
28301    return rc;
28302  }
28303  TPM_RC response_code;
28304  std::string response_code_bytes;
28305  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28306  if (rc != TPM_RC_SUCCESS) {
28307    return rc;
28308  }
28309  if (response_size != response.size()) {
28310    return TPM_RC_SIZE;
28311  }
28312  if (response_code != TPM_RC_SUCCESS) {
28313    return response_code;
28314  }
28315  TPM_CC command_code = TPM_CC_ContextSave;
28316  std::string command_code_bytes;
28317  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28318  if (rc != TPM_RC_SUCCESS) {
28319    return rc;
28320  }
28321  std::string authorization_section_bytes;
28322  if (tag == TPM_ST_SESSIONS) {
28323    UINT32 parameter_section_size = buffer.size();
28324    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28325    if (rc != TPM_RC_SUCCESS) {
28326      return rc;
28327    }
28328    if (parameter_section_size > buffer.size()) {
28329      return TPM_RC_INSUFFICIENT;
28330    }
28331    authorization_section_bytes = buffer.substr(parameter_section_size);
28332    // Keep the parameter section in |buffer|.
28333    buffer.erase(parameter_section_size);
28334  }
28335  std::unique_ptr<crypto::SecureHash> hash(
28336      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28337  hash->Update(response_code_bytes.data(), response_code_bytes.size());
28338  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28339  hash->Update(buffer.data(), buffer.size());
28340  std::string response_hash(32, 0);
28341  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
28342  if (tag == TPM_ST_SESSIONS) {
28343    CHECK(authorization_delegate) << "Authorization delegate missing!";
28344    if (!authorization_delegate->CheckResponseAuthorization(
28345            response_hash, authorization_section_bytes)) {
28346      return TRUNKS_RC_AUTHORIZATION_FAILED;
28347    }
28348  }
28349  std::string context_bytes;
28350  rc = Parse_TPMS_CONTEXT(&buffer, context, &context_bytes);
28351  if (rc != TPM_RC_SUCCESS) {
28352    return rc;
28353  }
28354  return TPM_RC_SUCCESS;
28355}
28356
28357void ContextSaveErrorCallback(const Tpm::ContextSaveResponse& callback,
28358                              TPM_RC response_code) {
28359  VLOG(1) << __func__;
28360  callback.Run(response_code, TPMS_CONTEXT());
28361}
28362
28363void ContextSaveResponseParser(const Tpm::ContextSaveResponse& callback,
28364                               AuthorizationDelegate* authorization_delegate,
28365                               const std::string& response) {
28366  VLOG(1) << __func__;
28367  base::Callback<void(TPM_RC)> error_reporter =
28368      base::Bind(ContextSaveErrorCallback, callback);
28369  TPMS_CONTEXT context;
28370  TPM_RC rc = Tpm::ParseResponse_ContextSave(response, &context,
28371                                             authorization_delegate);
28372  if (rc != TPM_RC_SUCCESS) {
28373    error_reporter.Run(rc);
28374    return;
28375  }
28376  callback.Run(rc, context);
28377}
28378
28379void Tpm::ContextSave(const TPMI_DH_CONTEXT& save_handle,
28380                      const std::string& save_handle_name,
28381                      AuthorizationDelegate* authorization_delegate,
28382                      const ContextSaveResponse& callback) {
28383  VLOG(1) << __func__;
28384  base::Callback<void(TPM_RC)> error_reporter =
28385      base::Bind(ContextSaveErrorCallback, callback);
28386  base::Callback<void(const std::string&)> parser =
28387      base::Bind(ContextSaveResponseParser, callback, authorization_delegate);
28388  std::string command;
28389  TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28390                                           &command, authorization_delegate);
28391  if (rc != TPM_RC_SUCCESS) {
28392    error_reporter.Run(rc);
28393    return;
28394  }
28395  transceiver_->SendCommand(command, parser);
28396}
28397
28398TPM_RC Tpm::ContextSaveSync(const TPMI_DH_CONTEXT& save_handle,
28399                            const std::string& save_handle_name,
28400                            TPMS_CONTEXT* context,
28401                            AuthorizationDelegate* authorization_delegate) {
28402  VLOG(1) << __func__;
28403  std::string command;
28404  TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28405                                           &command, authorization_delegate);
28406  if (rc != TPM_RC_SUCCESS) {
28407    return rc;
28408  }
28409  std::string response = transceiver_->SendCommandAndWait(command);
28410  rc = ParseResponse_ContextSave(response, context, authorization_delegate);
28411  return rc;
28412}
28413
28414TPM_RC Tpm::SerializeCommand_ContextLoad(
28415    const TPMS_CONTEXT& context,
28416    std::string* serialized_command,
28417    AuthorizationDelegate* authorization_delegate) {
28418  VLOG(3) << __func__;
28419  TPM_RC rc = TPM_RC_SUCCESS;
28420  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28421  UINT32 command_size = 10;  // Header size.
28422  std::string handle_section_bytes;
28423  std::string parameter_section_bytes;
28424  TPM_CC command_code = TPM_CC_ContextLoad;
28425  bool is_command_parameter_encryption_possible = false;
28426  bool is_response_parameter_encryption_possible = false;
28427  std::string command_code_bytes;
28428  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28429  if (rc != TPM_RC_SUCCESS) {
28430    return rc;
28431  }
28432  std::string context_bytes;
28433  rc = Serialize_TPMS_CONTEXT(context, &context_bytes);
28434  if (rc != TPM_RC_SUCCESS) {
28435    return rc;
28436  }
28437  std::unique_ptr<crypto::SecureHash> hash(
28438      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28439  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28440  hash->Update(context_bytes.data(), context_bytes.size());
28441  parameter_section_bytes += context_bytes;
28442  command_size += context_bytes.size();
28443  std::string command_hash(32, 0);
28444  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
28445  std::string authorization_section_bytes;
28446  std::string authorization_size_bytes;
28447  if (authorization_delegate) {
28448    if (!authorization_delegate->GetCommandAuthorization(
28449            command_hash, is_command_parameter_encryption_possible,
28450            is_response_parameter_encryption_possible,
28451            &authorization_section_bytes)) {
28452      return TRUNKS_RC_AUTHORIZATION_FAILED;
28453    }
28454    if (!authorization_section_bytes.empty()) {
28455      tag = TPM_ST_SESSIONS;
28456      std::string tmp;
28457      rc = Serialize_UINT32(authorization_section_bytes.size(),
28458                            &authorization_size_bytes);
28459      if (rc != TPM_RC_SUCCESS) {
28460        return rc;
28461      }
28462      command_size +=
28463          authorization_size_bytes.size() + authorization_section_bytes.size();
28464    }
28465  }
28466  std::string tag_bytes;
28467  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28468  if (rc != TPM_RC_SUCCESS) {
28469    return rc;
28470  }
28471  std::string command_size_bytes;
28472  rc = Serialize_UINT32(command_size, &command_size_bytes);
28473  if (rc != TPM_RC_SUCCESS) {
28474    return rc;
28475  }
28476  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28477                        handle_section_bytes + authorization_size_bytes +
28478                        authorization_section_bytes + parameter_section_bytes;
28479  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28480  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
28481                                            serialized_command->size());
28482  return TPM_RC_SUCCESS;
28483}
28484
28485TPM_RC Tpm::ParseResponse_ContextLoad(
28486    const std::string& response,
28487    TPMI_DH_CONTEXT* loaded_handle,
28488    AuthorizationDelegate* authorization_delegate) {
28489  VLOG(3) << __func__;
28490  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28491  TPM_RC rc = TPM_RC_SUCCESS;
28492  std::string buffer(response);
28493  TPM_ST tag;
28494  std::string tag_bytes;
28495  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28496  if (rc != TPM_RC_SUCCESS) {
28497    return rc;
28498  }
28499  UINT32 response_size;
28500  std::string response_size_bytes;
28501  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28502  if (rc != TPM_RC_SUCCESS) {
28503    return rc;
28504  }
28505  TPM_RC response_code;
28506  std::string response_code_bytes;
28507  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28508  if (rc != TPM_RC_SUCCESS) {
28509    return rc;
28510  }
28511  if (response_size != response.size()) {
28512    return TPM_RC_SIZE;
28513  }
28514  if (response_code != TPM_RC_SUCCESS) {
28515    return response_code;
28516  }
28517  std::string loaded_handle_bytes;
28518  rc = Parse_TPMI_DH_CONTEXT(&buffer, loaded_handle, &loaded_handle_bytes);
28519  if (rc != TPM_RC_SUCCESS) {
28520    return rc;
28521  }
28522  TPM_CC command_code = TPM_CC_ContextLoad;
28523  std::string command_code_bytes;
28524  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28525  if (rc != TPM_RC_SUCCESS) {
28526    return rc;
28527  }
28528  std::string authorization_section_bytes;
28529  if (tag == TPM_ST_SESSIONS) {
28530    UINT32 parameter_section_size = buffer.size();
28531    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28532    if (rc != TPM_RC_SUCCESS) {
28533      return rc;
28534    }
28535    if (parameter_section_size > buffer.size()) {
28536      return TPM_RC_INSUFFICIENT;
28537    }
28538    authorization_section_bytes = buffer.substr(parameter_section_size);
28539    // Keep the parameter section in |buffer|.
28540    buffer.erase(parameter_section_size);
28541  }
28542  std::unique_ptr<crypto::SecureHash> hash(
28543      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28544  hash->Update(response_code_bytes.data(), response_code_bytes.size());
28545  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28546  hash->Update(buffer.data(), buffer.size());
28547  std::string response_hash(32, 0);
28548  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
28549  if (tag == TPM_ST_SESSIONS) {
28550    CHECK(authorization_delegate) << "Authorization delegate missing!";
28551    if (!authorization_delegate->CheckResponseAuthorization(
28552            response_hash, authorization_section_bytes)) {
28553      return TRUNKS_RC_AUTHORIZATION_FAILED;
28554    }
28555  }
28556  return TPM_RC_SUCCESS;
28557}
28558
28559void ContextLoadErrorCallback(const Tpm::ContextLoadResponse& callback,
28560                              TPM_RC response_code) {
28561  VLOG(1) << __func__;
28562  callback.Run(response_code, TPMI_DH_CONTEXT());
28563}
28564
28565void ContextLoadResponseParser(const Tpm::ContextLoadResponse& callback,
28566                               AuthorizationDelegate* authorization_delegate,
28567                               const std::string& response) {
28568  VLOG(1) << __func__;
28569  base::Callback<void(TPM_RC)> error_reporter =
28570      base::Bind(ContextLoadErrorCallback, callback);
28571  TPMI_DH_CONTEXT loaded_handle;
28572  TPM_RC rc = Tpm::ParseResponse_ContextLoad(response, &loaded_handle,
28573                                             authorization_delegate);
28574  if (rc != TPM_RC_SUCCESS) {
28575    error_reporter.Run(rc);
28576    return;
28577  }
28578  callback.Run(rc, loaded_handle);
28579}
28580
28581void Tpm::ContextLoad(const TPMS_CONTEXT& context,
28582                      AuthorizationDelegate* authorization_delegate,
28583                      const ContextLoadResponse& callback) {
28584  VLOG(1) << __func__;
28585  base::Callback<void(TPM_RC)> error_reporter =
28586      base::Bind(ContextLoadErrorCallback, callback);
28587  base::Callback<void(const std::string&)> parser =
28588      base::Bind(ContextLoadResponseParser, callback, authorization_delegate);
28589  std::string command;
28590  TPM_RC rc =
28591      SerializeCommand_ContextLoad(context, &command, authorization_delegate);
28592  if (rc != TPM_RC_SUCCESS) {
28593    error_reporter.Run(rc);
28594    return;
28595  }
28596  transceiver_->SendCommand(command, parser);
28597}
28598
28599TPM_RC Tpm::ContextLoadSync(const TPMS_CONTEXT& context,
28600                            TPMI_DH_CONTEXT* loaded_handle,
28601                            AuthorizationDelegate* authorization_delegate) {
28602  VLOG(1) << __func__;
28603  std::string command;
28604  TPM_RC rc =
28605      SerializeCommand_ContextLoad(context, &command, authorization_delegate);
28606  if (rc != TPM_RC_SUCCESS) {
28607    return rc;
28608  }
28609  std::string response = transceiver_->SendCommandAndWait(command);
28610  rc = ParseResponse_ContextLoad(response, loaded_handle,
28611                                 authorization_delegate);
28612  return rc;
28613}
28614
28615TPM_RC Tpm::SerializeCommand_FlushContext(
28616    const TPMI_DH_CONTEXT& flush_handle,
28617    std::string* serialized_command,
28618    AuthorizationDelegate* authorization_delegate) {
28619  VLOG(3) << __func__;
28620  TPM_RC rc = TPM_RC_SUCCESS;
28621  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28622  UINT32 command_size = 10;  // Header size.
28623  std::string handle_section_bytes;
28624  std::string parameter_section_bytes;
28625  TPM_CC command_code = TPM_CC_FlushContext;
28626  bool is_command_parameter_encryption_possible = false;
28627  bool is_response_parameter_encryption_possible = false;
28628  std::string command_code_bytes;
28629  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28630  if (rc != TPM_RC_SUCCESS) {
28631    return rc;
28632  }
28633  std::string flush_handle_bytes;
28634  rc = Serialize_TPMI_DH_CONTEXT(flush_handle, &flush_handle_bytes);
28635  if (rc != TPM_RC_SUCCESS) {
28636    return rc;
28637  }
28638  std::unique_ptr<crypto::SecureHash> hash(
28639      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28640  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28641  hash->Update(flush_handle_bytes.data(), flush_handle_bytes.size());
28642  parameter_section_bytes += flush_handle_bytes;
28643  command_size += flush_handle_bytes.size();
28644  std::string command_hash(32, 0);
28645  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
28646  std::string authorization_section_bytes;
28647  std::string authorization_size_bytes;
28648  if (authorization_delegate) {
28649    if (!authorization_delegate->GetCommandAuthorization(
28650            command_hash, is_command_parameter_encryption_possible,
28651            is_response_parameter_encryption_possible,
28652            &authorization_section_bytes)) {
28653      return TRUNKS_RC_AUTHORIZATION_FAILED;
28654    }
28655    if (!authorization_section_bytes.empty()) {
28656      tag = TPM_ST_SESSIONS;
28657      std::string tmp;
28658      rc = Serialize_UINT32(authorization_section_bytes.size(),
28659                            &authorization_size_bytes);
28660      if (rc != TPM_RC_SUCCESS) {
28661        return rc;
28662      }
28663      command_size +=
28664          authorization_size_bytes.size() + authorization_section_bytes.size();
28665    }
28666  }
28667  std::string tag_bytes;
28668  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28669  if (rc != TPM_RC_SUCCESS) {
28670    return rc;
28671  }
28672  std::string command_size_bytes;
28673  rc = Serialize_UINT32(command_size, &command_size_bytes);
28674  if (rc != TPM_RC_SUCCESS) {
28675    return rc;
28676  }
28677  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28678                        handle_section_bytes + authorization_size_bytes +
28679                        authorization_section_bytes + parameter_section_bytes;
28680  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28681  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
28682                                            serialized_command->size());
28683  return TPM_RC_SUCCESS;
28684}
28685
28686TPM_RC Tpm::ParseResponse_FlushContext(
28687    const std::string& response,
28688    AuthorizationDelegate* authorization_delegate) {
28689  VLOG(3) << __func__;
28690  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28691  TPM_RC rc = TPM_RC_SUCCESS;
28692  std::string buffer(response);
28693  TPM_ST tag;
28694  std::string tag_bytes;
28695  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28696  if (rc != TPM_RC_SUCCESS) {
28697    return rc;
28698  }
28699  UINT32 response_size;
28700  std::string response_size_bytes;
28701  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28702  if (rc != TPM_RC_SUCCESS) {
28703    return rc;
28704  }
28705  TPM_RC response_code;
28706  std::string response_code_bytes;
28707  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28708  if (rc != TPM_RC_SUCCESS) {
28709    return rc;
28710  }
28711  if (response_size != response.size()) {
28712    return TPM_RC_SIZE;
28713  }
28714  if (response_code != TPM_RC_SUCCESS) {
28715    return response_code;
28716  }
28717  TPM_CC command_code = TPM_CC_FlushContext;
28718  std::string command_code_bytes;
28719  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28720  if (rc != TPM_RC_SUCCESS) {
28721    return rc;
28722  }
28723  std::string authorization_section_bytes;
28724  if (tag == TPM_ST_SESSIONS) {
28725    UINT32 parameter_section_size = buffer.size();
28726    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28727    if (rc != TPM_RC_SUCCESS) {
28728      return rc;
28729    }
28730    if (parameter_section_size > buffer.size()) {
28731      return TPM_RC_INSUFFICIENT;
28732    }
28733    authorization_section_bytes = buffer.substr(parameter_section_size);
28734    // Keep the parameter section in |buffer|.
28735    buffer.erase(parameter_section_size);
28736  }
28737  std::unique_ptr<crypto::SecureHash> hash(
28738      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28739  hash->Update(response_code_bytes.data(), response_code_bytes.size());
28740  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28741  hash->Update(buffer.data(), buffer.size());
28742  std::string response_hash(32, 0);
28743  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
28744  if (tag == TPM_ST_SESSIONS) {
28745    CHECK(authorization_delegate) << "Authorization delegate missing!";
28746    if (!authorization_delegate->CheckResponseAuthorization(
28747            response_hash, authorization_section_bytes)) {
28748      return TRUNKS_RC_AUTHORIZATION_FAILED;
28749    }
28750  }
28751  return TPM_RC_SUCCESS;
28752}
28753
28754void FlushContextErrorCallback(const Tpm::FlushContextResponse& callback,
28755                               TPM_RC response_code) {
28756  VLOG(1) << __func__;
28757  callback.Run(response_code);
28758}
28759
28760void FlushContextResponseParser(const Tpm::FlushContextResponse& callback,
28761                                AuthorizationDelegate* authorization_delegate,
28762                                const std::string& response) {
28763  VLOG(1) << __func__;
28764  base::Callback<void(TPM_RC)> error_reporter =
28765      base::Bind(FlushContextErrorCallback, callback);
28766  TPM_RC rc = Tpm::ParseResponse_FlushContext(response, authorization_delegate);
28767  if (rc != TPM_RC_SUCCESS) {
28768    error_reporter.Run(rc);
28769    return;
28770  }
28771  callback.Run(rc);
28772}
28773
28774void Tpm::FlushContext(const TPMI_DH_CONTEXT& flush_handle,
28775                       AuthorizationDelegate* authorization_delegate,
28776                       const FlushContextResponse& callback) {
28777  VLOG(1) << __func__;
28778  base::Callback<void(TPM_RC)> error_reporter =
28779      base::Bind(FlushContextErrorCallback, callback);
28780  base::Callback<void(const std::string&)> parser =
28781      base::Bind(FlushContextResponseParser, callback, authorization_delegate);
28782  std::string command;
28783  TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
28784                                            authorization_delegate);
28785  if (rc != TPM_RC_SUCCESS) {
28786    error_reporter.Run(rc);
28787    return;
28788  }
28789  transceiver_->SendCommand(command, parser);
28790}
28791
28792TPM_RC Tpm::FlushContextSync(const TPMI_DH_CONTEXT& flush_handle,
28793                             AuthorizationDelegate* authorization_delegate) {
28794  VLOG(1) << __func__;
28795  std::string command;
28796  TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
28797                                            authorization_delegate);
28798  if (rc != TPM_RC_SUCCESS) {
28799    return rc;
28800  }
28801  std::string response = transceiver_->SendCommandAndWait(command);
28802  rc = ParseResponse_FlushContext(response, authorization_delegate);
28803  return rc;
28804}
28805
28806TPM_RC Tpm::SerializeCommand_EvictControl(
28807    const TPMI_RH_PROVISION& auth,
28808    const std::string& auth_name,
28809    const TPMI_DH_OBJECT& object_handle,
28810    const std::string& object_handle_name,
28811    const TPMI_DH_PERSISTENT& persistent_handle,
28812    std::string* serialized_command,
28813    AuthorizationDelegate* authorization_delegate) {
28814  VLOG(3) << __func__;
28815  TPM_RC rc = TPM_RC_SUCCESS;
28816  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28817  UINT32 command_size = 10;  // Header size.
28818  std::string handle_section_bytes;
28819  std::string parameter_section_bytes;
28820  TPM_CC command_code = TPM_CC_EvictControl;
28821  bool is_command_parameter_encryption_possible = false;
28822  bool is_response_parameter_encryption_possible = false;
28823  std::string command_code_bytes;
28824  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28825  if (rc != TPM_RC_SUCCESS) {
28826    return rc;
28827  }
28828  std::string auth_bytes;
28829  rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
28830  if (rc != TPM_RC_SUCCESS) {
28831    return rc;
28832  }
28833  std::string object_handle_bytes;
28834  rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
28835  if (rc != TPM_RC_SUCCESS) {
28836    return rc;
28837  }
28838  std::string persistent_handle_bytes;
28839  rc =
28840      Serialize_TPMI_DH_PERSISTENT(persistent_handle, &persistent_handle_bytes);
28841  if (rc != TPM_RC_SUCCESS) {
28842    return rc;
28843  }
28844  std::unique_ptr<crypto::SecureHash> hash(
28845      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28846  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28847  hash->Update(auth_name.data(), auth_name.size());
28848  handle_section_bytes += auth_bytes;
28849  command_size += auth_bytes.size();
28850  hash->Update(object_handle_name.data(), object_handle_name.size());
28851  handle_section_bytes += object_handle_bytes;
28852  command_size += object_handle_bytes.size();
28853  hash->Update(persistent_handle_bytes.data(), persistent_handle_bytes.size());
28854  parameter_section_bytes += persistent_handle_bytes;
28855  command_size += persistent_handle_bytes.size();
28856  std::string command_hash(32, 0);
28857  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
28858  std::string authorization_section_bytes;
28859  std::string authorization_size_bytes;
28860  if (authorization_delegate) {
28861    if (!authorization_delegate->GetCommandAuthorization(
28862            command_hash, is_command_parameter_encryption_possible,
28863            is_response_parameter_encryption_possible,
28864            &authorization_section_bytes)) {
28865      return TRUNKS_RC_AUTHORIZATION_FAILED;
28866    }
28867    if (!authorization_section_bytes.empty()) {
28868      tag = TPM_ST_SESSIONS;
28869      std::string tmp;
28870      rc = Serialize_UINT32(authorization_section_bytes.size(),
28871                            &authorization_size_bytes);
28872      if (rc != TPM_RC_SUCCESS) {
28873        return rc;
28874      }
28875      command_size +=
28876          authorization_size_bytes.size() + authorization_section_bytes.size();
28877    }
28878  }
28879  std::string tag_bytes;
28880  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28881  if (rc != TPM_RC_SUCCESS) {
28882    return rc;
28883  }
28884  std::string command_size_bytes;
28885  rc = Serialize_UINT32(command_size, &command_size_bytes);
28886  if (rc != TPM_RC_SUCCESS) {
28887    return rc;
28888  }
28889  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28890                        handle_section_bytes + authorization_size_bytes +
28891                        authorization_section_bytes + parameter_section_bytes;
28892  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28893  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
28894                                            serialized_command->size());
28895  return TPM_RC_SUCCESS;
28896}
28897
28898TPM_RC Tpm::ParseResponse_EvictControl(
28899    const std::string& response,
28900    AuthorizationDelegate* authorization_delegate) {
28901  VLOG(3) << __func__;
28902  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28903  TPM_RC rc = TPM_RC_SUCCESS;
28904  std::string buffer(response);
28905  TPM_ST tag;
28906  std::string tag_bytes;
28907  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28908  if (rc != TPM_RC_SUCCESS) {
28909    return rc;
28910  }
28911  UINT32 response_size;
28912  std::string response_size_bytes;
28913  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28914  if (rc != TPM_RC_SUCCESS) {
28915    return rc;
28916  }
28917  TPM_RC response_code;
28918  std::string response_code_bytes;
28919  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28920  if (rc != TPM_RC_SUCCESS) {
28921    return rc;
28922  }
28923  if (response_size != response.size()) {
28924    return TPM_RC_SIZE;
28925  }
28926  if (response_code != TPM_RC_SUCCESS) {
28927    return response_code;
28928  }
28929  TPM_CC command_code = TPM_CC_EvictControl;
28930  std::string command_code_bytes;
28931  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28932  if (rc != TPM_RC_SUCCESS) {
28933    return rc;
28934  }
28935  std::string authorization_section_bytes;
28936  if (tag == TPM_ST_SESSIONS) {
28937    UINT32 parameter_section_size = buffer.size();
28938    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28939    if (rc != TPM_RC_SUCCESS) {
28940      return rc;
28941    }
28942    if (parameter_section_size > buffer.size()) {
28943      return TPM_RC_INSUFFICIENT;
28944    }
28945    authorization_section_bytes = buffer.substr(parameter_section_size);
28946    // Keep the parameter section in |buffer|.
28947    buffer.erase(parameter_section_size);
28948  }
28949  std::unique_ptr<crypto::SecureHash> hash(
28950      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28951  hash->Update(response_code_bytes.data(), response_code_bytes.size());
28952  hash->Update(command_code_bytes.data(), command_code_bytes.size());
28953  hash->Update(buffer.data(), buffer.size());
28954  std::string response_hash(32, 0);
28955  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
28956  if (tag == TPM_ST_SESSIONS) {
28957    CHECK(authorization_delegate) << "Authorization delegate missing!";
28958    if (!authorization_delegate->CheckResponseAuthorization(
28959            response_hash, authorization_section_bytes)) {
28960      return TRUNKS_RC_AUTHORIZATION_FAILED;
28961    }
28962  }
28963  return TPM_RC_SUCCESS;
28964}
28965
28966void EvictControlErrorCallback(const Tpm::EvictControlResponse& callback,
28967                               TPM_RC response_code) {
28968  VLOG(1) << __func__;
28969  callback.Run(response_code);
28970}
28971
28972void EvictControlResponseParser(const Tpm::EvictControlResponse& callback,
28973                                AuthorizationDelegate* authorization_delegate,
28974                                const std::string& response) {
28975  VLOG(1) << __func__;
28976  base::Callback<void(TPM_RC)> error_reporter =
28977      base::Bind(EvictControlErrorCallback, callback);
28978  TPM_RC rc = Tpm::ParseResponse_EvictControl(response, authorization_delegate);
28979  if (rc != TPM_RC_SUCCESS) {
28980    error_reporter.Run(rc);
28981    return;
28982  }
28983  callback.Run(rc);
28984}
28985
28986void Tpm::EvictControl(const TPMI_RH_PROVISION& auth,
28987                       const std::string& auth_name,
28988                       const TPMI_DH_OBJECT& object_handle,
28989                       const std::string& object_handle_name,
28990                       const TPMI_DH_PERSISTENT& persistent_handle,
28991                       AuthorizationDelegate* authorization_delegate,
28992                       const EvictControlResponse& callback) {
28993  VLOG(1) << __func__;
28994  base::Callback<void(TPM_RC)> error_reporter =
28995      base::Bind(EvictControlErrorCallback, callback);
28996  base::Callback<void(const std::string&)> parser =
28997      base::Bind(EvictControlResponseParser, callback, authorization_delegate);
28998  std::string command;
28999  TPM_RC rc = SerializeCommand_EvictControl(
29000      auth, auth_name, object_handle, object_handle_name, persistent_handle,
29001      &command, authorization_delegate);
29002  if (rc != TPM_RC_SUCCESS) {
29003    error_reporter.Run(rc);
29004    return;
29005  }
29006  transceiver_->SendCommand(command, parser);
29007}
29008
29009TPM_RC Tpm::EvictControlSync(const TPMI_RH_PROVISION& auth,
29010                             const std::string& auth_name,
29011                             const TPMI_DH_OBJECT& object_handle,
29012                             const std::string& object_handle_name,
29013                             const TPMI_DH_PERSISTENT& persistent_handle,
29014                             AuthorizationDelegate* authorization_delegate) {
29015  VLOG(1) << __func__;
29016  std::string command;
29017  TPM_RC rc = SerializeCommand_EvictControl(
29018      auth, auth_name, object_handle, object_handle_name, persistent_handle,
29019      &command, authorization_delegate);
29020  if (rc != TPM_RC_SUCCESS) {
29021    return rc;
29022  }
29023  std::string response = transceiver_->SendCommandAndWait(command);
29024  rc = ParseResponse_EvictControl(response, authorization_delegate);
29025  return rc;
29026}
29027
29028TPM_RC Tpm::SerializeCommand_ReadClock(
29029    std::string* serialized_command,
29030    AuthorizationDelegate* authorization_delegate) {
29031  VLOG(3) << __func__;
29032  TPM_RC rc = TPM_RC_SUCCESS;
29033  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29034  UINT32 command_size = 10;  // Header size.
29035  std::string handle_section_bytes;
29036  std::string parameter_section_bytes;
29037  TPM_CC command_code = TPM_CC_ReadClock;
29038  bool is_command_parameter_encryption_possible = false;
29039  bool is_response_parameter_encryption_possible = false;
29040  std::string command_code_bytes;
29041  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29042  if (rc != TPM_RC_SUCCESS) {
29043    return rc;
29044  }
29045  std::unique_ptr<crypto::SecureHash> hash(
29046      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29047  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29048  std::string command_hash(32, 0);
29049  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
29050  std::string authorization_section_bytes;
29051  std::string authorization_size_bytes;
29052  if (authorization_delegate) {
29053    if (!authorization_delegate->GetCommandAuthorization(
29054            command_hash, is_command_parameter_encryption_possible,
29055            is_response_parameter_encryption_possible,
29056            &authorization_section_bytes)) {
29057      return TRUNKS_RC_AUTHORIZATION_FAILED;
29058    }
29059    if (!authorization_section_bytes.empty()) {
29060      tag = TPM_ST_SESSIONS;
29061      std::string tmp;
29062      rc = Serialize_UINT32(authorization_section_bytes.size(),
29063                            &authorization_size_bytes);
29064      if (rc != TPM_RC_SUCCESS) {
29065        return rc;
29066      }
29067      command_size +=
29068          authorization_size_bytes.size() + authorization_section_bytes.size();
29069    }
29070  }
29071  std::string tag_bytes;
29072  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29073  if (rc != TPM_RC_SUCCESS) {
29074    return rc;
29075  }
29076  std::string command_size_bytes;
29077  rc = Serialize_UINT32(command_size, &command_size_bytes);
29078  if (rc != TPM_RC_SUCCESS) {
29079    return rc;
29080  }
29081  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29082                        handle_section_bytes + authorization_size_bytes +
29083                        authorization_section_bytes + parameter_section_bytes;
29084  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29085  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
29086                                            serialized_command->size());
29087  return TPM_RC_SUCCESS;
29088}
29089
29090TPM_RC Tpm::ParseResponse_ReadClock(
29091    const std::string& response,
29092    TPMS_TIME_INFO* current_time,
29093    AuthorizationDelegate* authorization_delegate) {
29094  VLOG(3) << __func__;
29095  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29096  TPM_RC rc = TPM_RC_SUCCESS;
29097  std::string buffer(response);
29098  TPM_ST tag;
29099  std::string tag_bytes;
29100  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29101  if (rc != TPM_RC_SUCCESS) {
29102    return rc;
29103  }
29104  UINT32 response_size;
29105  std::string response_size_bytes;
29106  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29107  if (rc != TPM_RC_SUCCESS) {
29108    return rc;
29109  }
29110  TPM_RC response_code;
29111  std::string response_code_bytes;
29112  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29113  if (rc != TPM_RC_SUCCESS) {
29114    return rc;
29115  }
29116  if (response_size != response.size()) {
29117    return TPM_RC_SIZE;
29118  }
29119  if (response_code != TPM_RC_SUCCESS) {
29120    return response_code;
29121  }
29122  TPM_CC command_code = TPM_CC_ReadClock;
29123  std::string command_code_bytes;
29124  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29125  if (rc != TPM_RC_SUCCESS) {
29126    return rc;
29127  }
29128  std::string authorization_section_bytes;
29129  if (tag == TPM_ST_SESSIONS) {
29130    UINT32 parameter_section_size = buffer.size();
29131    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29132    if (rc != TPM_RC_SUCCESS) {
29133      return rc;
29134    }
29135    if (parameter_section_size > buffer.size()) {
29136      return TPM_RC_INSUFFICIENT;
29137    }
29138    authorization_section_bytes = buffer.substr(parameter_section_size);
29139    // Keep the parameter section in |buffer|.
29140    buffer.erase(parameter_section_size);
29141  }
29142  std::unique_ptr<crypto::SecureHash> hash(
29143      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29144  hash->Update(response_code_bytes.data(), response_code_bytes.size());
29145  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29146  hash->Update(buffer.data(), buffer.size());
29147  std::string response_hash(32, 0);
29148  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
29149  if (tag == TPM_ST_SESSIONS) {
29150    CHECK(authorization_delegate) << "Authorization delegate missing!";
29151    if (!authorization_delegate->CheckResponseAuthorization(
29152            response_hash, authorization_section_bytes)) {
29153      return TRUNKS_RC_AUTHORIZATION_FAILED;
29154    }
29155  }
29156  std::string current_time_bytes;
29157  rc = Parse_TPMS_TIME_INFO(&buffer, current_time, &current_time_bytes);
29158  if (rc != TPM_RC_SUCCESS) {
29159    return rc;
29160  }
29161  return TPM_RC_SUCCESS;
29162}
29163
29164void ReadClockErrorCallback(const Tpm::ReadClockResponse& callback,
29165                            TPM_RC response_code) {
29166  VLOG(1) << __func__;
29167  callback.Run(response_code, TPMS_TIME_INFO());
29168}
29169
29170void ReadClockResponseParser(const Tpm::ReadClockResponse& callback,
29171                             AuthorizationDelegate* authorization_delegate,
29172                             const std::string& response) {
29173  VLOG(1) << __func__;
29174  base::Callback<void(TPM_RC)> error_reporter =
29175      base::Bind(ReadClockErrorCallback, callback);
29176  TPMS_TIME_INFO current_time;
29177  TPM_RC rc = Tpm::ParseResponse_ReadClock(response, &current_time,
29178                                           authorization_delegate);
29179  if (rc != TPM_RC_SUCCESS) {
29180    error_reporter.Run(rc);
29181    return;
29182  }
29183  callback.Run(rc, current_time);
29184}
29185
29186void Tpm::ReadClock(AuthorizationDelegate* authorization_delegate,
29187                    const ReadClockResponse& callback) {
29188  VLOG(1) << __func__;
29189  base::Callback<void(TPM_RC)> error_reporter =
29190      base::Bind(ReadClockErrorCallback, callback);
29191  base::Callback<void(const std::string&)> parser =
29192      base::Bind(ReadClockResponseParser, callback, authorization_delegate);
29193  std::string command;
29194  TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29195  if (rc != TPM_RC_SUCCESS) {
29196    error_reporter.Run(rc);
29197    return;
29198  }
29199  transceiver_->SendCommand(command, parser);
29200}
29201
29202TPM_RC Tpm::ReadClockSync(TPMS_TIME_INFO* current_time,
29203                          AuthorizationDelegate* authorization_delegate) {
29204  VLOG(1) << __func__;
29205  std::string command;
29206  TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29207  if (rc != TPM_RC_SUCCESS) {
29208    return rc;
29209  }
29210  std::string response = transceiver_->SendCommandAndWait(command);
29211  rc = ParseResponse_ReadClock(response, current_time, authorization_delegate);
29212  return rc;
29213}
29214
29215TPM_RC Tpm::SerializeCommand_ClockSet(
29216    const TPMI_RH_PROVISION& auth,
29217    const std::string& auth_name,
29218    const UINT64& new_time,
29219    std::string* serialized_command,
29220    AuthorizationDelegate* authorization_delegate) {
29221  VLOG(3) << __func__;
29222  TPM_RC rc = TPM_RC_SUCCESS;
29223  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29224  UINT32 command_size = 10;  // Header size.
29225  std::string handle_section_bytes;
29226  std::string parameter_section_bytes;
29227  TPM_CC command_code = TPM_CC_ClockSet;
29228  bool is_command_parameter_encryption_possible = false;
29229  bool is_response_parameter_encryption_possible = false;
29230  std::string command_code_bytes;
29231  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29232  if (rc != TPM_RC_SUCCESS) {
29233    return rc;
29234  }
29235  std::string auth_bytes;
29236  rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29237  if (rc != TPM_RC_SUCCESS) {
29238    return rc;
29239  }
29240  std::string new_time_bytes;
29241  rc = Serialize_UINT64(new_time, &new_time_bytes);
29242  if (rc != TPM_RC_SUCCESS) {
29243    return rc;
29244  }
29245  std::unique_ptr<crypto::SecureHash> hash(
29246      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29247  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29248  hash->Update(auth_name.data(), auth_name.size());
29249  handle_section_bytes += auth_bytes;
29250  command_size += auth_bytes.size();
29251  hash->Update(new_time_bytes.data(), new_time_bytes.size());
29252  parameter_section_bytes += new_time_bytes;
29253  command_size += new_time_bytes.size();
29254  std::string command_hash(32, 0);
29255  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
29256  std::string authorization_section_bytes;
29257  std::string authorization_size_bytes;
29258  if (authorization_delegate) {
29259    if (!authorization_delegate->GetCommandAuthorization(
29260            command_hash, is_command_parameter_encryption_possible,
29261            is_response_parameter_encryption_possible,
29262            &authorization_section_bytes)) {
29263      return TRUNKS_RC_AUTHORIZATION_FAILED;
29264    }
29265    if (!authorization_section_bytes.empty()) {
29266      tag = TPM_ST_SESSIONS;
29267      std::string tmp;
29268      rc = Serialize_UINT32(authorization_section_bytes.size(),
29269                            &authorization_size_bytes);
29270      if (rc != TPM_RC_SUCCESS) {
29271        return rc;
29272      }
29273      command_size +=
29274          authorization_size_bytes.size() + authorization_section_bytes.size();
29275    }
29276  }
29277  std::string tag_bytes;
29278  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29279  if (rc != TPM_RC_SUCCESS) {
29280    return rc;
29281  }
29282  std::string command_size_bytes;
29283  rc = Serialize_UINT32(command_size, &command_size_bytes);
29284  if (rc != TPM_RC_SUCCESS) {
29285    return rc;
29286  }
29287  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29288                        handle_section_bytes + authorization_size_bytes +
29289                        authorization_section_bytes + parameter_section_bytes;
29290  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29291  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
29292                                            serialized_command->size());
29293  return TPM_RC_SUCCESS;
29294}
29295
29296TPM_RC Tpm::ParseResponse_ClockSet(
29297    const std::string& response,
29298    AuthorizationDelegate* authorization_delegate) {
29299  VLOG(3) << __func__;
29300  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29301  TPM_RC rc = TPM_RC_SUCCESS;
29302  std::string buffer(response);
29303  TPM_ST tag;
29304  std::string tag_bytes;
29305  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29306  if (rc != TPM_RC_SUCCESS) {
29307    return rc;
29308  }
29309  UINT32 response_size;
29310  std::string response_size_bytes;
29311  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29312  if (rc != TPM_RC_SUCCESS) {
29313    return rc;
29314  }
29315  TPM_RC response_code;
29316  std::string response_code_bytes;
29317  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29318  if (rc != TPM_RC_SUCCESS) {
29319    return rc;
29320  }
29321  if (response_size != response.size()) {
29322    return TPM_RC_SIZE;
29323  }
29324  if (response_code != TPM_RC_SUCCESS) {
29325    return response_code;
29326  }
29327  TPM_CC command_code = TPM_CC_ClockSet;
29328  std::string command_code_bytes;
29329  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29330  if (rc != TPM_RC_SUCCESS) {
29331    return rc;
29332  }
29333  std::string authorization_section_bytes;
29334  if (tag == TPM_ST_SESSIONS) {
29335    UINT32 parameter_section_size = buffer.size();
29336    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29337    if (rc != TPM_RC_SUCCESS) {
29338      return rc;
29339    }
29340    if (parameter_section_size > buffer.size()) {
29341      return TPM_RC_INSUFFICIENT;
29342    }
29343    authorization_section_bytes = buffer.substr(parameter_section_size);
29344    // Keep the parameter section in |buffer|.
29345    buffer.erase(parameter_section_size);
29346  }
29347  std::unique_ptr<crypto::SecureHash> hash(
29348      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29349  hash->Update(response_code_bytes.data(), response_code_bytes.size());
29350  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29351  hash->Update(buffer.data(), buffer.size());
29352  std::string response_hash(32, 0);
29353  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
29354  if (tag == TPM_ST_SESSIONS) {
29355    CHECK(authorization_delegate) << "Authorization delegate missing!";
29356    if (!authorization_delegate->CheckResponseAuthorization(
29357            response_hash, authorization_section_bytes)) {
29358      return TRUNKS_RC_AUTHORIZATION_FAILED;
29359    }
29360  }
29361  return TPM_RC_SUCCESS;
29362}
29363
29364void ClockSetErrorCallback(const Tpm::ClockSetResponse& callback,
29365                           TPM_RC response_code) {
29366  VLOG(1) << __func__;
29367  callback.Run(response_code);
29368}
29369
29370void ClockSetResponseParser(const Tpm::ClockSetResponse& callback,
29371                            AuthorizationDelegate* authorization_delegate,
29372                            const std::string& response) {
29373  VLOG(1) << __func__;
29374  base::Callback<void(TPM_RC)> error_reporter =
29375      base::Bind(ClockSetErrorCallback, callback);
29376  TPM_RC rc = Tpm::ParseResponse_ClockSet(response, authorization_delegate);
29377  if (rc != TPM_RC_SUCCESS) {
29378    error_reporter.Run(rc);
29379    return;
29380  }
29381  callback.Run(rc);
29382}
29383
29384void Tpm::ClockSet(const TPMI_RH_PROVISION& auth,
29385                   const std::string& auth_name,
29386                   const UINT64& new_time,
29387                   AuthorizationDelegate* authorization_delegate,
29388                   const ClockSetResponse& callback) {
29389  VLOG(1) << __func__;
29390  base::Callback<void(TPM_RC)> error_reporter =
29391      base::Bind(ClockSetErrorCallback, callback);
29392  base::Callback<void(const std::string&)> parser =
29393      base::Bind(ClockSetResponseParser, callback, authorization_delegate);
29394  std::string command;
29395  TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29396                                        authorization_delegate);
29397  if (rc != TPM_RC_SUCCESS) {
29398    error_reporter.Run(rc);
29399    return;
29400  }
29401  transceiver_->SendCommand(command, parser);
29402}
29403
29404TPM_RC Tpm::ClockSetSync(const TPMI_RH_PROVISION& auth,
29405                         const std::string& auth_name,
29406                         const UINT64& new_time,
29407                         AuthorizationDelegate* authorization_delegate) {
29408  VLOG(1) << __func__;
29409  std::string command;
29410  TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29411                                        authorization_delegate);
29412  if (rc != TPM_RC_SUCCESS) {
29413    return rc;
29414  }
29415  std::string response = transceiver_->SendCommandAndWait(command);
29416  rc = ParseResponse_ClockSet(response, authorization_delegate);
29417  return rc;
29418}
29419
29420TPM_RC Tpm::SerializeCommand_ClockRateAdjust(
29421    const TPMI_RH_PROVISION& auth,
29422    const std::string& auth_name,
29423    const TPM_CLOCK_ADJUST& rate_adjust,
29424    std::string* serialized_command,
29425    AuthorizationDelegate* authorization_delegate) {
29426  VLOG(3) << __func__;
29427  TPM_RC rc = TPM_RC_SUCCESS;
29428  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29429  UINT32 command_size = 10;  // Header size.
29430  std::string handle_section_bytes;
29431  std::string parameter_section_bytes;
29432  TPM_CC command_code = TPM_CC_ClockRateAdjust;
29433  bool is_command_parameter_encryption_possible = false;
29434  bool is_response_parameter_encryption_possible = false;
29435  std::string command_code_bytes;
29436  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29437  if (rc != TPM_RC_SUCCESS) {
29438    return rc;
29439  }
29440  std::string auth_bytes;
29441  rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29442  if (rc != TPM_RC_SUCCESS) {
29443    return rc;
29444  }
29445  std::string rate_adjust_bytes;
29446  rc = Serialize_TPM_CLOCK_ADJUST(rate_adjust, &rate_adjust_bytes);
29447  if (rc != TPM_RC_SUCCESS) {
29448    return rc;
29449  }
29450  std::unique_ptr<crypto::SecureHash> hash(
29451      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29452  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29453  hash->Update(auth_name.data(), auth_name.size());
29454  handle_section_bytes += auth_bytes;
29455  command_size += auth_bytes.size();
29456  hash->Update(rate_adjust_bytes.data(), rate_adjust_bytes.size());
29457  parameter_section_bytes += rate_adjust_bytes;
29458  command_size += rate_adjust_bytes.size();
29459  std::string command_hash(32, 0);
29460  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
29461  std::string authorization_section_bytes;
29462  std::string authorization_size_bytes;
29463  if (authorization_delegate) {
29464    if (!authorization_delegate->GetCommandAuthorization(
29465            command_hash, is_command_parameter_encryption_possible,
29466            is_response_parameter_encryption_possible,
29467            &authorization_section_bytes)) {
29468      return TRUNKS_RC_AUTHORIZATION_FAILED;
29469    }
29470    if (!authorization_section_bytes.empty()) {
29471      tag = TPM_ST_SESSIONS;
29472      std::string tmp;
29473      rc = Serialize_UINT32(authorization_section_bytes.size(),
29474                            &authorization_size_bytes);
29475      if (rc != TPM_RC_SUCCESS) {
29476        return rc;
29477      }
29478      command_size +=
29479          authorization_size_bytes.size() + authorization_section_bytes.size();
29480    }
29481  }
29482  std::string tag_bytes;
29483  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29484  if (rc != TPM_RC_SUCCESS) {
29485    return rc;
29486  }
29487  std::string command_size_bytes;
29488  rc = Serialize_UINT32(command_size, &command_size_bytes);
29489  if (rc != TPM_RC_SUCCESS) {
29490    return rc;
29491  }
29492  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29493                        handle_section_bytes + authorization_size_bytes +
29494                        authorization_section_bytes + parameter_section_bytes;
29495  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29496  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
29497                                            serialized_command->size());
29498  return TPM_RC_SUCCESS;
29499}
29500
29501TPM_RC Tpm::ParseResponse_ClockRateAdjust(
29502    const std::string& response,
29503    AuthorizationDelegate* authorization_delegate) {
29504  VLOG(3) << __func__;
29505  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29506  TPM_RC rc = TPM_RC_SUCCESS;
29507  std::string buffer(response);
29508  TPM_ST tag;
29509  std::string tag_bytes;
29510  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29511  if (rc != TPM_RC_SUCCESS) {
29512    return rc;
29513  }
29514  UINT32 response_size;
29515  std::string response_size_bytes;
29516  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29517  if (rc != TPM_RC_SUCCESS) {
29518    return rc;
29519  }
29520  TPM_RC response_code;
29521  std::string response_code_bytes;
29522  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29523  if (rc != TPM_RC_SUCCESS) {
29524    return rc;
29525  }
29526  if (response_size != response.size()) {
29527    return TPM_RC_SIZE;
29528  }
29529  if (response_code != TPM_RC_SUCCESS) {
29530    return response_code;
29531  }
29532  TPM_CC command_code = TPM_CC_ClockRateAdjust;
29533  std::string command_code_bytes;
29534  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29535  if (rc != TPM_RC_SUCCESS) {
29536    return rc;
29537  }
29538  std::string authorization_section_bytes;
29539  if (tag == TPM_ST_SESSIONS) {
29540    UINT32 parameter_section_size = buffer.size();
29541    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29542    if (rc != TPM_RC_SUCCESS) {
29543      return rc;
29544    }
29545    if (parameter_section_size > buffer.size()) {
29546      return TPM_RC_INSUFFICIENT;
29547    }
29548    authorization_section_bytes = buffer.substr(parameter_section_size);
29549    // Keep the parameter section in |buffer|.
29550    buffer.erase(parameter_section_size);
29551  }
29552  std::unique_ptr<crypto::SecureHash> hash(
29553      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29554  hash->Update(response_code_bytes.data(), response_code_bytes.size());
29555  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29556  hash->Update(buffer.data(), buffer.size());
29557  std::string response_hash(32, 0);
29558  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
29559  if (tag == TPM_ST_SESSIONS) {
29560    CHECK(authorization_delegate) << "Authorization delegate missing!";
29561    if (!authorization_delegate->CheckResponseAuthorization(
29562            response_hash, authorization_section_bytes)) {
29563      return TRUNKS_RC_AUTHORIZATION_FAILED;
29564    }
29565  }
29566  return TPM_RC_SUCCESS;
29567}
29568
29569void ClockRateAdjustErrorCallback(const Tpm::ClockRateAdjustResponse& callback,
29570                                  TPM_RC response_code) {
29571  VLOG(1) << __func__;
29572  callback.Run(response_code);
29573}
29574
29575void ClockRateAdjustResponseParser(
29576    const Tpm::ClockRateAdjustResponse& callback,
29577    AuthorizationDelegate* authorization_delegate,
29578    const std::string& response) {
29579  VLOG(1) << __func__;
29580  base::Callback<void(TPM_RC)> error_reporter =
29581      base::Bind(ClockRateAdjustErrorCallback, callback);
29582  TPM_RC rc =
29583      Tpm::ParseResponse_ClockRateAdjust(response, authorization_delegate);
29584  if (rc != TPM_RC_SUCCESS) {
29585    error_reporter.Run(rc);
29586    return;
29587  }
29588  callback.Run(rc);
29589}
29590
29591void Tpm::ClockRateAdjust(const TPMI_RH_PROVISION& auth,
29592                          const std::string& auth_name,
29593                          const TPM_CLOCK_ADJUST& rate_adjust,
29594                          AuthorizationDelegate* authorization_delegate,
29595                          const ClockRateAdjustResponse& callback) {
29596  VLOG(1) << __func__;
29597  base::Callback<void(TPM_RC)> error_reporter =
29598      base::Bind(ClockRateAdjustErrorCallback, callback);
29599  base::Callback<void(const std::string&)> parser = base::Bind(
29600      ClockRateAdjustResponseParser, callback, authorization_delegate);
29601  std::string command;
29602  TPM_RC rc = SerializeCommand_ClockRateAdjust(
29603      auth, auth_name, rate_adjust, &command, authorization_delegate);
29604  if (rc != TPM_RC_SUCCESS) {
29605    error_reporter.Run(rc);
29606    return;
29607  }
29608  transceiver_->SendCommand(command, parser);
29609}
29610
29611TPM_RC Tpm::ClockRateAdjustSync(const TPMI_RH_PROVISION& auth,
29612                                const std::string& auth_name,
29613                                const TPM_CLOCK_ADJUST& rate_adjust,
29614                                AuthorizationDelegate* authorization_delegate) {
29615  VLOG(1) << __func__;
29616  std::string command;
29617  TPM_RC rc = SerializeCommand_ClockRateAdjust(
29618      auth, auth_name, rate_adjust, &command, authorization_delegate);
29619  if (rc != TPM_RC_SUCCESS) {
29620    return rc;
29621  }
29622  std::string response = transceiver_->SendCommandAndWait(command);
29623  rc = ParseResponse_ClockRateAdjust(response, authorization_delegate);
29624  return rc;
29625}
29626
29627TPM_RC Tpm::SerializeCommand_GetCapability(
29628    const TPM_CAP& capability,
29629    const UINT32& property,
29630    const UINT32& property_count,
29631    std::string* serialized_command,
29632    AuthorizationDelegate* authorization_delegate) {
29633  VLOG(3) << __func__;
29634  TPM_RC rc = TPM_RC_SUCCESS;
29635  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29636  UINT32 command_size = 10;  // Header size.
29637  std::string handle_section_bytes;
29638  std::string parameter_section_bytes;
29639  TPM_CC command_code = TPM_CC_GetCapability;
29640  bool is_command_parameter_encryption_possible = false;
29641  bool is_response_parameter_encryption_possible = false;
29642  std::string command_code_bytes;
29643  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29644  if (rc != TPM_RC_SUCCESS) {
29645    return rc;
29646  }
29647  std::string capability_bytes;
29648  rc = Serialize_TPM_CAP(capability, &capability_bytes);
29649  if (rc != TPM_RC_SUCCESS) {
29650    return rc;
29651  }
29652  std::string property_bytes;
29653  rc = Serialize_UINT32(property, &property_bytes);
29654  if (rc != TPM_RC_SUCCESS) {
29655    return rc;
29656  }
29657  std::string property_count_bytes;
29658  rc = Serialize_UINT32(property_count, &property_count_bytes);
29659  if (rc != TPM_RC_SUCCESS) {
29660    return rc;
29661  }
29662  std::unique_ptr<crypto::SecureHash> hash(
29663      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29664  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29665  hash->Update(capability_bytes.data(), capability_bytes.size());
29666  parameter_section_bytes += capability_bytes;
29667  command_size += capability_bytes.size();
29668  hash->Update(property_bytes.data(), property_bytes.size());
29669  parameter_section_bytes += property_bytes;
29670  command_size += property_bytes.size();
29671  hash->Update(property_count_bytes.data(), property_count_bytes.size());
29672  parameter_section_bytes += property_count_bytes;
29673  command_size += property_count_bytes.size();
29674  std::string command_hash(32, 0);
29675  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
29676  std::string authorization_section_bytes;
29677  std::string authorization_size_bytes;
29678  if (authorization_delegate) {
29679    if (!authorization_delegate->GetCommandAuthorization(
29680            command_hash, is_command_parameter_encryption_possible,
29681            is_response_parameter_encryption_possible,
29682            &authorization_section_bytes)) {
29683      return TRUNKS_RC_AUTHORIZATION_FAILED;
29684    }
29685    if (!authorization_section_bytes.empty()) {
29686      tag = TPM_ST_SESSIONS;
29687      std::string tmp;
29688      rc = Serialize_UINT32(authorization_section_bytes.size(),
29689                            &authorization_size_bytes);
29690      if (rc != TPM_RC_SUCCESS) {
29691        return rc;
29692      }
29693      command_size +=
29694          authorization_size_bytes.size() + authorization_section_bytes.size();
29695    }
29696  }
29697  std::string tag_bytes;
29698  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29699  if (rc != TPM_RC_SUCCESS) {
29700    return rc;
29701  }
29702  std::string command_size_bytes;
29703  rc = Serialize_UINT32(command_size, &command_size_bytes);
29704  if (rc != TPM_RC_SUCCESS) {
29705    return rc;
29706  }
29707  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29708                        handle_section_bytes + authorization_size_bytes +
29709                        authorization_section_bytes + parameter_section_bytes;
29710  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29711  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
29712                                            serialized_command->size());
29713  return TPM_RC_SUCCESS;
29714}
29715
29716TPM_RC Tpm::ParseResponse_GetCapability(
29717    const std::string& response,
29718    TPMI_YES_NO* more_data,
29719    TPMS_CAPABILITY_DATA* capability_data,
29720    AuthorizationDelegate* authorization_delegate) {
29721  VLOG(3) << __func__;
29722  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29723  TPM_RC rc = TPM_RC_SUCCESS;
29724  std::string buffer(response);
29725  TPM_ST tag;
29726  std::string tag_bytes;
29727  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29728  if (rc != TPM_RC_SUCCESS) {
29729    return rc;
29730  }
29731  UINT32 response_size;
29732  std::string response_size_bytes;
29733  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29734  if (rc != TPM_RC_SUCCESS) {
29735    return rc;
29736  }
29737  TPM_RC response_code;
29738  std::string response_code_bytes;
29739  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29740  if (rc != TPM_RC_SUCCESS) {
29741    return rc;
29742  }
29743  if (response_size != response.size()) {
29744    return TPM_RC_SIZE;
29745  }
29746  if (response_code != TPM_RC_SUCCESS) {
29747    return response_code;
29748  }
29749  TPM_CC command_code = TPM_CC_GetCapability;
29750  std::string command_code_bytes;
29751  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29752  if (rc != TPM_RC_SUCCESS) {
29753    return rc;
29754  }
29755  std::string authorization_section_bytes;
29756  if (tag == TPM_ST_SESSIONS) {
29757    UINT32 parameter_section_size = buffer.size();
29758    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29759    if (rc != TPM_RC_SUCCESS) {
29760      return rc;
29761    }
29762    if (parameter_section_size > buffer.size()) {
29763      return TPM_RC_INSUFFICIENT;
29764    }
29765    authorization_section_bytes = buffer.substr(parameter_section_size);
29766    // Keep the parameter section in |buffer|.
29767    buffer.erase(parameter_section_size);
29768  }
29769  std::unique_ptr<crypto::SecureHash> hash(
29770      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29771  hash->Update(response_code_bytes.data(), response_code_bytes.size());
29772  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29773  hash->Update(buffer.data(), buffer.size());
29774  std::string response_hash(32, 0);
29775  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
29776  if (tag == TPM_ST_SESSIONS) {
29777    CHECK(authorization_delegate) << "Authorization delegate missing!";
29778    if (!authorization_delegate->CheckResponseAuthorization(
29779            response_hash, authorization_section_bytes)) {
29780      return TRUNKS_RC_AUTHORIZATION_FAILED;
29781    }
29782  }
29783  std::string more_data_bytes;
29784  rc = Parse_TPMI_YES_NO(&buffer, more_data, &more_data_bytes);
29785  if (rc != TPM_RC_SUCCESS) {
29786    return rc;
29787  }
29788  std::string capability_data_bytes;
29789  rc = Parse_TPMS_CAPABILITY_DATA(&buffer, capability_data,
29790                                  &capability_data_bytes);
29791  if (rc != TPM_RC_SUCCESS) {
29792    return rc;
29793  }
29794  return TPM_RC_SUCCESS;
29795}
29796
29797void GetCapabilityErrorCallback(const Tpm::GetCapabilityResponse& callback,
29798                                TPM_RC response_code) {
29799  VLOG(1) << __func__;
29800  callback.Run(response_code, TPMI_YES_NO(), TPMS_CAPABILITY_DATA());
29801}
29802
29803void GetCapabilityResponseParser(const Tpm::GetCapabilityResponse& callback,
29804                                 AuthorizationDelegate* authorization_delegate,
29805                                 const std::string& response) {
29806  VLOG(1) << __func__;
29807  base::Callback<void(TPM_RC)> error_reporter =
29808      base::Bind(GetCapabilityErrorCallback, callback);
29809  TPMI_YES_NO more_data;
29810  TPMS_CAPABILITY_DATA capability_data;
29811  TPM_RC rc = Tpm::ParseResponse_GetCapability(
29812      response, &more_data, &capability_data, authorization_delegate);
29813  if (rc != TPM_RC_SUCCESS) {
29814    error_reporter.Run(rc);
29815    return;
29816  }
29817  callback.Run(rc, more_data, capability_data);
29818}
29819
29820void Tpm::GetCapability(const TPM_CAP& capability,
29821                        const UINT32& property,
29822                        const UINT32& property_count,
29823                        AuthorizationDelegate* authorization_delegate,
29824                        const GetCapabilityResponse& callback) {
29825  VLOG(1) << __func__;
29826  base::Callback<void(TPM_RC)> error_reporter =
29827      base::Bind(GetCapabilityErrorCallback, callback);
29828  base::Callback<void(const std::string&)> parser =
29829      base::Bind(GetCapabilityResponseParser, callback, authorization_delegate);
29830  std::string command;
29831  TPM_RC rc = SerializeCommand_GetCapability(
29832      capability, property, property_count, &command, authorization_delegate);
29833  if (rc != TPM_RC_SUCCESS) {
29834    error_reporter.Run(rc);
29835    return;
29836  }
29837  transceiver_->SendCommand(command, parser);
29838}
29839
29840TPM_RC Tpm::GetCapabilitySync(const TPM_CAP& capability,
29841                              const UINT32& property,
29842                              const UINT32& property_count,
29843                              TPMI_YES_NO* more_data,
29844                              TPMS_CAPABILITY_DATA* capability_data,
29845                              AuthorizationDelegate* authorization_delegate) {
29846  VLOG(1) << __func__;
29847  std::string command;
29848  TPM_RC rc = SerializeCommand_GetCapability(
29849      capability, property, property_count, &command, authorization_delegate);
29850  if (rc != TPM_RC_SUCCESS) {
29851    return rc;
29852  }
29853  std::string response = transceiver_->SendCommandAndWait(command);
29854  rc = ParseResponse_GetCapability(response, more_data, capability_data,
29855                                   authorization_delegate);
29856  return rc;
29857}
29858
29859TPM_RC Tpm::SerializeCommand_TestParms(
29860    const TPMT_PUBLIC_PARMS& parameters,
29861    std::string* serialized_command,
29862    AuthorizationDelegate* authorization_delegate) {
29863  VLOG(3) << __func__;
29864  TPM_RC rc = TPM_RC_SUCCESS;
29865  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29866  UINT32 command_size = 10;  // Header size.
29867  std::string handle_section_bytes;
29868  std::string parameter_section_bytes;
29869  TPM_CC command_code = TPM_CC_TestParms;
29870  bool is_command_parameter_encryption_possible = false;
29871  bool is_response_parameter_encryption_possible = false;
29872  std::string command_code_bytes;
29873  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29874  if (rc != TPM_RC_SUCCESS) {
29875    return rc;
29876  }
29877  std::string parameters_bytes;
29878  rc = Serialize_TPMT_PUBLIC_PARMS(parameters, &parameters_bytes);
29879  if (rc != TPM_RC_SUCCESS) {
29880    return rc;
29881  }
29882  std::unique_ptr<crypto::SecureHash> hash(
29883      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29884  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29885  hash->Update(parameters_bytes.data(), parameters_bytes.size());
29886  parameter_section_bytes += parameters_bytes;
29887  command_size += parameters_bytes.size();
29888  std::string command_hash(32, 0);
29889  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
29890  std::string authorization_section_bytes;
29891  std::string authorization_size_bytes;
29892  if (authorization_delegate) {
29893    if (!authorization_delegate->GetCommandAuthorization(
29894            command_hash, is_command_parameter_encryption_possible,
29895            is_response_parameter_encryption_possible,
29896            &authorization_section_bytes)) {
29897      return TRUNKS_RC_AUTHORIZATION_FAILED;
29898    }
29899    if (!authorization_section_bytes.empty()) {
29900      tag = TPM_ST_SESSIONS;
29901      std::string tmp;
29902      rc = Serialize_UINT32(authorization_section_bytes.size(),
29903                            &authorization_size_bytes);
29904      if (rc != TPM_RC_SUCCESS) {
29905        return rc;
29906      }
29907      command_size +=
29908          authorization_size_bytes.size() + authorization_section_bytes.size();
29909    }
29910  }
29911  std::string tag_bytes;
29912  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29913  if (rc != TPM_RC_SUCCESS) {
29914    return rc;
29915  }
29916  std::string command_size_bytes;
29917  rc = Serialize_UINT32(command_size, &command_size_bytes);
29918  if (rc != TPM_RC_SUCCESS) {
29919    return rc;
29920  }
29921  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29922                        handle_section_bytes + authorization_size_bytes +
29923                        authorization_section_bytes + parameter_section_bytes;
29924  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29925  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
29926                                            serialized_command->size());
29927  return TPM_RC_SUCCESS;
29928}
29929
29930TPM_RC Tpm::ParseResponse_TestParms(
29931    const std::string& response,
29932    AuthorizationDelegate* authorization_delegate) {
29933  VLOG(3) << __func__;
29934  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29935  TPM_RC rc = TPM_RC_SUCCESS;
29936  std::string buffer(response);
29937  TPM_ST tag;
29938  std::string tag_bytes;
29939  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29940  if (rc != TPM_RC_SUCCESS) {
29941    return rc;
29942  }
29943  UINT32 response_size;
29944  std::string response_size_bytes;
29945  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29946  if (rc != TPM_RC_SUCCESS) {
29947    return rc;
29948  }
29949  TPM_RC response_code;
29950  std::string response_code_bytes;
29951  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29952  if (rc != TPM_RC_SUCCESS) {
29953    return rc;
29954  }
29955  if (response_size != response.size()) {
29956    return TPM_RC_SIZE;
29957  }
29958  if (response_code != TPM_RC_SUCCESS) {
29959    return response_code;
29960  }
29961  TPM_CC command_code = TPM_CC_TestParms;
29962  std::string command_code_bytes;
29963  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29964  if (rc != TPM_RC_SUCCESS) {
29965    return rc;
29966  }
29967  std::string authorization_section_bytes;
29968  if (tag == TPM_ST_SESSIONS) {
29969    UINT32 parameter_section_size = buffer.size();
29970    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29971    if (rc != TPM_RC_SUCCESS) {
29972      return rc;
29973    }
29974    if (parameter_section_size > buffer.size()) {
29975      return TPM_RC_INSUFFICIENT;
29976    }
29977    authorization_section_bytes = buffer.substr(parameter_section_size);
29978    // Keep the parameter section in |buffer|.
29979    buffer.erase(parameter_section_size);
29980  }
29981  std::unique_ptr<crypto::SecureHash> hash(
29982      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29983  hash->Update(response_code_bytes.data(), response_code_bytes.size());
29984  hash->Update(command_code_bytes.data(), command_code_bytes.size());
29985  hash->Update(buffer.data(), buffer.size());
29986  std::string response_hash(32, 0);
29987  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
29988  if (tag == TPM_ST_SESSIONS) {
29989    CHECK(authorization_delegate) << "Authorization delegate missing!";
29990    if (!authorization_delegate->CheckResponseAuthorization(
29991            response_hash, authorization_section_bytes)) {
29992      return TRUNKS_RC_AUTHORIZATION_FAILED;
29993    }
29994  }
29995  return TPM_RC_SUCCESS;
29996}
29997
29998void TestParmsErrorCallback(const Tpm::TestParmsResponse& callback,
29999                            TPM_RC response_code) {
30000  VLOG(1) << __func__;
30001  callback.Run(response_code);
30002}
30003
30004void TestParmsResponseParser(const Tpm::TestParmsResponse& callback,
30005                             AuthorizationDelegate* authorization_delegate,
30006                             const std::string& response) {
30007  VLOG(1) << __func__;
30008  base::Callback<void(TPM_RC)> error_reporter =
30009      base::Bind(TestParmsErrorCallback, callback);
30010  TPM_RC rc = Tpm::ParseResponse_TestParms(response, authorization_delegate);
30011  if (rc != TPM_RC_SUCCESS) {
30012    error_reporter.Run(rc);
30013    return;
30014  }
30015  callback.Run(rc);
30016}
30017
30018void Tpm::TestParms(const TPMT_PUBLIC_PARMS& parameters,
30019                    AuthorizationDelegate* authorization_delegate,
30020                    const TestParmsResponse& callback) {
30021  VLOG(1) << __func__;
30022  base::Callback<void(TPM_RC)> error_reporter =
30023      base::Bind(TestParmsErrorCallback, callback);
30024  base::Callback<void(const std::string&)> parser =
30025      base::Bind(TestParmsResponseParser, callback, authorization_delegate);
30026  std::string command;
30027  TPM_RC rc =
30028      SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30029  if (rc != TPM_RC_SUCCESS) {
30030    error_reporter.Run(rc);
30031    return;
30032  }
30033  transceiver_->SendCommand(command, parser);
30034}
30035
30036TPM_RC Tpm::TestParmsSync(const TPMT_PUBLIC_PARMS& parameters,
30037                          AuthorizationDelegate* authorization_delegate) {
30038  VLOG(1) << __func__;
30039  std::string command;
30040  TPM_RC rc =
30041      SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30042  if (rc != TPM_RC_SUCCESS) {
30043    return rc;
30044  }
30045  std::string response = transceiver_->SendCommandAndWait(command);
30046  rc = ParseResponse_TestParms(response, authorization_delegate);
30047  return rc;
30048}
30049
30050TPM_RC Tpm::SerializeCommand_NV_DefineSpace(
30051    const TPMI_RH_PROVISION& auth_handle,
30052    const std::string& auth_handle_name,
30053    const TPM2B_AUTH& auth,
30054    const TPM2B_NV_PUBLIC& public_info,
30055    std::string* serialized_command,
30056    AuthorizationDelegate* authorization_delegate) {
30057  VLOG(3) << __func__;
30058  TPM_RC rc = TPM_RC_SUCCESS;
30059  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30060  UINT32 command_size = 10;  // Header size.
30061  std::string handle_section_bytes;
30062  std::string parameter_section_bytes;
30063  TPM_CC command_code = TPM_CC_NV_DefineSpace;
30064  bool is_command_parameter_encryption_possible = true;
30065  bool is_response_parameter_encryption_possible = false;
30066  std::string command_code_bytes;
30067  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30068  if (rc != TPM_RC_SUCCESS) {
30069    return rc;
30070  }
30071  std::string auth_handle_bytes;
30072  rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30073  if (rc != TPM_RC_SUCCESS) {
30074    return rc;
30075  }
30076  std::string auth_bytes;
30077  rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
30078  if (rc != TPM_RC_SUCCESS) {
30079    return rc;
30080  }
30081  std::string public_info_bytes;
30082  rc = Serialize_TPM2B_NV_PUBLIC(public_info, &public_info_bytes);
30083  if (rc != TPM_RC_SUCCESS) {
30084    return rc;
30085  }
30086  if (authorization_delegate) {
30087    // Encrypt just the parameter data, not the size.
30088    std::string tmp = auth_bytes.substr(2);
30089    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30090      return TRUNKS_RC_ENCRYPTION_FAILED;
30091    }
30092    auth_bytes.replace(2, std::string::npos, tmp);
30093  }
30094  std::unique_ptr<crypto::SecureHash> hash(
30095      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30096  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30097  hash->Update(auth_handle_name.data(), auth_handle_name.size());
30098  handle_section_bytes += auth_handle_bytes;
30099  command_size += auth_handle_bytes.size();
30100  hash->Update(auth_bytes.data(), auth_bytes.size());
30101  parameter_section_bytes += auth_bytes;
30102  command_size += auth_bytes.size();
30103  hash->Update(public_info_bytes.data(), public_info_bytes.size());
30104  parameter_section_bytes += public_info_bytes;
30105  command_size += public_info_bytes.size();
30106  std::string command_hash(32, 0);
30107  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
30108  std::string authorization_section_bytes;
30109  std::string authorization_size_bytes;
30110  if (authorization_delegate) {
30111    if (!authorization_delegate->GetCommandAuthorization(
30112            command_hash, is_command_parameter_encryption_possible,
30113            is_response_parameter_encryption_possible,
30114            &authorization_section_bytes)) {
30115      return TRUNKS_RC_AUTHORIZATION_FAILED;
30116    }
30117    if (!authorization_section_bytes.empty()) {
30118      tag = TPM_ST_SESSIONS;
30119      std::string tmp;
30120      rc = Serialize_UINT32(authorization_section_bytes.size(),
30121                            &authorization_size_bytes);
30122      if (rc != TPM_RC_SUCCESS) {
30123        return rc;
30124      }
30125      command_size +=
30126          authorization_size_bytes.size() + authorization_section_bytes.size();
30127    }
30128  }
30129  std::string tag_bytes;
30130  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30131  if (rc != TPM_RC_SUCCESS) {
30132    return rc;
30133  }
30134  std::string command_size_bytes;
30135  rc = Serialize_UINT32(command_size, &command_size_bytes);
30136  if (rc != TPM_RC_SUCCESS) {
30137    return rc;
30138  }
30139  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30140                        handle_section_bytes + authorization_size_bytes +
30141                        authorization_section_bytes + parameter_section_bytes;
30142  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30143  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
30144                                            serialized_command->size());
30145  return TPM_RC_SUCCESS;
30146}
30147
30148TPM_RC Tpm::ParseResponse_NV_DefineSpace(
30149    const std::string& response,
30150    AuthorizationDelegate* authorization_delegate) {
30151  VLOG(3) << __func__;
30152  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30153  TPM_RC rc = TPM_RC_SUCCESS;
30154  std::string buffer(response);
30155  TPM_ST tag;
30156  std::string tag_bytes;
30157  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30158  if (rc != TPM_RC_SUCCESS) {
30159    return rc;
30160  }
30161  UINT32 response_size;
30162  std::string response_size_bytes;
30163  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30164  if (rc != TPM_RC_SUCCESS) {
30165    return rc;
30166  }
30167  TPM_RC response_code;
30168  std::string response_code_bytes;
30169  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30170  if (rc != TPM_RC_SUCCESS) {
30171    return rc;
30172  }
30173  if (response_size != response.size()) {
30174    return TPM_RC_SIZE;
30175  }
30176  if (response_code != TPM_RC_SUCCESS) {
30177    return response_code;
30178  }
30179  TPM_CC command_code = TPM_CC_NV_DefineSpace;
30180  std::string command_code_bytes;
30181  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30182  if (rc != TPM_RC_SUCCESS) {
30183    return rc;
30184  }
30185  std::string authorization_section_bytes;
30186  if (tag == TPM_ST_SESSIONS) {
30187    UINT32 parameter_section_size = buffer.size();
30188    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30189    if (rc != TPM_RC_SUCCESS) {
30190      return rc;
30191    }
30192    if (parameter_section_size > buffer.size()) {
30193      return TPM_RC_INSUFFICIENT;
30194    }
30195    authorization_section_bytes = buffer.substr(parameter_section_size);
30196    // Keep the parameter section in |buffer|.
30197    buffer.erase(parameter_section_size);
30198  }
30199  std::unique_ptr<crypto::SecureHash> hash(
30200      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30201  hash->Update(response_code_bytes.data(), response_code_bytes.size());
30202  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30203  hash->Update(buffer.data(), buffer.size());
30204  std::string response_hash(32, 0);
30205  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
30206  if (tag == TPM_ST_SESSIONS) {
30207    CHECK(authorization_delegate) << "Authorization delegate missing!";
30208    if (!authorization_delegate->CheckResponseAuthorization(
30209            response_hash, authorization_section_bytes)) {
30210      return TRUNKS_RC_AUTHORIZATION_FAILED;
30211    }
30212  }
30213  return TPM_RC_SUCCESS;
30214}
30215
30216void NV_DefineSpaceErrorCallback(const Tpm::NV_DefineSpaceResponse& callback,
30217                                 TPM_RC response_code) {
30218  VLOG(1) << __func__;
30219  callback.Run(response_code);
30220}
30221
30222void NV_DefineSpaceResponseParser(const Tpm::NV_DefineSpaceResponse& callback,
30223                                  AuthorizationDelegate* authorization_delegate,
30224                                  const std::string& response) {
30225  VLOG(1) << __func__;
30226  base::Callback<void(TPM_RC)> error_reporter =
30227      base::Bind(NV_DefineSpaceErrorCallback, callback);
30228  TPM_RC rc =
30229      Tpm::ParseResponse_NV_DefineSpace(response, authorization_delegate);
30230  if (rc != TPM_RC_SUCCESS) {
30231    error_reporter.Run(rc);
30232    return;
30233  }
30234  callback.Run(rc);
30235}
30236
30237void Tpm::NV_DefineSpace(const TPMI_RH_PROVISION& auth_handle,
30238                         const std::string& auth_handle_name,
30239                         const TPM2B_AUTH& auth,
30240                         const TPM2B_NV_PUBLIC& public_info,
30241                         AuthorizationDelegate* authorization_delegate,
30242                         const NV_DefineSpaceResponse& callback) {
30243  VLOG(1) << __func__;
30244  base::Callback<void(TPM_RC)> error_reporter =
30245      base::Bind(NV_DefineSpaceErrorCallback, callback);
30246  base::Callback<void(const std::string&)> parser = base::Bind(
30247      NV_DefineSpaceResponseParser, callback, authorization_delegate);
30248  std::string command;
30249  TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30250                                              auth, public_info, &command,
30251                                              authorization_delegate);
30252  if (rc != TPM_RC_SUCCESS) {
30253    error_reporter.Run(rc);
30254    return;
30255  }
30256  transceiver_->SendCommand(command, parser);
30257}
30258
30259TPM_RC Tpm::NV_DefineSpaceSync(const TPMI_RH_PROVISION& auth_handle,
30260                               const std::string& auth_handle_name,
30261                               const TPM2B_AUTH& auth,
30262                               const TPM2B_NV_PUBLIC& public_info,
30263                               AuthorizationDelegate* authorization_delegate) {
30264  VLOG(1) << __func__;
30265  std::string command;
30266  TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30267                                              auth, public_info, &command,
30268                                              authorization_delegate);
30269  if (rc != TPM_RC_SUCCESS) {
30270    return rc;
30271  }
30272  std::string response = transceiver_->SendCommandAndWait(command);
30273  rc = ParseResponse_NV_DefineSpace(response, authorization_delegate);
30274  return rc;
30275}
30276
30277TPM_RC Tpm::SerializeCommand_NV_UndefineSpace(
30278    const TPMI_RH_PROVISION& auth_handle,
30279    const std::string& auth_handle_name,
30280    const TPMI_RH_NV_INDEX& nv_index,
30281    const std::string& nv_index_name,
30282    std::string* serialized_command,
30283    AuthorizationDelegate* authorization_delegate) {
30284  VLOG(3) << __func__;
30285  TPM_RC rc = TPM_RC_SUCCESS;
30286  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30287  UINT32 command_size = 10;  // Header size.
30288  std::string handle_section_bytes;
30289  std::string parameter_section_bytes;
30290  TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30291  bool is_command_parameter_encryption_possible = false;
30292  bool is_response_parameter_encryption_possible = false;
30293  std::string command_code_bytes;
30294  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30295  if (rc != TPM_RC_SUCCESS) {
30296    return rc;
30297  }
30298  std::string auth_handle_bytes;
30299  rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30300  if (rc != TPM_RC_SUCCESS) {
30301    return rc;
30302  }
30303  std::string nv_index_bytes;
30304  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30305  if (rc != TPM_RC_SUCCESS) {
30306    return rc;
30307  }
30308  std::unique_ptr<crypto::SecureHash> hash(
30309      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30310  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30311  hash->Update(auth_handle_name.data(), auth_handle_name.size());
30312  handle_section_bytes += auth_handle_bytes;
30313  command_size += auth_handle_bytes.size();
30314  hash->Update(nv_index_name.data(), nv_index_name.size());
30315  handle_section_bytes += nv_index_bytes;
30316  command_size += nv_index_bytes.size();
30317  std::string command_hash(32, 0);
30318  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
30319  std::string authorization_section_bytes;
30320  std::string authorization_size_bytes;
30321  if (authorization_delegate) {
30322    if (!authorization_delegate->GetCommandAuthorization(
30323            command_hash, is_command_parameter_encryption_possible,
30324            is_response_parameter_encryption_possible,
30325            &authorization_section_bytes)) {
30326      return TRUNKS_RC_AUTHORIZATION_FAILED;
30327    }
30328    if (!authorization_section_bytes.empty()) {
30329      tag = TPM_ST_SESSIONS;
30330      std::string tmp;
30331      rc = Serialize_UINT32(authorization_section_bytes.size(),
30332                            &authorization_size_bytes);
30333      if (rc != TPM_RC_SUCCESS) {
30334        return rc;
30335      }
30336      command_size +=
30337          authorization_size_bytes.size() + authorization_section_bytes.size();
30338    }
30339  }
30340  std::string tag_bytes;
30341  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30342  if (rc != TPM_RC_SUCCESS) {
30343    return rc;
30344  }
30345  std::string command_size_bytes;
30346  rc = Serialize_UINT32(command_size, &command_size_bytes);
30347  if (rc != TPM_RC_SUCCESS) {
30348    return rc;
30349  }
30350  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30351                        handle_section_bytes + authorization_size_bytes +
30352                        authorization_section_bytes + parameter_section_bytes;
30353  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30354  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
30355                                            serialized_command->size());
30356  return TPM_RC_SUCCESS;
30357}
30358
30359TPM_RC Tpm::ParseResponse_NV_UndefineSpace(
30360    const std::string& response,
30361    AuthorizationDelegate* authorization_delegate) {
30362  VLOG(3) << __func__;
30363  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30364  TPM_RC rc = TPM_RC_SUCCESS;
30365  std::string buffer(response);
30366  TPM_ST tag;
30367  std::string tag_bytes;
30368  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30369  if (rc != TPM_RC_SUCCESS) {
30370    return rc;
30371  }
30372  UINT32 response_size;
30373  std::string response_size_bytes;
30374  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30375  if (rc != TPM_RC_SUCCESS) {
30376    return rc;
30377  }
30378  TPM_RC response_code;
30379  std::string response_code_bytes;
30380  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30381  if (rc != TPM_RC_SUCCESS) {
30382    return rc;
30383  }
30384  if (response_size != response.size()) {
30385    return TPM_RC_SIZE;
30386  }
30387  if (response_code != TPM_RC_SUCCESS) {
30388    return response_code;
30389  }
30390  TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30391  std::string command_code_bytes;
30392  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30393  if (rc != TPM_RC_SUCCESS) {
30394    return rc;
30395  }
30396  std::string authorization_section_bytes;
30397  if (tag == TPM_ST_SESSIONS) {
30398    UINT32 parameter_section_size = buffer.size();
30399    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30400    if (rc != TPM_RC_SUCCESS) {
30401      return rc;
30402    }
30403    if (parameter_section_size > buffer.size()) {
30404      return TPM_RC_INSUFFICIENT;
30405    }
30406    authorization_section_bytes = buffer.substr(parameter_section_size);
30407    // Keep the parameter section in |buffer|.
30408    buffer.erase(parameter_section_size);
30409  }
30410  std::unique_ptr<crypto::SecureHash> hash(
30411      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30412  hash->Update(response_code_bytes.data(), response_code_bytes.size());
30413  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30414  hash->Update(buffer.data(), buffer.size());
30415  std::string response_hash(32, 0);
30416  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
30417  if (tag == TPM_ST_SESSIONS) {
30418    CHECK(authorization_delegate) << "Authorization delegate missing!";
30419    if (!authorization_delegate->CheckResponseAuthorization(
30420            response_hash, authorization_section_bytes)) {
30421      return TRUNKS_RC_AUTHORIZATION_FAILED;
30422    }
30423  }
30424  return TPM_RC_SUCCESS;
30425}
30426
30427void NV_UndefineSpaceErrorCallback(
30428    const Tpm::NV_UndefineSpaceResponse& callback,
30429    TPM_RC response_code) {
30430  VLOG(1) << __func__;
30431  callback.Run(response_code);
30432}
30433
30434void NV_UndefineSpaceResponseParser(
30435    const Tpm::NV_UndefineSpaceResponse& callback,
30436    AuthorizationDelegate* authorization_delegate,
30437    const std::string& response) {
30438  VLOG(1) << __func__;
30439  base::Callback<void(TPM_RC)> error_reporter =
30440      base::Bind(NV_UndefineSpaceErrorCallback, callback);
30441  TPM_RC rc =
30442      Tpm::ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30443  if (rc != TPM_RC_SUCCESS) {
30444    error_reporter.Run(rc);
30445    return;
30446  }
30447  callback.Run(rc);
30448}
30449
30450void Tpm::NV_UndefineSpace(const TPMI_RH_PROVISION& auth_handle,
30451                           const std::string& auth_handle_name,
30452                           const TPMI_RH_NV_INDEX& nv_index,
30453                           const std::string& nv_index_name,
30454                           AuthorizationDelegate* authorization_delegate,
30455                           const NV_UndefineSpaceResponse& callback) {
30456  VLOG(1) << __func__;
30457  base::Callback<void(TPM_RC)> error_reporter =
30458      base::Bind(NV_UndefineSpaceErrorCallback, callback);
30459  base::Callback<void(const std::string&)> parser = base::Bind(
30460      NV_UndefineSpaceResponseParser, callback, authorization_delegate);
30461  std::string command;
30462  TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30463      auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30464      authorization_delegate);
30465  if (rc != TPM_RC_SUCCESS) {
30466    error_reporter.Run(rc);
30467    return;
30468  }
30469  transceiver_->SendCommand(command, parser);
30470}
30471
30472TPM_RC Tpm::NV_UndefineSpaceSync(
30473    const TPMI_RH_PROVISION& auth_handle,
30474    const std::string& auth_handle_name,
30475    const TPMI_RH_NV_INDEX& nv_index,
30476    const std::string& nv_index_name,
30477    AuthorizationDelegate* authorization_delegate) {
30478  VLOG(1) << __func__;
30479  std::string command;
30480  TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30481      auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30482      authorization_delegate);
30483  if (rc != TPM_RC_SUCCESS) {
30484    return rc;
30485  }
30486  std::string response = transceiver_->SendCommandAndWait(command);
30487  rc = ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30488  return rc;
30489}
30490
30491TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial(
30492    const TPMI_RH_NV_INDEX& nv_index,
30493    const std::string& nv_index_name,
30494    const TPMI_RH_PLATFORM& platform,
30495    const std::string& platform_name,
30496    std::string* serialized_command,
30497    AuthorizationDelegate* authorization_delegate) {
30498  VLOG(3) << __func__;
30499  TPM_RC rc = TPM_RC_SUCCESS;
30500  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30501  UINT32 command_size = 10;  // Header size.
30502  std::string handle_section_bytes;
30503  std::string parameter_section_bytes;
30504  TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30505  bool is_command_parameter_encryption_possible = false;
30506  bool is_response_parameter_encryption_possible = false;
30507  std::string command_code_bytes;
30508  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30509  if (rc != TPM_RC_SUCCESS) {
30510    return rc;
30511  }
30512  std::string nv_index_bytes;
30513  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30514  if (rc != TPM_RC_SUCCESS) {
30515    return rc;
30516  }
30517  std::string platform_bytes;
30518  rc = Serialize_TPMI_RH_PLATFORM(platform, &platform_bytes);
30519  if (rc != TPM_RC_SUCCESS) {
30520    return rc;
30521  }
30522  std::unique_ptr<crypto::SecureHash> hash(
30523      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30524  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30525  hash->Update(nv_index_name.data(), nv_index_name.size());
30526  handle_section_bytes += nv_index_bytes;
30527  command_size += nv_index_bytes.size();
30528  hash->Update(platform_name.data(), platform_name.size());
30529  handle_section_bytes += platform_bytes;
30530  command_size += platform_bytes.size();
30531  std::string command_hash(32, 0);
30532  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
30533  std::string authorization_section_bytes;
30534  std::string authorization_size_bytes;
30535  if (authorization_delegate) {
30536    if (!authorization_delegate->GetCommandAuthorization(
30537            command_hash, is_command_parameter_encryption_possible,
30538            is_response_parameter_encryption_possible,
30539            &authorization_section_bytes)) {
30540      return TRUNKS_RC_AUTHORIZATION_FAILED;
30541    }
30542    if (!authorization_section_bytes.empty()) {
30543      tag = TPM_ST_SESSIONS;
30544      std::string tmp;
30545      rc = Serialize_UINT32(authorization_section_bytes.size(),
30546                            &authorization_size_bytes);
30547      if (rc != TPM_RC_SUCCESS) {
30548        return rc;
30549      }
30550      command_size +=
30551          authorization_size_bytes.size() + authorization_section_bytes.size();
30552    }
30553  }
30554  std::string tag_bytes;
30555  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30556  if (rc != TPM_RC_SUCCESS) {
30557    return rc;
30558  }
30559  std::string command_size_bytes;
30560  rc = Serialize_UINT32(command_size, &command_size_bytes);
30561  if (rc != TPM_RC_SUCCESS) {
30562    return rc;
30563  }
30564  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30565                        handle_section_bytes + authorization_size_bytes +
30566                        authorization_section_bytes + parameter_section_bytes;
30567  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30568  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
30569                                            serialized_command->size());
30570  return TPM_RC_SUCCESS;
30571}
30572
30573TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial(
30574    const std::string& response,
30575    AuthorizationDelegate* authorization_delegate) {
30576  VLOG(3) << __func__;
30577  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30578  TPM_RC rc = TPM_RC_SUCCESS;
30579  std::string buffer(response);
30580  TPM_ST tag;
30581  std::string tag_bytes;
30582  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30583  if (rc != TPM_RC_SUCCESS) {
30584    return rc;
30585  }
30586  UINT32 response_size;
30587  std::string response_size_bytes;
30588  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30589  if (rc != TPM_RC_SUCCESS) {
30590    return rc;
30591  }
30592  TPM_RC response_code;
30593  std::string response_code_bytes;
30594  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30595  if (rc != TPM_RC_SUCCESS) {
30596    return rc;
30597  }
30598  if (response_size != response.size()) {
30599    return TPM_RC_SIZE;
30600  }
30601  if (response_code != TPM_RC_SUCCESS) {
30602    return response_code;
30603  }
30604  TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30605  std::string command_code_bytes;
30606  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30607  if (rc != TPM_RC_SUCCESS) {
30608    return rc;
30609  }
30610  std::string authorization_section_bytes;
30611  if (tag == TPM_ST_SESSIONS) {
30612    UINT32 parameter_section_size = buffer.size();
30613    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30614    if (rc != TPM_RC_SUCCESS) {
30615      return rc;
30616    }
30617    if (parameter_section_size > buffer.size()) {
30618      return TPM_RC_INSUFFICIENT;
30619    }
30620    authorization_section_bytes = buffer.substr(parameter_section_size);
30621    // Keep the parameter section in |buffer|.
30622    buffer.erase(parameter_section_size);
30623  }
30624  std::unique_ptr<crypto::SecureHash> hash(
30625      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30626  hash->Update(response_code_bytes.data(), response_code_bytes.size());
30627  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30628  hash->Update(buffer.data(), buffer.size());
30629  std::string response_hash(32, 0);
30630  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
30631  if (tag == TPM_ST_SESSIONS) {
30632    CHECK(authorization_delegate) << "Authorization delegate missing!";
30633    if (!authorization_delegate->CheckResponseAuthorization(
30634            response_hash, authorization_section_bytes)) {
30635      return TRUNKS_RC_AUTHORIZATION_FAILED;
30636    }
30637  }
30638  return TPM_RC_SUCCESS;
30639}
30640
30641void NV_UndefineSpaceSpecialErrorCallback(
30642    const Tpm::NV_UndefineSpaceSpecialResponse& callback,
30643    TPM_RC response_code) {
30644  VLOG(1) << __func__;
30645  callback.Run(response_code);
30646}
30647
30648void NV_UndefineSpaceSpecialResponseParser(
30649    const Tpm::NV_UndefineSpaceSpecialResponse& callback,
30650    AuthorizationDelegate* authorization_delegate,
30651    const std::string& response) {
30652  VLOG(1) << __func__;
30653  base::Callback<void(TPM_RC)> error_reporter =
30654      base::Bind(NV_UndefineSpaceSpecialErrorCallback, callback);
30655  TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial(
30656      response, authorization_delegate);
30657  if (rc != TPM_RC_SUCCESS) {
30658    error_reporter.Run(rc);
30659    return;
30660  }
30661  callback.Run(rc);
30662}
30663
30664void Tpm::NV_UndefineSpaceSpecial(
30665    const TPMI_RH_NV_INDEX& nv_index,
30666    const std::string& nv_index_name,
30667    const TPMI_RH_PLATFORM& platform,
30668    const std::string& platform_name,
30669    AuthorizationDelegate* authorization_delegate,
30670    const NV_UndefineSpaceSpecialResponse& callback) {
30671  VLOG(1) << __func__;
30672  base::Callback<void(TPM_RC)> error_reporter =
30673      base::Bind(NV_UndefineSpaceSpecialErrorCallback, callback);
30674  base::Callback<void(const std::string&)> parser = base::Bind(
30675      NV_UndefineSpaceSpecialResponseParser, callback, authorization_delegate);
30676  std::string command;
30677  TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
30678      nv_index, nv_index_name, platform, platform_name, &command,
30679      authorization_delegate);
30680  if (rc != TPM_RC_SUCCESS) {
30681    error_reporter.Run(rc);
30682    return;
30683  }
30684  transceiver_->SendCommand(command, parser);
30685}
30686
30687TPM_RC Tpm::NV_UndefineSpaceSpecialSync(
30688    const TPMI_RH_NV_INDEX& nv_index,
30689    const std::string& nv_index_name,
30690    const TPMI_RH_PLATFORM& platform,
30691    const std::string& platform_name,
30692    AuthorizationDelegate* authorization_delegate) {
30693  VLOG(1) << __func__;
30694  std::string command;
30695  TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
30696      nv_index, nv_index_name, platform, platform_name, &command,
30697      authorization_delegate);
30698  if (rc != TPM_RC_SUCCESS) {
30699    return rc;
30700  }
30701  std::string response = transceiver_->SendCommandAndWait(command);
30702  rc = ParseResponse_NV_UndefineSpaceSpecial(response, authorization_delegate);
30703  return rc;
30704}
30705
30706TPM_RC Tpm::SerializeCommand_NV_ReadPublic(
30707    const TPMI_RH_NV_INDEX& nv_index,
30708    const std::string& nv_index_name,
30709    std::string* serialized_command,
30710    AuthorizationDelegate* authorization_delegate) {
30711  VLOG(3) << __func__;
30712  TPM_RC rc = TPM_RC_SUCCESS;
30713  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30714  UINT32 command_size = 10;  // Header size.
30715  std::string handle_section_bytes;
30716  std::string parameter_section_bytes;
30717  TPM_CC command_code = TPM_CC_NV_ReadPublic;
30718  bool is_command_parameter_encryption_possible = false;
30719  bool is_response_parameter_encryption_possible = true;
30720  std::string command_code_bytes;
30721  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30722  if (rc != TPM_RC_SUCCESS) {
30723    return rc;
30724  }
30725  std::string nv_index_bytes;
30726  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30727  if (rc != TPM_RC_SUCCESS) {
30728    return rc;
30729  }
30730  std::unique_ptr<crypto::SecureHash> hash(
30731      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30732  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30733  hash->Update(nv_index_name.data(), nv_index_name.size());
30734  handle_section_bytes += nv_index_bytes;
30735  command_size += nv_index_bytes.size();
30736  std::string command_hash(32, 0);
30737  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
30738  std::string authorization_section_bytes;
30739  std::string authorization_size_bytes;
30740  if (authorization_delegate) {
30741    if (!authorization_delegate->GetCommandAuthorization(
30742            command_hash, is_command_parameter_encryption_possible,
30743            is_response_parameter_encryption_possible,
30744            &authorization_section_bytes)) {
30745      return TRUNKS_RC_AUTHORIZATION_FAILED;
30746    }
30747    if (!authorization_section_bytes.empty()) {
30748      tag = TPM_ST_SESSIONS;
30749      std::string tmp;
30750      rc = Serialize_UINT32(authorization_section_bytes.size(),
30751                            &authorization_size_bytes);
30752      if (rc != TPM_RC_SUCCESS) {
30753        return rc;
30754      }
30755      command_size +=
30756          authorization_size_bytes.size() + authorization_section_bytes.size();
30757    }
30758  }
30759  std::string tag_bytes;
30760  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30761  if (rc != TPM_RC_SUCCESS) {
30762    return rc;
30763  }
30764  std::string command_size_bytes;
30765  rc = Serialize_UINT32(command_size, &command_size_bytes);
30766  if (rc != TPM_RC_SUCCESS) {
30767    return rc;
30768  }
30769  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30770                        handle_section_bytes + authorization_size_bytes +
30771                        authorization_section_bytes + parameter_section_bytes;
30772  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30773  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
30774                                            serialized_command->size());
30775  return TPM_RC_SUCCESS;
30776}
30777
30778TPM_RC Tpm::ParseResponse_NV_ReadPublic(
30779    const std::string& response,
30780    TPM2B_NV_PUBLIC* nv_public,
30781    TPM2B_NAME* nv_name,
30782    AuthorizationDelegate* authorization_delegate) {
30783  VLOG(3) << __func__;
30784  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30785  TPM_RC rc = TPM_RC_SUCCESS;
30786  std::string buffer(response);
30787  TPM_ST tag;
30788  std::string tag_bytes;
30789  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30790  if (rc != TPM_RC_SUCCESS) {
30791    return rc;
30792  }
30793  UINT32 response_size;
30794  std::string response_size_bytes;
30795  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30796  if (rc != TPM_RC_SUCCESS) {
30797    return rc;
30798  }
30799  TPM_RC response_code;
30800  std::string response_code_bytes;
30801  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30802  if (rc != TPM_RC_SUCCESS) {
30803    return rc;
30804  }
30805  if (response_size != response.size()) {
30806    return TPM_RC_SIZE;
30807  }
30808  if (response_code != TPM_RC_SUCCESS) {
30809    return response_code;
30810  }
30811  TPM_CC command_code = TPM_CC_NV_ReadPublic;
30812  std::string command_code_bytes;
30813  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30814  if (rc != TPM_RC_SUCCESS) {
30815    return rc;
30816  }
30817  std::string authorization_section_bytes;
30818  if (tag == TPM_ST_SESSIONS) {
30819    UINT32 parameter_section_size = buffer.size();
30820    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30821    if (rc != TPM_RC_SUCCESS) {
30822      return rc;
30823    }
30824    if (parameter_section_size > buffer.size()) {
30825      return TPM_RC_INSUFFICIENT;
30826    }
30827    authorization_section_bytes = buffer.substr(parameter_section_size);
30828    // Keep the parameter section in |buffer|.
30829    buffer.erase(parameter_section_size);
30830  }
30831  std::unique_ptr<crypto::SecureHash> hash(
30832      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30833  hash->Update(response_code_bytes.data(), response_code_bytes.size());
30834  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30835  hash->Update(buffer.data(), buffer.size());
30836  std::string response_hash(32, 0);
30837  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
30838  if (tag == TPM_ST_SESSIONS) {
30839    CHECK(authorization_delegate) << "Authorization delegate missing!";
30840    if (!authorization_delegate->CheckResponseAuthorization(
30841            response_hash, authorization_section_bytes)) {
30842      return TRUNKS_RC_AUTHORIZATION_FAILED;
30843    }
30844  }
30845  std::string nv_public_bytes;
30846  rc = Parse_TPM2B_NV_PUBLIC(&buffer, nv_public, &nv_public_bytes);
30847  if (rc != TPM_RC_SUCCESS) {
30848    return rc;
30849  }
30850  std::string nv_name_bytes;
30851  rc = Parse_TPM2B_NAME(&buffer, nv_name, &nv_name_bytes);
30852  if (rc != TPM_RC_SUCCESS) {
30853    return rc;
30854  }
30855  if (tag == TPM_ST_SESSIONS) {
30856    CHECK(authorization_delegate) << "Authorization delegate missing!";
30857    // Decrypt just the parameter data, not the size.
30858    std::string tmp = nv_public_bytes.substr(2);
30859    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
30860      return TRUNKS_RC_ENCRYPTION_FAILED;
30861    }
30862    nv_public_bytes.replace(2, std::string::npos, tmp);
30863    rc = Parse_TPM2B_NV_PUBLIC(&nv_public_bytes, nv_public, nullptr);
30864    if (rc != TPM_RC_SUCCESS) {
30865      return rc;
30866    }
30867  }
30868  return TPM_RC_SUCCESS;
30869}
30870
30871void NV_ReadPublicErrorCallback(const Tpm::NV_ReadPublicResponse& callback,
30872                                TPM_RC response_code) {
30873  VLOG(1) << __func__;
30874  callback.Run(response_code, TPM2B_NV_PUBLIC(), TPM2B_NAME());
30875}
30876
30877void NV_ReadPublicResponseParser(const Tpm::NV_ReadPublicResponse& callback,
30878                                 AuthorizationDelegate* authorization_delegate,
30879                                 const std::string& response) {
30880  VLOG(1) << __func__;
30881  base::Callback<void(TPM_RC)> error_reporter =
30882      base::Bind(NV_ReadPublicErrorCallback, callback);
30883  TPM2B_NV_PUBLIC nv_public;
30884  TPM2B_NAME nv_name;
30885  TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic(response, &nv_public, &nv_name,
30886                                               authorization_delegate);
30887  if (rc != TPM_RC_SUCCESS) {
30888    error_reporter.Run(rc);
30889    return;
30890  }
30891  callback.Run(rc, nv_public, nv_name);
30892}
30893
30894void Tpm::NV_ReadPublic(const TPMI_RH_NV_INDEX& nv_index,
30895                        const std::string& nv_index_name,
30896                        AuthorizationDelegate* authorization_delegate,
30897                        const NV_ReadPublicResponse& callback) {
30898  VLOG(1) << __func__;
30899  base::Callback<void(TPM_RC)> error_reporter =
30900      base::Bind(NV_ReadPublicErrorCallback, callback);
30901  base::Callback<void(const std::string&)> parser =
30902      base::Bind(NV_ReadPublicResponseParser, callback, authorization_delegate);
30903  std::string command;
30904  TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
30905                                             authorization_delegate);
30906  if (rc != TPM_RC_SUCCESS) {
30907    error_reporter.Run(rc);
30908    return;
30909  }
30910  transceiver_->SendCommand(command, parser);
30911}
30912
30913TPM_RC Tpm::NV_ReadPublicSync(const TPMI_RH_NV_INDEX& nv_index,
30914                              const std::string& nv_index_name,
30915                              TPM2B_NV_PUBLIC* nv_public,
30916                              TPM2B_NAME* nv_name,
30917                              AuthorizationDelegate* authorization_delegate) {
30918  VLOG(1) << __func__;
30919  std::string command;
30920  TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
30921                                             authorization_delegate);
30922  if (rc != TPM_RC_SUCCESS) {
30923    return rc;
30924  }
30925  std::string response = transceiver_->SendCommandAndWait(command);
30926  rc = ParseResponse_NV_ReadPublic(response, nv_public, nv_name,
30927                                   authorization_delegate);
30928  return rc;
30929}
30930
30931TPM_RC Tpm::SerializeCommand_NV_Write(
30932    const TPMI_RH_NV_AUTH& auth_handle,
30933    const std::string& auth_handle_name,
30934    const TPMI_RH_NV_INDEX& nv_index,
30935    const std::string& nv_index_name,
30936    const TPM2B_MAX_NV_BUFFER& data,
30937    const UINT16& offset,
30938    std::string* serialized_command,
30939    AuthorizationDelegate* authorization_delegate) {
30940  VLOG(3) << __func__;
30941  TPM_RC rc = TPM_RC_SUCCESS;
30942  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30943  UINT32 command_size = 10;  // Header size.
30944  std::string handle_section_bytes;
30945  std::string parameter_section_bytes;
30946  TPM_CC command_code = TPM_CC_NV_Write;
30947  bool is_command_parameter_encryption_possible = true;
30948  bool is_response_parameter_encryption_possible = false;
30949  std::string command_code_bytes;
30950  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30951  if (rc != TPM_RC_SUCCESS) {
30952    return rc;
30953  }
30954  std::string auth_handle_bytes;
30955  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
30956  if (rc != TPM_RC_SUCCESS) {
30957    return rc;
30958  }
30959  std::string nv_index_bytes;
30960  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30961  if (rc != TPM_RC_SUCCESS) {
30962    return rc;
30963  }
30964  std::string data_bytes;
30965  rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
30966  if (rc != TPM_RC_SUCCESS) {
30967    return rc;
30968  }
30969  std::string offset_bytes;
30970  rc = Serialize_UINT16(offset, &offset_bytes);
30971  if (rc != TPM_RC_SUCCESS) {
30972    return rc;
30973  }
30974  if (authorization_delegate) {
30975    // Encrypt just the parameter data, not the size.
30976    std::string tmp = data_bytes.substr(2);
30977    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30978      return TRUNKS_RC_ENCRYPTION_FAILED;
30979    }
30980    data_bytes.replace(2, std::string::npos, tmp);
30981  }
30982  std::unique_ptr<crypto::SecureHash> hash(
30983      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30984  hash->Update(command_code_bytes.data(), command_code_bytes.size());
30985  hash->Update(auth_handle_name.data(), auth_handle_name.size());
30986  handle_section_bytes += auth_handle_bytes;
30987  command_size += auth_handle_bytes.size();
30988  hash->Update(nv_index_name.data(), nv_index_name.size());
30989  handle_section_bytes += nv_index_bytes;
30990  command_size += nv_index_bytes.size();
30991  hash->Update(data_bytes.data(), data_bytes.size());
30992  parameter_section_bytes += data_bytes;
30993  command_size += data_bytes.size();
30994  hash->Update(offset_bytes.data(), offset_bytes.size());
30995  parameter_section_bytes += offset_bytes;
30996  command_size += offset_bytes.size();
30997  std::string command_hash(32, 0);
30998  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
30999  std::string authorization_section_bytes;
31000  std::string authorization_size_bytes;
31001  if (authorization_delegate) {
31002    if (!authorization_delegate->GetCommandAuthorization(
31003            command_hash, is_command_parameter_encryption_possible,
31004            is_response_parameter_encryption_possible,
31005            &authorization_section_bytes)) {
31006      return TRUNKS_RC_AUTHORIZATION_FAILED;
31007    }
31008    if (!authorization_section_bytes.empty()) {
31009      tag = TPM_ST_SESSIONS;
31010      std::string tmp;
31011      rc = Serialize_UINT32(authorization_section_bytes.size(),
31012                            &authorization_size_bytes);
31013      if (rc != TPM_RC_SUCCESS) {
31014        return rc;
31015      }
31016      command_size +=
31017          authorization_size_bytes.size() + authorization_section_bytes.size();
31018    }
31019  }
31020  std::string tag_bytes;
31021  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31022  if (rc != TPM_RC_SUCCESS) {
31023    return rc;
31024  }
31025  std::string command_size_bytes;
31026  rc = Serialize_UINT32(command_size, &command_size_bytes);
31027  if (rc != TPM_RC_SUCCESS) {
31028    return rc;
31029  }
31030  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31031                        handle_section_bytes + authorization_size_bytes +
31032                        authorization_section_bytes + parameter_section_bytes;
31033  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31034  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
31035                                            serialized_command->size());
31036  return TPM_RC_SUCCESS;
31037}
31038
31039TPM_RC Tpm::ParseResponse_NV_Write(
31040    const std::string& response,
31041    AuthorizationDelegate* authorization_delegate) {
31042  VLOG(3) << __func__;
31043  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31044  TPM_RC rc = TPM_RC_SUCCESS;
31045  std::string buffer(response);
31046  TPM_ST tag;
31047  std::string tag_bytes;
31048  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31049  if (rc != TPM_RC_SUCCESS) {
31050    return rc;
31051  }
31052  UINT32 response_size;
31053  std::string response_size_bytes;
31054  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31055  if (rc != TPM_RC_SUCCESS) {
31056    return rc;
31057  }
31058  TPM_RC response_code;
31059  std::string response_code_bytes;
31060  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31061  if (rc != TPM_RC_SUCCESS) {
31062    return rc;
31063  }
31064  if (response_size != response.size()) {
31065    return TPM_RC_SIZE;
31066  }
31067  if (response_code != TPM_RC_SUCCESS) {
31068    return response_code;
31069  }
31070  TPM_CC command_code = TPM_CC_NV_Write;
31071  std::string command_code_bytes;
31072  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31073  if (rc != TPM_RC_SUCCESS) {
31074    return rc;
31075  }
31076  std::string authorization_section_bytes;
31077  if (tag == TPM_ST_SESSIONS) {
31078    UINT32 parameter_section_size = buffer.size();
31079    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31080    if (rc != TPM_RC_SUCCESS) {
31081      return rc;
31082    }
31083    if (parameter_section_size > buffer.size()) {
31084      return TPM_RC_INSUFFICIENT;
31085    }
31086    authorization_section_bytes = buffer.substr(parameter_section_size);
31087    // Keep the parameter section in |buffer|.
31088    buffer.erase(parameter_section_size);
31089  }
31090  std::unique_ptr<crypto::SecureHash> hash(
31091      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31092  hash->Update(response_code_bytes.data(), response_code_bytes.size());
31093  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31094  hash->Update(buffer.data(), buffer.size());
31095  std::string response_hash(32, 0);
31096  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
31097  if (tag == TPM_ST_SESSIONS) {
31098    CHECK(authorization_delegate) << "Authorization delegate missing!";
31099    if (!authorization_delegate->CheckResponseAuthorization(
31100            response_hash, authorization_section_bytes)) {
31101      return TRUNKS_RC_AUTHORIZATION_FAILED;
31102    }
31103  }
31104  return TPM_RC_SUCCESS;
31105}
31106
31107void NV_WriteErrorCallback(const Tpm::NV_WriteResponse& callback,
31108                           TPM_RC response_code) {
31109  VLOG(1) << __func__;
31110  callback.Run(response_code);
31111}
31112
31113void NV_WriteResponseParser(const Tpm::NV_WriteResponse& callback,
31114                            AuthorizationDelegate* authorization_delegate,
31115                            const std::string& response) {
31116  VLOG(1) << __func__;
31117  base::Callback<void(TPM_RC)> error_reporter =
31118      base::Bind(NV_WriteErrorCallback, callback);
31119  TPM_RC rc = Tpm::ParseResponse_NV_Write(response, authorization_delegate);
31120  if (rc != TPM_RC_SUCCESS) {
31121    error_reporter.Run(rc);
31122    return;
31123  }
31124  callback.Run(rc);
31125}
31126
31127void Tpm::NV_Write(const TPMI_RH_NV_AUTH& auth_handle,
31128                   const std::string& auth_handle_name,
31129                   const TPMI_RH_NV_INDEX& nv_index,
31130                   const std::string& nv_index_name,
31131                   const TPM2B_MAX_NV_BUFFER& data,
31132                   const UINT16& offset,
31133                   AuthorizationDelegate* authorization_delegate,
31134                   const NV_WriteResponse& callback) {
31135  VLOG(1) << __func__;
31136  base::Callback<void(TPM_RC)> error_reporter =
31137      base::Bind(NV_WriteErrorCallback, callback);
31138  base::Callback<void(const std::string&)> parser =
31139      base::Bind(NV_WriteResponseParser, callback, authorization_delegate);
31140  std::string command;
31141  TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31142                                        nv_index_name, data, offset, &command,
31143                                        authorization_delegate);
31144  if (rc != TPM_RC_SUCCESS) {
31145    error_reporter.Run(rc);
31146    return;
31147  }
31148  transceiver_->SendCommand(command, parser);
31149}
31150
31151TPM_RC Tpm::NV_WriteSync(const TPMI_RH_NV_AUTH& auth_handle,
31152                         const std::string& auth_handle_name,
31153                         const TPMI_RH_NV_INDEX& nv_index,
31154                         const std::string& nv_index_name,
31155                         const TPM2B_MAX_NV_BUFFER& data,
31156                         const UINT16& offset,
31157                         AuthorizationDelegate* authorization_delegate) {
31158  VLOG(1) << __func__;
31159  std::string command;
31160  TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31161                                        nv_index_name, data, offset, &command,
31162                                        authorization_delegate);
31163  if (rc != TPM_RC_SUCCESS) {
31164    return rc;
31165  }
31166  std::string response = transceiver_->SendCommandAndWait(command);
31167  rc = ParseResponse_NV_Write(response, authorization_delegate);
31168  return rc;
31169}
31170
31171TPM_RC Tpm::SerializeCommand_NV_Increment(
31172    const TPMI_RH_NV_AUTH& auth_handle,
31173    const std::string& auth_handle_name,
31174    const TPMI_RH_NV_INDEX& nv_index,
31175    const std::string& nv_index_name,
31176    std::string* serialized_command,
31177    AuthorizationDelegate* authorization_delegate) {
31178  VLOG(3) << __func__;
31179  TPM_RC rc = TPM_RC_SUCCESS;
31180  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31181  UINT32 command_size = 10;  // Header size.
31182  std::string handle_section_bytes;
31183  std::string parameter_section_bytes;
31184  TPM_CC command_code = TPM_CC_NV_Increment;
31185  bool is_command_parameter_encryption_possible = false;
31186  bool is_response_parameter_encryption_possible = false;
31187  std::string command_code_bytes;
31188  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31189  if (rc != TPM_RC_SUCCESS) {
31190    return rc;
31191  }
31192  std::string auth_handle_bytes;
31193  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31194  if (rc != TPM_RC_SUCCESS) {
31195    return rc;
31196  }
31197  std::string nv_index_bytes;
31198  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31199  if (rc != TPM_RC_SUCCESS) {
31200    return rc;
31201  }
31202  std::unique_ptr<crypto::SecureHash> hash(
31203      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31204  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31205  hash->Update(auth_handle_name.data(), auth_handle_name.size());
31206  handle_section_bytes += auth_handle_bytes;
31207  command_size += auth_handle_bytes.size();
31208  hash->Update(nv_index_name.data(), nv_index_name.size());
31209  handle_section_bytes += nv_index_bytes;
31210  command_size += nv_index_bytes.size();
31211  std::string command_hash(32, 0);
31212  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
31213  std::string authorization_section_bytes;
31214  std::string authorization_size_bytes;
31215  if (authorization_delegate) {
31216    if (!authorization_delegate->GetCommandAuthorization(
31217            command_hash, is_command_parameter_encryption_possible,
31218            is_response_parameter_encryption_possible,
31219            &authorization_section_bytes)) {
31220      return TRUNKS_RC_AUTHORIZATION_FAILED;
31221    }
31222    if (!authorization_section_bytes.empty()) {
31223      tag = TPM_ST_SESSIONS;
31224      std::string tmp;
31225      rc = Serialize_UINT32(authorization_section_bytes.size(),
31226                            &authorization_size_bytes);
31227      if (rc != TPM_RC_SUCCESS) {
31228        return rc;
31229      }
31230      command_size +=
31231          authorization_size_bytes.size() + authorization_section_bytes.size();
31232    }
31233  }
31234  std::string tag_bytes;
31235  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31236  if (rc != TPM_RC_SUCCESS) {
31237    return rc;
31238  }
31239  std::string command_size_bytes;
31240  rc = Serialize_UINT32(command_size, &command_size_bytes);
31241  if (rc != TPM_RC_SUCCESS) {
31242    return rc;
31243  }
31244  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31245                        handle_section_bytes + authorization_size_bytes +
31246                        authorization_section_bytes + parameter_section_bytes;
31247  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31248  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
31249                                            serialized_command->size());
31250  return TPM_RC_SUCCESS;
31251}
31252
31253TPM_RC Tpm::ParseResponse_NV_Increment(
31254    const std::string& response,
31255    AuthorizationDelegate* authorization_delegate) {
31256  VLOG(3) << __func__;
31257  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31258  TPM_RC rc = TPM_RC_SUCCESS;
31259  std::string buffer(response);
31260  TPM_ST tag;
31261  std::string tag_bytes;
31262  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31263  if (rc != TPM_RC_SUCCESS) {
31264    return rc;
31265  }
31266  UINT32 response_size;
31267  std::string response_size_bytes;
31268  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31269  if (rc != TPM_RC_SUCCESS) {
31270    return rc;
31271  }
31272  TPM_RC response_code;
31273  std::string response_code_bytes;
31274  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31275  if (rc != TPM_RC_SUCCESS) {
31276    return rc;
31277  }
31278  if (response_size != response.size()) {
31279    return TPM_RC_SIZE;
31280  }
31281  if (response_code != TPM_RC_SUCCESS) {
31282    return response_code;
31283  }
31284  TPM_CC command_code = TPM_CC_NV_Increment;
31285  std::string command_code_bytes;
31286  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31287  if (rc != TPM_RC_SUCCESS) {
31288    return rc;
31289  }
31290  std::string authorization_section_bytes;
31291  if (tag == TPM_ST_SESSIONS) {
31292    UINT32 parameter_section_size = buffer.size();
31293    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31294    if (rc != TPM_RC_SUCCESS) {
31295      return rc;
31296    }
31297    if (parameter_section_size > buffer.size()) {
31298      return TPM_RC_INSUFFICIENT;
31299    }
31300    authorization_section_bytes = buffer.substr(parameter_section_size);
31301    // Keep the parameter section in |buffer|.
31302    buffer.erase(parameter_section_size);
31303  }
31304  std::unique_ptr<crypto::SecureHash> hash(
31305      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31306  hash->Update(response_code_bytes.data(), response_code_bytes.size());
31307  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31308  hash->Update(buffer.data(), buffer.size());
31309  std::string response_hash(32, 0);
31310  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
31311  if (tag == TPM_ST_SESSIONS) {
31312    CHECK(authorization_delegate) << "Authorization delegate missing!";
31313    if (!authorization_delegate->CheckResponseAuthorization(
31314            response_hash, authorization_section_bytes)) {
31315      return TRUNKS_RC_AUTHORIZATION_FAILED;
31316    }
31317  }
31318  return TPM_RC_SUCCESS;
31319}
31320
31321void NV_IncrementErrorCallback(const Tpm::NV_IncrementResponse& callback,
31322                               TPM_RC response_code) {
31323  VLOG(1) << __func__;
31324  callback.Run(response_code);
31325}
31326
31327void NV_IncrementResponseParser(const Tpm::NV_IncrementResponse& callback,
31328                                AuthorizationDelegate* authorization_delegate,
31329                                const std::string& response) {
31330  VLOG(1) << __func__;
31331  base::Callback<void(TPM_RC)> error_reporter =
31332      base::Bind(NV_IncrementErrorCallback, callback);
31333  TPM_RC rc = Tpm::ParseResponse_NV_Increment(response, authorization_delegate);
31334  if (rc != TPM_RC_SUCCESS) {
31335    error_reporter.Run(rc);
31336    return;
31337  }
31338  callback.Run(rc);
31339}
31340
31341void Tpm::NV_Increment(const TPMI_RH_NV_AUTH& auth_handle,
31342                       const std::string& auth_handle_name,
31343                       const TPMI_RH_NV_INDEX& nv_index,
31344                       const std::string& nv_index_name,
31345                       AuthorizationDelegate* authorization_delegate,
31346                       const NV_IncrementResponse& callback) {
31347  VLOG(1) << __func__;
31348  base::Callback<void(TPM_RC)> error_reporter =
31349      base::Bind(NV_IncrementErrorCallback, callback);
31350  base::Callback<void(const std::string&)> parser =
31351      base::Bind(NV_IncrementResponseParser, callback, authorization_delegate);
31352  std::string command;
31353  TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31354                                            nv_index, nv_index_name, &command,
31355                                            authorization_delegate);
31356  if (rc != TPM_RC_SUCCESS) {
31357    error_reporter.Run(rc);
31358    return;
31359  }
31360  transceiver_->SendCommand(command, parser);
31361}
31362
31363TPM_RC Tpm::NV_IncrementSync(const TPMI_RH_NV_AUTH& auth_handle,
31364                             const std::string& auth_handle_name,
31365                             const TPMI_RH_NV_INDEX& nv_index,
31366                             const std::string& nv_index_name,
31367                             AuthorizationDelegate* authorization_delegate) {
31368  VLOG(1) << __func__;
31369  std::string command;
31370  TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31371                                            nv_index, nv_index_name, &command,
31372                                            authorization_delegate);
31373  if (rc != TPM_RC_SUCCESS) {
31374    return rc;
31375  }
31376  std::string response = transceiver_->SendCommandAndWait(command);
31377  rc = ParseResponse_NV_Increment(response, authorization_delegate);
31378  return rc;
31379}
31380
31381TPM_RC Tpm::SerializeCommand_NV_Extend(
31382    const TPMI_RH_NV_AUTH& auth_handle,
31383    const std::string& auth_handle_name,
31384    const TPMI_RH_NV_INDEX& nv_index,
31385    const std::string& nv_index_name,
31386    const TPM2B_MAX_NV_BUFFER& data,
31387    std::string* serialized_command,
31388    AuthorizationDelegate* authorization_delegate) {
31389  VLOG(3) << __func__;
31390  TPM_RC rc = TPM_RC_SUCCESS;
31391  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31392  UINT32 command_size = 10;  // Header size.
31393  std::string handle_section_bytes;
31394  std::string parameter_section_bytes;
31395  TPM_CC command_code = TPM_CC_NV_Extend;
31396  bool is_command_parameter_encryption_possible = true;
31397  bool is_response_parameter_encryption_possible = false;
31398  std::string command_code_bytes;
31399  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31400  if (rc != TPM_RC_SUCCESS) {
31401    return rc;
31402  }
31403  std::string auth_handle_bytes;
31404  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31405  if (rc != TPM_RC_SUCCESS) {
31406    return rc;
31407  }
31408  std::string nv_index_bytes;
31409  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31410  if (rc != TPM_RC_SUCCESS) {
31411    return rc;
31412  }
31413  std::string data_bytes;
31414  rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31415  if (rc != TPM_RC_SUCCESS) {
31416    return rc;
31417  }
31418  if (authorization_delegate) {
31419    // Encrypt just the parameter data, not the size.
31420    std::string tmp = data_bytes.substr(2);
31421    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31422      return TRUNKS_RC_ENCRYPTION_FAILED;
31423    }
31424    data_bytes.replace(2, std::string::npos, tmp);
31425  }
31426  std::unique_ptr<crypto::SecureHash> hash(
31427      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31428  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31429  hash->Update(auth_handle_name.data(), auth_handle_name.size());
31430  handle_section_bytes += auth_handle_bytes;
31431  command_size += auth_handle_bytes.size();
31432  hash->Update(nv_index_name.data(), nv_index_name.size());
31433  handle_section_bytes += nv_index_bytes;
31434  command_size += nv_index_bytes.size();
31435  hash->Update(data_bytes.data(), data_bytes.size());
31436  parameter_section_bytes += data_bytes;
31437  command_size += data_bytes.size();
31438  std::string command_hash(32, 0);
31439  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
31440  std::string authorization_section_bytes;
31441  std::string authorization_size_bytes;
31442  if (authorization_delegate) {
31443    if (!authorization_delegate->GetCommandAuthorization(
31444            command_hash, is_command_parameter_encryption_possible,
31445            is_response_parameter_encryption_possible,
31446            &authorization_section_bytes)) {
31447      return TRUNKS_RC_AUTHORIZATION_FAILED;
31448    }
31449    if (!authorization_section_bytes.empty()) {
31450      tag = TPM_ST_SESSIONS;
31451      std::string tmp;
31452      rc = Serialize_UINT32(authorization_section_bytes.size(),
31453                            &authorization_size_bytes);
31454      if (rc != TPM_RC_SUCCESS) {
31455        return rc;
31456      }
31457      command_size +=
31458          authorization_size_bytes.size() + authorization_section_bytes.size();
31459    }
31460  }
31461  std::string tag_bytes;
31462  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31463  if (rc != TPM_RC_SUCCESS) {
31464    return rc;
31465  }
31466  std::string command_size_bytes;
31467  rc = Serialize_UINT32(command_size, &command_size_bytes);
31468  if (rc != TPM_RC_SUCCESS) {
31469    return rc;
31470  }
31471  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31472                        handle_section_bytes + authorization_size_bytes +
31473                        authorization_section_bytes + parameter_section_bytes;
31474  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31475  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
31476                                            serialized_command->size());
31477  return TPM_RC_SUCCESS;
31478}
31479
31480TPM_RC Tpm::ParseResponse_NV_Extend(
31481    const std::string& response,
31482    AuthorizationDelegate* authorization_delegate) {
31483  VLOG(3) << __func__;
31484  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31485  TPM_RC rc = TPM_RC_SUCCESS;
31486  std::string buffer(response);
31487  TPM_ST tag;
31488  std::string tag_bytes;
31489  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31490  if (rc != TPM_RC_SUCCESS) {
31491    return rc;
31492  }
31493  UINT32 response_size;
31494  std::string response_size_bytes;
31495  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31496  if (rc != TPM_RC_SUCCESS) {
31497    return rc;
31498  }
31499  TPM_RC response_code;
31500  std::string response_code_bytes;
31501  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31502  if (rc != TPM_RC_SUCCESS) {
31503    return rc;
31504  }
31505  if (response_size != response.size()) {
31506    return TPM_RC_SIZE;
31507  }
31508  if (response_code != TPM_RC_SUCCESS) {
31509    return response_code;
31510  }
31511  TPM_CC command_code = TPM_CC_NV_Extend;
31512  std::string command_code_bytes;
31513  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31514  if (rc != TPM_RC_SUCCESS) {
31515    return rc;
31516  }
31517  std::string authorization_section_bytes;
31518  if (tag == TPM_ST_SESSIONS) {
31519    UINT32 parameter_section_size = buffer.size();
31520    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31521    if (rc != TPM_RC_SUCCESS) {
31522      return rc;
31523    }
31524    if (parameter_section_size > buffer.size()) {
31525      return TPM_RC_INSUFFICIENT;
31526    }
31527    authorization_section_bytes = buffer.substr(parameter_section_size);
31528    // Keep the parameter section in |buffer|.
31529    buffer.erase(parameter_section_size);
31530  }
31531  std::unique_ptr<crypto::SecureHash> hash(
31532      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31533  hash->Update(response_code_bytes.data(), response_code_bytes.size());
31534  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31535  hash->Update(buffer.data(), buffer.size());
31536  std::string response_hash(32, 0);
31537  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
31538  if (tag == TPM_ST_SESSIONS) {
31539    CHECK(authorization_delegate) << "Authorization delegate missing!";
31540    if (!authorization_delegate->CheckResponseAuthorization(
31541            response_hash, authorization_section_bytes)) {
31542      return TRUNKS_RC_AUTHORIZATION_FAILED;
31543    }
31544  }
31545  return TPM_RC_SUCCESS;
31546}
31547
31548void NV_ExtendErrorCallback(const Tpm::NV_ExtendResponse& callback,
31549                            TPM_RC response_code) {
31550  VLOG(1) << __func__;
31551  callback.Run(response_code);
31552}
31553
31554void NV_ExtendResponseParser(const Tpm::NV_ExtendResponse& callback,
31555                             AuthorizationDelegate* authorization_delegate,
31556                             const std::string& response) {
31557  VLOG(1) << __func__;
31558  base::Callback<void(TPM_RC)> error_reporter =
31559      base::Bind(NV_ExtendErrorCallback, callback);
31560  TPM_RC rc = Tpm::ParseResponse_NV_Extend(response, authorization_delegate);
31561  if (rc != TPM_RC_SUCCESS) {
31562    error_reporter.Run(rc);
31563    return;
31564  }
31565  callback.Run(rc);
31566}
31567
31568void Tpm::NV_Extend(const TPMI_RH_NV_AUTH& auth_handle,
31569                    const std::string& auth_handle_name,
31570                    const TPMI_RH_NV_INDEX& nv_index,
31571                    const std::string& nv_index_name,
31572                    const TPM2B_MAX_NV_BUFFER& data,
31573                    AuthorizationDelegate* authorization_delegate,
31574                    const NV_ExtendResponse& callback) {
31575  VLOG(1) << __func__;
31576  base::Callback<void(TPM_RC)> error_reporter =
31577      base::Bind(NV_ExtendErrorCallback, callback);
31578  base::Callback<void(const std::string&)> parser =
31579      base::Bind(NV_ExtendResponseParser, callback, authorization_delegate);
31580  std::string command;
31581  TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
31582                                         nv_index, nv_index_name, data,
31583                                         &command, authorization_delegate);
31584  if (rc != TPM_RC_SUCCESS) {
31585    error_reporter.Run(rc);
31586    return;
31587  }
31588  transceiver_->SendCommand(command, parser);
31589}
31590
31591TPM_RC Tpm::NV_ExtendSync(const TPMI_RH_NV_AUTH& auth_handle,
31592                          const std::string& auth_handle_name,
31593                          const TPMI_RH_NV_INDEX& nv_index,
31594                          const std::string& nv_index_name,
31595                          const TPM2B_MAX_NV_BUFFER& data,
31596                          AuthorizationDelegate* authorization_delegate) {
31597  VLOG(1) << __func__;
31598  std::string command;
31599  TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
31600                                         nv_index, nv_index_name, data,
31601                                         &command, authorization_delegate);
31602  if (rc != TPM_RC_SUCCESS) {
31603    return rc;
31604  }
31605  std::string response = transceiver_->SendCommandAndWait(command);
31606  rc = ParseResponse_NV_Extend(response, authorization_delegate);
31607  return rc;
31608}
31609
31610TPM_RC Tpm::SerializeCommand_NV_SetBits(
31611    const TPMI_RH_NV_AUTH& auth_handle,
31612    const std::string& auth_handle_name,
31613    const TPMI_RH_NV_INDEX& nv_index,
31614    const std::string& nv_index_name,
31615    const UINT64& bits,
31616    std::string* serialized_command,
31617    AuthorizationDelegate* authorization_delegate) {
31618  VLOG(3) << __func__;
31619  TPM_RC rc = TPM_RC_SUCCESS;
31620  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31621  UINT32 command_size = 10;  // Header size.
31622  std::string handle_section_bytes;
31623  std::string parameter_section_bytes;
31624  TPM_CC command_code = TPM_CC_NV_SetBits;
31625  bool is_command_parameter_encryption_possible = false;
31626  bool is_response_parameter_encryption_possible = false;
31627  std::string command_code_bytes;
31628  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31629  if (rc != TPM_RC_SUCCESS) {
31630    return rc;
31631  }
31632  std::string auth_handle_bytes;
31633  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31634  if (rc != TPM_RC_SUCCESS) {
31635    return rc;
31636  }
31637  std::string nv_index_bytes;
31638  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31639  if (rc != TPM_RC_SUCCESS) {
31640    return rc;
31641  }
31642  std::string bits_bytes;
31643  rc = Serialize_UINT64(bits, &bits_bytes);
31644  if (rc != TPM_RC_SUCCESS) {
31645    return rc;
31646  }
31647  std::unique_ptr<crypto::SecureHash> hash(
31648      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31649  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31650  hash->Update(auth_handle_name.data(), auth_handle_name.size());
31651  handle_section_bytes += auth_handle_bytes;
31652  command_size += auth_handle_bytes.size();
31653  hash->Update(nv_index_name.data(), nv_index_name.size());
31654  handle_section_bytes += nv_index_bytes;
31655  command_size += nv_index_bytes.size();
31656  hash->Update(bits_bytes.data(), bits_bytes.size());
31657  parameter_section_bytes += bits_bytes;
31658  command_size += bits_bytes.size();
31659  std::string command_hash(32, 0);
31660  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
31661  std::string authorization_section_bytes;
31662  std::string authorization_size_bytes;
31663  if (authorization_delegate) {
31664    if (!authorization_delegate->GetCommandAuthorization(
31665            command_hash, is_command_parameter_encryption_possible,
31666            is_response_parameter_encryption_possible,
31667            &authorization_section_bytes)) {
31668      return TRUNKS_RC_AUTHORIZATION_FAILED;
31669    }
31670    if (!authorization_section_bytes.empty()) {
31671      tag = TPM_ST_SESSIONS;
31672      std::string tmp;
31673      rc = Serialize_UINT32(authorization_section_bytes.size(),
31674                            &authorization_size_bytes);
31675      if (rc != TPM_RC_SUCCESS) {
31676        return rc;
31677      }
31678      command_size +=
31679          authorization_size_bytes.size() + authorization_section_bytes.size();
31680    }
31681  }
31682  std::string tag_bytes;
31683  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31684  if (rc != TPM_RC_SUCCESS) {
31685    return rc;
31686  }
31687  std::string command_size_bytes;
31688  rc = Serialize_UINT32(command_size, &command_size_bytes);
31689  if (rc != TPM_RC_SUCCESS) {
31690    return rc;
31691  }
31692  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31693                        handle_section_bytes + authorization_size_bytes +
31694                        authorization_section_bytes + parameter_section_bytes;
31695  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31696  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
31697                                            serialized_command->size());
31698  return TPM_RC_SUCCESS;
31699}
31700
31701TPM_RC Tpm::ParseResponse_NV_SetBits(
31702    const std::string& response,
31703    AuthorizationDelegate* authorization_delegate) {
31704  VLOG(3) << __func__;
31705  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31706  TPM_RC rc = TPM_RC_SUCCESS;
31707  std::string buffer(response);
31708  TPM_ST tag;
31709  std::string tag_bytes;
31710  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31711  if (rc != TPM_RC_SUCCESS) {
31712    return rc;
31713  }
31714  UINT32 response_size;
31715  std::string response_size_bytes;
31716  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31717  if (rc != TPM_RC_SUCCESS) {
31718    return rc;
31719  }
31720  TPM_RC response_code;
31721  std::string response_code_bytes;
31722  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31723  if (rc != TPM_RC_SUCCESS) {
31724    return rc;
31725  }
31726  if (response_size != response.size()) {
31727    return TPM_RC_SIZE;
31728  }
31729  if (response_code != TPM_RC_SUCCESS) {
31730    return response_code;
31731  }
31732  TPM_CC command_code = TPM_CC_NV_SetBits;
31733  std::string command_code_bytes;
31734  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31735  if (rc != TPM_RC_SUCCESS) {
31736    return rc;
31737  }
31738  std::string authorization_section_bytes;
31739  if (tag == TPM_ST_SESSIONS) {
31740    UINT32 parameter_section_size = buffer.size();
31741    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31742    if (rc != TPM_RC_SUCCESS) {
31743      return rc;
31744    }
31745    if (parameter_section_size > buffer.size()) {
31746      return TPM_RC_INSUFFICIENT;
31747    }
31748    authorization_section_bytes = buffer.substr(parameter_section_size);
31749    // Keep the parameter section in |buffer|.
31750    buffer.erase(parameter_section_size);
31751  }
31752  std::unique_ptr<crypto::SecureHash> hash(
31753      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31754  hash->Update(response_code_bytes.data(), response_code_bytes.size());
31755  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31756  hash->Update(buffer.data(), buffer.size());
31757  std::string response_hash(32, 0);
31758  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
31759  if (tag == TPM_ST_SESSIONS) {
31760    CHECK(authorization_delegate) << "Authorization delegate missing!";
31761    if (!authorization_delegate->CheckResponseAuthorization(
31762            response_hash, authorization_section_bytes)) {
31763      return TRUNKS_RC_AUTHORIZATION_FAILED;
31764    }
31765  }
31766  return TPM_RC_SUCCESS;
31767}
31768
31769void NV_SetBitsErrorCallback(const Tpm::NV_SetBitsResponse& callback,
31770                             TPM_RC response_code) {
31771  VLOG(1) << __func__;
31772  callback.Run(response_code);
31773}
31774
31775void NV_SetBitsResponseParser(const Tpm::NV_SetBitsResponse& callback,
31776                              AuthorizationDelegate* authorization_delegate,
31777                              const std::string& response) {
31778  VLOG(1) << __func__;
31779  base::Callback<void(TPM_RC)> error_reporter =
31780      base::Bind(NV_SetBitsErrorCallback, callback);
31781  TPM_RC rc = Tpm::ParseResponse_NV_SetBits(response, authorization_delegate);
31782  if (rc != TPM_RC_SUCCESS) {
31783    error_reporter.Run(rc);
31784    return;
31785  }
31786  callback.Run(rc);
31787}
31788
31789void Tpm::NV_SetBits(const TPMI_RH_NV_AUTH& auth_handle,
31790                     const std::string& auth_handle_name,
31791                     const TPMI_RH_NV_INDEX& nv_index,
31792                     const std::string& nv_index_name,
31793                     const UINT64& bits,
31794                     AuthorizationDelegate* authorization_delegate,
31795                     const NV_SetBitsResponse& callback) {
31796  VLOG(1) << __func__;
31797  base::Callback<void(TPM_RC)> error_reporter =
31798      base::Bind(NV_SetBitsErrorCallback, callback);
31799  base::Callback<void(const std::string&)> parser =
31800      base::Bind(NV_SetBitsResponseParser, callback, authorization_delegate);
31801  std::string command;
31802  TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
31803                                          nv_index, nv_index_name, bits,
31804                                          &command, authorization_delegate);
31805  if (rc != TPM_RC_SUCCESS) {
31806    error_reporter.Run(rc);
31807    return;
31808  }
31809  transceiver_->SendCommand(command, parser);
31810}
31811
31812TPM_RC Tpm::NV_SetBitsSync(const TPMI_RH_NV_AUTH& auth_handle,
31813                           const std::string& auth_handle_name,
31814                           const TPMI_RH_NV_INDEX& nv_index,
31815                           const std::string& nv_index_name,
31816                           const UINT64& bits,
31817                           AuthorizationDelegate* authorization_delegate) {
31818  VLOG(1) << __func__;
31819  std::string command;
31820  TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
31821                                          nv_index, nv_index_name, bits,
31822                                          &command, authorization_delegate);
31823  if (rc != TPM_RC_SUCCESS) {
31824    return rc;
31825  }
31826  std::string response = transceiver_->SendCommandAndWait(command);
31827  rc = ParseResponse_NV_SetBits(response, authorization_delegate);
31828  return rc;
31829}
31830
31831TPM_RC Tpm::SerializeCommand_NV_WriteLock(
31832    const TPMI_RH_NV_AUTH& auth_handle,
31833    const std::string& auth_handle_name,
31834    const TPMI_RH_NV_INDEX& nv_index,
31835    const std::string& nv_index_name,
31836    std::string* serialized_command,
31837    AuthorizationDelegate* authorization_delegate) {
31838  VLOG(3) << __func__;
31839  TPM_RC rc = TPM_RC_SUCCESS;
31840  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31841  UINT32 command_size = 10;  // Header size.
31842  std::string handle_section_bytes;
31843  std::string parameter_section_bytes;
31844  TPM_CC command_code = TPM_CC_NV_WriteLock;
31845  bool is_command_parameter_encryption_possible = false;
31846  bool is_response_parameter_encryption_possible = false;
31847  std::string command_code_bytes;
31848  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31849  if (rc != TPM_RC_SUCCESS) {
31850    return rc;
31851  }
31852  std::string auth_handle_bytes;
31853  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31854  if (rc != TPM_RC_SUCCESS) {
31855    return rc;
31856  }
31857  std::string nv_index_bytes;
31858  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31859  if (rc != TPM_RC_SUCCESS) {
31860    return rc;
31861  }
31862  std::unique_ptr<crypto::SecureHash> hash(
31863      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31864  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31865  hash->Update(auth_handle_name.data(), auth_handle_name.size());
31866  handle_section_bytes += auth_handle_bytes;
31867  command_size += auth_handle_bytes.size();
31868  hash->Update(nv_index_name.data(), nv_index_name.size());
31869  handle_section_bytes += nv_index_bytes;
31870  command_size += nv_index_bytes.size();
31871  std::string command_hash(32, 0);
31872  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
31873  std::string authorization_section_bytes;
31874  std::string authorization_size_bytes;
31875  if (authorization_delegate) {
31876    if (!authorization_delegate->GetCommandAuthorization(
31877            command_hash, is_command_parameter_encryption_possible,
31878            is_response_parameter_encryption_possible,
31879            &authorization_section_bytes)) {
31880      return TRUNKS_RC_AUTHORIZATION_FAILED;
31881    }
31882    if (!authorization_section_bytes.empty()) {
31883      tag = TPM_ST_SESSIONS;
31884      std::string tmp;
31885      rc = Serialize_UINT32(authorization_section_bytes.size(),
31886                            &authorization_size_bytes);
31887      if (rc != TPM_RC_SUCCESS) {
31888        return rc;
31889      }
31890      command_size +=
31891          authorization_size_bytes.size() + authorization_section_bytes.size();
31892    }
31893  }
31894  std::string tag_bytes;
31895  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31896  if (rc != TPM_RC_SUCCESS) {
31897    return rc;
31898  }
31899  std::string command_size_bytes;
31900  rc = Serialize_UINT32(command_size, &command_size_bytes);
31901  if (rc != TPM_RC_SUCCESS) {
31902    return rc;
31903  }
31904  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31905                        handle_section_bytes + authorization_size_bytes +
31906                        authorization_section_bytes + parameter_section_bytes;
31907  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31908  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
31909                                            serialized_command->size());
31910  return TPM_RC_SUCCESS;
31911}
31912
31913TPM_RC Tpm::ParseResponse_NV_WriteLock(
31914    const std::string& response,
31915    AuthorizationDelegate* authorization_delegate) {
31916  VLOG(3) << __func__;
31917  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31918  TPM_RC rc = TPM_RC_SUCCESS;
31919  std::string buffer(response);
31920  TPM_ST tag;
31921  std::string tag_bytes;
31922  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31923  if (rc != TPM_RC_SUCCESS) {
31924    return rc;
31925  }
31926  UINT32 response_size;
31927  std::string response_size_bytes;
31928  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31929  if (rc != TPM_RC_SUCCESS) {
31930    return rc;
31931  }
31932  TPM_RC response_code;
31933  std::string response_code_bytes;
31934  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31935  if (rc != TPM_RC_SUCCESS) {
31936    return rc;
31937  }
31938  if (response_size != response.size()) {
31939    return TPM_RC_SIZE;
31940  }
31941  if (response_code != TPM_RC_SUCCESS) {
31942    return response_code;
31943  }
31944  TPM_CC command_code = TPM_CC_NV_WriteLock;
31945  std::string command_code_bytes;
31946  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31947  if (rc != TPM_RC_SUCCESS) {
31948    return rc;
31949  }
31950  std::string authorization_section_bytes;
31951  if (tag == TPM_ST_SESSIONS) {
31952    UINT32 parameter_section_size = buffer.size();
31953    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31954    if (rc != TPM_RC_SUCCESS) {
31955      return rc;
31956    }
31957    if (parameter_section_size > buffer.size()) {
31958      return TPM_RC_INSUFFICIENT;
31959    }
31960    authorization_section_bytes = buffer.substr(parameter_section_size);
31961    // Keep the parameter section in |buffer|.
31962    buffer.erase(parameter_section_size);
31963  }
31964  std::unique_ptr<crypto::SecureHash> hash(
31965      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31966  hash->Update(response_code_bytes.data(), response_code_bytes.size());
31967  hash->Update(command_code_bytes.data(), command_code_bytes.size());
31968  hash->Update(buffer.data(), buffer.size());
31969  std::string response_hash(32, 0);
31970  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
31971  if (tag == TPM_ST_SESSIONS) {
31972    CHECK(authorization_delegate) << "Authorization delegate missing!";
31973    if (!authorization_delegate->CheckResponseAuthorization(
31974            response_hash, authorization_section_bytes)) {
31975      return TRUNKS_RC_AUTHORIZATION_FAILED;
31976    }
31977  }
31978  return TPM_RC_SUCCESS;
31979}
31980
31981void NV_WriteLockErrorCallback(const Tpm::NV_WriteLockResponse& callback,
31982                               TPM_RC response_code) {
31983  VLOG(1) << __func__;
31984  callback.Run(response_code);
31985}
31986
31987void NV_WriteLockResponseParser(const Tpm::NV_WriteLockResponse& callback,
31988                                AuthorizationDelegate* authorization_delegate,
31989                                const std::string& response) {
31990  VLOG(1) << __func__;
31991  base::Callback<void(TPM_RC)> error_reporter =
31992      base::Bind(NV_WriteLockErrorCallback, callback);
31993  TPM_RC rc = Tpm::ParseResponse_NV_WriteLock(response, authorization_delegate);
31994  if (rc != TPM_RC_SUCCESS) {
31995    error_reporter.Run(rc);
31996    return;
31997  }
31998  callback.Run(rc);
31999}
32000
32001void Tpm::NV_WriteLock(const TPMI_RH_NV_AUTH& auth_handle,
32002                       const std::string& auth_handle_name,
32003                       const TPMI_RH_NV_INDEX& nv_index,
32004                       const std::string& nv_index_name,
32005                       AuthorizationDelegate* authorization_delegate,
32006                       const NV_WriteLockResponse& callback) {
32007  VLOG(1) << __func__;
32008  base::Callback<void(TPM_RC)> error_reporter =
32009      base::Bind(NV_WriteLockErrorCallback, callback);
32010  base::Callback<void(const std::string&)> parser =
32011      base::Bind(NV_WriteLockResponseParser, callback, authorization_delegate);
32012  std::string command;
32013  TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32014                                            nv_index, nv_index_name, &command,
32015                                            authorization_delegate);
32016  if (rc != TPM_RC_SUCCESS) {
32017    error_reporter.Run(rc);
32018    return;
32019  }
32020  transceiver_->SendCommand(command, parser);
32021}
32022
32023TPM_RC Tpm::NV_WriteLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32024                             const std::string& auth_handle_name,
32025                             const TPMI_RH_NV_INDEX& nv_index,
32026                             const std::string& nv_index_name,
32027                             AuthorizationDelegate* authorization_delegate) {
32028  VLOG(1) << __func__;
32029  std::string command;
32030  TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32031                                            nv_index, nv_index_name, &command,
32032                                            authorization_delegate);
32033  if (rc != TPM_RC_SUCCESS) {
32034    return rc;
32035  }
32036  std::string response = transceiver_->SendCommandAndWait(command);
32037  rc = ParseResponse_NV_WriteLock(response, authorization_delegate);
32038  return rc;
32039}
32040
32041TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock(
32042    const TPMI_RH_PROVISION& auth_handle,
32043    const std::string& auth_handle_name,
32044    std::string* serialized_command,
32045    AuthorizationDelegate* authorization_delegate) {
32046  VLOG(3) << __func__;
32047  TPM_RC rc = TPM_RC_SUCCESS;
32048  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32049  UINT32 command_size = 10;  // Header size.
32050  std::string handle_section_bytes;
32051  std::string parameter_section_bytes;
32052  TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32053  bool is_command_parameter_encryption_possible = false;
32054  bool is_response_parameter_encryption_possible = false;
32055  std::string command_code_bytes;
32056  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32057  if (rc != TPM_RC_SUCCESS) {
32058    return rc;
32059  }
32060  std::string auth_handle_bytes;
32061  rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
32062  if (rc != TPM_RC_SUCCESS) {
32063    return rc;
32064  }
32065  std::unique_ptr<crypto::SecureHash> hash(
32066      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32067  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32068  hash->Update(auth_handle_name.data(), auth_handle_name.size());
32069  handle_section_bytes += auth_handle_bytes;
32070  command_size += auth_handle_bytes.size();
32071  std::string command_hash(32, 0);
32072  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
32073  std::string authorization_section_bytes;
32074  std::string authorization_size_bytes;
32075  if (authorization_delegate) {
32076    if (!authorization_delegate->GetCommandAuthorization(
32077            command_hash, is_command_parameter_encryption_possible,
32078            is_response_parameter_encryption_possible,
32079            &authorization_section_bytes)) {
32080      return TRUNKS_RC_AUTHORIZATION_FAILED;
32081    }
32082    if (!authorization_section_bytes.empty()) {
32083      tag = TPM_ST_SESSIONS;
32084      std::string tmp;
32085      rc = Serialize_UINT32(authorization_section_bytes.size(),
32086                            &authorization_size_bytes);
32087      if (rc != TPM_RC_SUCCESS) {
32088        return rc;
32089      }
32090      command_size +=
32091          authorization_size_bytes.size() + authorization_section_bytes.size();
32092    }
32093  }
32094  std::string tag_bytes;
32095  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32096  if (rc != TPM_RC_SUCCESS) {
32097    return rc;
32098  }
32099  std::string command_size_bytes;
32100  rc = Serialize_UINT32(command_size, &command_size_bytes);
32101  if (rc != TPM_RC_SUCCESS) {
32102    return rc;
32103  }
32104  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32105                        handle_section_bytes + authorization_size_bytes +
32106                        authorization_section_bytes + parameter_section_bytes;
32107  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32108  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
32109                                            serialized_command->size());
32110  return TPM_RC_SUCCESS;
32111}
32112
32113TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock(
32114    const std::string& response,
32115    AuthorizationDelegate* authorization_delegate) {
32116  VLOG(3) << __func__;
32117  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32118  TPM_RC rc = TPM_RC_SUCCESS;
32119  std::string buffer(response);
32120  TPM_ST tag;
32121  std::string tag_bytes;
32122  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32123  if (rc != TPM_RC_SUCCESS) {
32124    return rc;
32125  }
32126  UINT32 response_size;
32127  std::string response_size_bytes;
32128  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32129  if (rc != TPM_RC_SUCCESS) {
32130    return rc;
32131  }
32132  TPM_RC response_code;
32133  std::string response_code_bytes;
32134  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32135  if (rc != TPM_RC_SUCCESS) {
32136    return rc;
32137  }
32138  if (response_size != response.size()) {
32139    return TPM_RC_SIZE;
32140  }
32141  if (response_code != TPM_RC_SUCCESS) {
32142    return response_code;
32143  }
32144  TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32145  std::string command_code_bytes;
32146  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32147  if (rc != TPM_RC_SUCCESS) {
32148    return rc;
32149  }
32150  std::string authorization_section_bytes;
32151  if (tag == TPM_ST_SESSIONS) {
32152    UINT32 parameter_section_size = buffer.size();
32153    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32154    if (rc != TPM_RC_SUCCESS) {
32155      return rc;
32156    }
32157    if (parameter_section_size > buffer.size()) {
32158      return TPM_RC_INSUFFICIENT;
32159    }
32160    authorization_section_bytes = buffer.substr(parameter_section_size);
32161    // Keep the parameter section in |buffer|.
32162    buffer.erase(parameter_section_size);
32163  }
32164  std::unique_ptr<crypto::SecureHash> hash(
32165      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32166  hash->Update(response_code_bytes.data(), response_code_bytes.size());
32167  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32168  hash->Update(buffer.data(), buffer.size());
32169  std::string response_hash(32, 0);
32170  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
32171  if (tag == TPM_ST_SESSIONS) {
32172    CHECK(authorization_delegate) << "Authorization delegate missing!";
32173    if (!authorization_delegate->CheckResponseAuthorization(
32174            response_hash, authorization_section_bytes)) {
32175      return TRUNKS_RC_AUTHORIZATION_FAILED;
32176    }
32177  }
32178  return TPM_RC_SUCCESS;
32179}
32180
32181void NV_GlobalWriteLockErrorCallback(
32182    const Tpm::NV_GlobalWriteLockResponse& callback,
32183    TPM_RC response_code) {
32184  VLOG(1) << __func__;
32185  callback.Run(response_code);
32186}
32187
32188void NV_GlobalWriteLockResponseParser(
32189    const Tpm::NV_GlobalWriteLockResponse& callback,
32190    AuthorizationDelegate* authorization_delegate,
32191    const std::string& response) {
32192  VLOG(1) << __func__;
32193  base::Callback<void(TPM_RC)> error_reporter =
32194      base::Bind(NV_GlobalWriteLockErrorCallback, callback);
32195  TPM_RC rc =
32196      Tpm::ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32197  if (rc != TPM_RC_SUCCESS) {
32198    error_reporter.Run(rc);
32199    return;
32200  }
32201  callback.Run(rc);
32202}
32203
32204void Tpm::NV_GlobalWriteLock(const TPMI_RH_PROVISION& auth_handle,
32205                             const std::string& auth_handle_name,
32206                             AuthorizationDelegate* authorization_delegate,
32207                             const NV_GlobalWriteLockResponse& callback) {
32208  VLOG(1) << __func__;
32209  base::Callback<void(TPM_RC)> error_reporter =
32210      base::Bind(NV_GlobalWriteLockErrorCallback, callback);
32211  base::Callback<void(const std::string&)> parser = base::Bind(
32212      NV_GlobalWriteLockResponseParser, callback, authorization_delegate);
32213  std::string command;
32214  TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32215      auth_handle, auth_handle_name, &command, authorization_delegate);
32216  if (rc != TPM_RC_SUCCESS) {
32217    error_reporter.Run(rc);
32218    return;
32219  }
32220  transceiver_->SendCommand(command, parser);
32221}
32222
32223TPM_RC Tpm::NV_GlobalWriteLockSync(
32224    const TPMI_RH_PROVISION& auth_handle,
32225    const std::string& auth_handle_name,
32226    AuthorizationDelegate* authorization_delegate) {
32227  VLOG(1) << __func__;
32228  std::string command;
32229  TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32230      auth_handle, auth_handle_name, &command, authorization_delegate);
32231  if (rc != TPM_RC_SUCCESS) {
32232    return rc;
32233  }
32234  std::string response = transceiver_->SendCommandAndWait(command);
32235  rc = ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32236  return rc;
32237}
32238
32239TPM_RC Tpm::SerializeCommand_NV_Read(
32240    const TPMI_RH_NV_AUTH& auth_handle,
32241    const std::string& auth_handle_name,
32242    const TPMI_RH_NV_INDEX& nv_index,
32243    const std::string& nv_index_name,
32244    const UINT16& size,
32245    const UINT16& offset,
32246    std::string* serialized_command,
32247    AuthorizationDelegate* authorization_delegate) {
32248  VLOG(3) << __func__;
32249  TPM_RC rc = TPM_RC_SUCCESS;
32250  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32251  UINT32 command_size = 10;  // Header size.
32252  std::string handle_section_bytes;
32253  std::string parameter_section_bytes;
32254  TPM_CC command_code = TPM_CC_NV_Read;
32255  bool is_command_parameter_encryption_possible = false;
32256  bool is_response_parameter_encryption_possible = true;
32257  std::string command_code_bytes;
32258  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32259  if (rc != TPM_RC_SUCCESS) {
32260    return rc;
32261  }
32262  std::string auth_handle_bytes;
32263  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32264  if (rc != TPM_RC_SUCCESS) {
32265    return rc;
32266  }
32267  std::string nv_index_bytes;
32268  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32269  if (rc != TPM_RC_SUCCESS) {
32270    return rc;
32271  }
32272  std::string size_bytes;
32273  rc = Serialize_UINT16(size, &size_bytes);
32274  if (rc != TPM_RC_SUCCESS) {
32275    return rc;
32276  }
32277  std::string offset_bytes;
32278  rc = Serialize_UINT16(offset, &offset_bytes);
32279  if (rc != TPM_RC_SUCCESS) {
32280    return rc;
32281  }
32282  std::unique_ptr<crypto::SecureHash> hash(
32283      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32284  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32285  hash->Update(auth_handle_name.data(), auth_handle_name.size());
32286  handle_section_bytes += auth_handle_bytes;
32287  command_size += auth_handle_bytes.size();
32288  hash->Update(nv_index_name.data(), nv_index_name.size());
32289  handle_section_bytes += nv_index_bytes;
32290  command_size += nv_index_bytes.size();
32291  hash->Update(size_bytes.data(), size_bytes.size());
32292  parameter_section_bytes += size_bytes;
32293  command_size += size_bytes.size();
32294  hash->Update(offset_bytes.data(), offset_bytes.size());
32295  parameter_section_bytes += offset_bytes;
32296  command_size += offset_bytes.size();
32297  std::string command_hash(32, 0);
32298  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
32299  std::string authorization_section_bytes;
32300  std::string authorization_size_bytes;
32301  if (authorization_delegate) {
32302    if (!authorization_delegate->GetCommandAuthorization(
32303            command_hash, is_command_parameter_encryption_possible,
32304            is_response_parameter_encryption_possible,
32305            &authorization_section_bytes)) {
32306      return TRUNKS_RC_AUTHORIZATION_FAILED;
32307    }
32308    if (!authorization_section_bytes.empty()) {
32309      tag = TPM_ST_SESSIONS;
32310      std::string tmp;
32311      rc = Serialize_UINT32(authorization_section_bytes.size(),
32312                            &authorization_size_bytes);
32313      if (rc != TPM_RC_SUCCESS) {
32314        return rc;
32315      }
32316      command_size +=
32317          authorization_size_bytes.size() + authorization_section_bytes.size();
32318    }
32319  }
32320  std::string tag_bytes;
32321  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32322  if (rc != TPM_RC_SUCCESS) {
32323    return rc;
32324  }
32325  std::string command_size_bytes;
32326  rc = Serialize_UINT32(command_size, &command_size_bytes);
32327  if (rc != TPM_RC_SUCCESS) {
32328    return rc;
32329  }
32330  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32331                        handle_section_bytes + authorization_size_bytes +
32332                        authorization_section_bytes + parameter_section_bytes;
32333  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32334  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
32335                                            serialized_command->size());
32336  return TPM_RC_SUCCESS;
32337}
32338
32339TPM_RC Tpm::ParseResponse_NV_Read(
32340    const std::string& response,
32341    TPM2B_MAX_NV_BUFFER* data,
32342    AuthorizationDelegate* authorization_delegate) {
32343  VLOG(3) << __func__;
32344  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32345  TPM_RC rc = TPM_RC_SUCCESS;
32346  std::string buffer(response);
32347  TPM_ST tag;
32348  std::string tag_bytes;
32349  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32350  if (rc != TPM_RC_SUCCESS) {
32351    return rc;
32352  }
32353  UINT32 response_size;
32354  std::string response_size_bytes;
32355  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32356  if (rc != TPM_RC_SUCCESS) {
32357    return rc;
32358  }
32359  TPM_RC response_code;
32360  std::string response_code_bytes;
32361  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32362  if (rc != TPM_RC_SUCCESS) {
32363    return rc;
32364  }
32365  if (response_size != response.size()) {
32366    return TPM_RC_SIZE;
32367  }
32368  if (response_code != TPM_RC_SUCCESS) {
32369    return response_code;
32370  }
32371  TPM_CC command_code = TPM_CC_NV_Read;
32372  std::string command_code_bytes;
32373  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32374  if (rc != TPM_RC_SUCCESS) {
32375    return rc;
32376  }
32377  std::string authorization_section_bytes;
32378  if (tag == TPM_ST_SESSIONS) {
32379    UINT32 parameter_section_size = buffer.size();
32380    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32381    if (rc != TPM_RC_SUCCESS) {
32382      return rc;
32383    }
32384    if (parameter_section_size > buffer.size()) {
32385      return TPM_RC_INSUFFICIENT;
32386    }
32387    authorization_section_bytes = buffer.substr(parameter_section_size);
32388    // Keep the parameter section in |buffer|.
32389    buffer.erase(parameter_section_size);
32390  }
32391  std::unique_ptr<crypto::SecureHash> hash(
32392      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32393  hash->Update(response_code_bytes.data(), response_code_bytes.size());
32394  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32395  hash->Update(buffer.data(), buffer.size());
32396  std::string response_hash(32, 0);
32397  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
32398  if (tag == TPM_ST_SESSIONS) {
32399    CHECK(authorization_delegate) << "Authorization delegate missing!";
32400    if (!authorization_delegate->CheckResponseAuthorization(
32401            response_hash, authorization_section_bytes)) {
32402      return TRUNKS_RC_AUTHORIZATION_FAILED;
32403    }
32404  }
32405  std::string data_bytes;
32406  rc = Parse_TPM2B_MAX_NV_BUFFER(&buffer, data, &data_bytes);
32407  if (rc != TPM_RC_SUCCESS) {
32408    return rc;
32409  }
32410  if (tag == TPM_ST_SESSIONS) {
32411    CHECK(authorization_delegate) << "Authorization delegate missing!";
32412    // Decrypt just the parameter data, not the size.
32413    std::string tmp = data_bytes.substr(2);
32414    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
32415      return TRUNKS_RC_ENCRYPTION_FAILED;
32416    }
32417    data_bytes.replace(2, std::string::npos, tmp);
32418    rc = Parse_TPM2B_MAX_NV_BUFFER(&data_bytes, data, nullptr);
32419    if (rc != TPM_RC_SUCCESS) {
32420      return rc;
32421    }
32422  }
32423  return TPM_RC_SUCCESS;
32424}
32425
32426void NV_ReadErrorCallback(const Tpm::NV_ReadResponse& callback,
32427                          TPM_RC response_code) {
32428  VLOG(1) << __func__;
32429  callback.Run(response_code, TPM2B_MAX_NV_BUFFER());
32430}
32431
32432void NV_ReadResponseParser(const Tpm::NV_ReadResponse& callback,
32433                           AuthorizationDelegate* authorization_delegate,
32434                           const std::string& response) {
32435  VLOG(1) << __func__;
32436  base::Callback<void(TPM_RC)> error_reporter =
32437      base::Bind(NV_ReadErrorCallback, callback);
32438  TPM2B_MAX_NV_BUFFER data;
32439  TPM_RC rc =
32440      Tpm::ParseResponse_NV_Read(response, &data, authorization_delegate);
32441  if (rc != TPM_RC_SUCCESS) {
32442    error_reporter.Run(rc);
32443    return;
32444  }
32445  callback.Run(rc, data);
32446}
32447
32448void Tpm::NV_Read(const TPMI_RH_NV_AUTH& auth_handle,
32449                  const std::string& auth_handle_name,
32450                  const TPMI_RH_NV_INDEX& nv_index,
32451                  const std::string& nv_index_name,
32452                  const UINT16& size,
32453                  const UINT16& offset,
32454                  AuthorizationDelegate* authorization_delegate,
32455                  const NV_ReadResponse& callback) {
32456  VLOG(1) << __func__;
32457  base::Callback<void(TPM_RC)> error_reporter =
32458      base::Bind(NV_ReadErrorCallback, callback);
32459  base::Callback<void(const std::string&)> parser =
32460      base::Bind(NV_ReadResponseParser, callback, authorization_delegate);
32461  std::string command;
32462  TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32463                                       nv_index_name, size, offset, &command,
32464                                       authorization_delegate);
32465  if (rc != TPM_RC_SUCCESS) {
32466    error_reporter.Run(rc);
32467    return;
32468  }
32469  transceiver_->SendCommand(command, parser);
32470}
32471
32472TPM_RC Tpm::NV_ReadSync(const TPMI_RH_NV_AUTH& auth_handle,
32473                        const std::string& auth_handle_name,
32474                        const TPMI_RH_NV_INDEX& nv_index,
32475                        const std::string& nv_index_name,
32476                        const UINT16& size,
32477                        const UINT16& offset,
32478                        TPM2B_MAX_NV_BUFFER* data,
32479                        AuthorizationDelegate* authorization_delegate) {
32480  VLOG(1) << __func__;
32481  std::string command;
32482  TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32483                                       nv_index_name, size, offset, &command,
32484                                       authorization_delegate);
32485  if (rc != TPM_RC_SUCCESS) {
32486    return rc;
32487  }
32488  std::string response = transceiver_->SendCommandAndWait(command);
32489  rc = ParseResponse_NV_Read(response, data, authorization_delegate);
32490  return rc;
32491}
32492
32493TPM_RC Tpm::SerializeCommand_NV_ReadLock(
32494    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    std::string* serialized_command,
32499    AuthorizationDelegate* authorization_delegate) {
32500  VLOG(3) << __func__;
32501  TPM_RC rc = TPM_RC_SUCCESS;
32502  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32503  UINT32 command_size = 10;  // Header size.
32504  std::string handle_section_bytes;
32505  std::string parameter_section_bytes;
32506  TPM_CC command_code = TPM_CC_NV_ReadLock;
32507  bool is_command_parameter_encryption_possible = false;
32508  bool is_response_parameter_encryption_possible = false;
32509  std::string command_code_bytes;
32510  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32511  if (rc != TPM_RC_SUCCESS) {
32512    return rc;
32513  }
32514  std::string auth_handle_bytes;
32515  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32516  if (rc != TPM_RC_SUCCESS) {
32517    return rc;
32518  }
32519  std::string nv_index_bytes;
32520  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32521  if (rc != TPM_RC_SUCCESS) {
32522    return rc;
32523  }
32524  std::unique_ptr<crypto::SecureHash> hash(
32525      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32526  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32527  hash->Update(auth_handle_name.data(), auth_handle_name.size());
32528  handle_section_bytes += auth_handle_bytes;
32529  command_size += auth_handle_bytes.size();
32530  hash->Update(nv_index_name.data(), nv_index_name.size());
32531  handle_section_bytes += nv_index_bytes;
32532  command_size += nv_index_bytes.size();
32533  std::string command_hash(32, 0);
32534  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
32535  std::string authorization_section_bytes;
32536  std::string authorization_size_bytes;
32537  if (authorization_delegate) {
32538    if (!authorization_delegate->GetCommandAuthorization(
32539            command_hash, is_command_parameter_encryption_possible,
32540            is_response_parameter_encryption_possible,
32541            &authorization_section_bytes)) {
32542      return TRUNKS_RC_AUTHORIZATION_FAILED;
32543    }
32544    if (!authorization_section_bytes.empty()) {
32545      tag = TPM_ST_SESSIONS;
32546      std::string tmp;
32547      rc = Serialize_UINT32(authorization_section_bytes.size(),
32548                            &authorization_size_bytes);
32549      if (rc != TPM_RC_SUCCESS) {
32550        return rc;
32551      }
32552      command_size +=
32553          authorization_size_bytes.size() + authorization_section_bytes.size();
32554    }
32555  }
32556  std::string tag_bytes;
32557  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32558  if (rc != TPM_RC_SUCCESS) {
32559    return rc;
32560  }
32561  std::string command_size_bytes;
32562  rc = Serialize_UINT32(command_size, &command_size_bytes);
32563  if (rc != TPM_RC_SUCCESS) {
32564    return rc;
32565  }
32566  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32567                        handle_section_bytes + authorization_size_bytes +
32568                        authorization_section_bytes + parameter_section_bytes;
32569  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32570  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
32571                                            serialized_command->size());
32572  return TPM_RC_SUCCESS;
32573}
32574
32575TPM_RC Tpm::ParseResponse_NV_ReadLock(
32576    const std::string& response,
32577    AuthorizationDelegate* authorization_delegate) {
32578  VLOG(3) << __func__;
32579  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32580  TPM_RC rc = TPM_RC_SUCCESS;
32581  std::string buffer(response);
32582  TPM_ST tag;
32583  std::string tag_bytes;
32584  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32585  if (rc != TPM_RC_SUCCESS) {
32586    return rc;
32587  }
32588  UINT32 response_size;
32589  std::string response_size_bytes;
32590  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32591  if (rc != TPM_RC_SUCCESS) {
32592    return rc;
32593  }
32594  TPM_RC response_code;
32595  std::string response_code_bytes;
32596  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32597  if (rc != TPM_RC_SUCCESS) {
32598    return rc;
32599  }
32600  if (response_size != response.size()) {
32601    return TPM_RC_SIZE;
32602  }
32603  if (response_code != TPM_RC_SUCCESS) {
32604    return response_code;
32605  }
32606  TPM_CC command_code = TPM_CC_NV_ReadLock;
32607  std::string command_code_bytes;
32608  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32609  if (rc != TPM_RC_SUCCESS) {
32610    return rc;
32611  }
32612  std::string authorization_section_bytes;
32613  if (tag == TPM_ST_SESSIONS) {
32614    UINT32 parameter_section_size = buffer.size();
32615    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32616    if (rc != TPM_RC_SUCCESS) {
32617      return rc;
32618    }
32619    if (parameter_section_size > buffer.size()) {
32620      return TPM_RC_INSUFFICIENT;
32621    }
32622    authorization_section_bytes = buffer.substr(parameter_section_size);
32623    // Keep the parameter section in |buffer|.
32624    buffer.erase(parameter_section_size);
32625  }
32626  std::unique_ptr<crypto::SecureHash> hash(
32627      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32628  hash->Update(response_code_bytes.data(), response_code_bytes.size());
32629  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32630  hash->Update(buffer.data(), buffer.size());
32631  std::string response_hash(32, 0);
32632  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
32633  if (tag == TPM_ST_SESSIONS) {
32634    CHECK(authorization_delegate) << "Authorization delegate missing!";
32635    if (!authorization_delegate->CheckResponseAuthorization(
32636            response_hash, authorization_section_bytes)) {
32637      return TRUNKS_RC_AUTHORIZATION_FAILED;
32638    }
32639  }
32640  return TPM_RC_SUCCESS;
32641}
32642
32643void NV_ReadLockErrorCallback(const Tpm::NV_ReadLockResponse& callback,
32644                              TPM_RC response_code) {
32645  VLOG(1) << __func__;
32646  callback.Run(response_code);
32647}
32648
32649void NV_ReadLockResponseParser(const Tpm::NV_ReadLockResponse& callback,
32650                               AuthorizationDelegate* authorization_delegate,
32651                               const std::string& response) {
32652  VLOG(1) << __func__;
32653  base::Callback<void(TPM_RC)> error_reporter =
32654      base::Bind(NV_ReadLockErrorCallback, callback);
32655  TPM_RC rc = Tpm::ParseResponse_NV_ReadLock(response, authorization_delegate);
32656  if (rc != TPM_RC_SUCCESS) {
32657    error_reporter.Run(rc);
32658    return;
32659  }
32660  callback.Run(rc);
32661}
32662
32663void Tpm::NV_ReadLock(const TPMI_RH_NV_AUTH& auth_handle,
32664                      const std::string& auth_handle_name,
32665                      const TPMI_RH_NV_INDEX& nv_index,
32666                      const std::string& nv_index_name,
32667                      AuthorizationDelegate* authorization_delegate,
32668                      const NV_ReadLockResponse& callback) {
32669  VLOG(1) << __func__;
32670  base::Callback<void(TPM_RC)> error_reporter =
32671      base::Bind(NV_ReadLockErrorCallback, callback);
32672  base::Callback<void(const std::string&)> parser =
32673      base::Bind(NV_ReadLockResponseParser, callback, authorization_delegate);
32674  std::string command;
32675  TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
32676                                           nv_index, nv_index_name, &command,
32677                                           authorization_delegate);
32678  if (rc != TPM_RC_SUCCESS) {
32679    error_reporter.Run(rc);
32680    return;
32681  }
32682  transceiver_->SendCommand(command, parser);
32683}
32684
32685TPM_RC Tpm::NV_ReadLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32686                            const std::string& auth_handle_name,
32687                            const TPMI_RH_NV_INDEX& nv_index,
32688                            const std::string& nv_index_name,
32689                            AuthorizationDelegate* authorization_delegate) {
32690  VLOG(1) << __func__;
32691  std::string command;
32692  TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
32693                                           nv_index, nv_index_name, &command,
32694                                           authorization_delegate);
32695  if (rc != TPM_RC_SUCCESS) {
32696    return rc;
32697  }
32698  std::string response = transceiver_->SendCommandAndWait(command);
32699  rc = ParseResponse_NV_ReadLock(response, authorization_delegate);
32700  return rc;
32701}
32702
32703TPM_RC Tpm::SerializeCommand_NV_ChangeAuth(
32704    const TPMI_RH_NV_INDEX& nv_index,
32705    const std::string& nv_index_name,
32706    const TPM2B_AUTH& new_auth,
32707    std::string* serialized_command,
32708    AuthorizationDelegate* authorization_delegate) {
32709  VLOG(3) << __func__;
32710  TPM_RC rc = TPM_RC_SUCCESS;
32711  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32712  UINT32 command_size = 10;  // Header size.
32713  std::string handle_section_bytes;
32714  std::string parameter_section_bytes;
32715  TPM_CC command_code = TPM_CC_NV_ChangeAuth;
32716  bool is_command_parameter_encryption_possible = true;
32717  bool is_response_parameter_encryption_possible = false;
32718  std::string command_code_bytes;
32719  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32720  if (rc != TPM_RC_SUCCESS) {
32721    return rc;
32722  }
32723  std::string nv_index_bytes;
32724  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32725  if (rc != TPM_RC_SUCCESS) {
32726    return rc;
32727  }
32728  std::string new_auth_bytes;
32729  rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
32730  if (rc != TPM_RC_SUCCESS) {
32731    return rc;
32732  }
32733  if (authorization_delegate) {
32734    // Encrypt just the parameter data, not the size.
32735    std::string tmp = new_auth_bytes.substr(2);
32736    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
32737      return TRUNKS_RC_ENCRYPTION_FAILED;
32738    }
32739    new_auth_bytes.replace(2, std::string::npos, tmp);
32740  }
32741  std::unique_ptr<crypto::SecureHash> hash(
32742      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32743  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32744  hash->Update(nv_index_name.data(), nv_index_name.size());
32745  handle_section_bytes += nv_index_bytes;
32746  command_size += nv_index_bytes.size();
32747  hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
32748  parameter_section_bytes += new_auth_bytes;
32749  command_size += new_auth_bytes.size();
32750  std::string command_hash(32, 0);
32751  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
32752  std::string authorization_section_bytes;
32753  std::string authorization_size_bytes;
32754  if (authorization_delegate) {
32755    if (!authorization_delegate->GetCommandAuthorization(
32756            command_hash, is_command_parameter_encryption_possible,
32757            is_response_parameter_encryption_possible,
32758            &authorization_section_bytes)) {
32759      return TRUNKS_RC_AUTHORIZATION_FAILED;
32760    }
32761    if (!authorization_section_bytes.empty()) {
32762      tag = TPM_ST_SESSIONS;
32763      std::string tmp;
32764      rc = Serialize_UINT32(authorization_section_bytes.size(),
32765                            &authorization_size_bytes);
32766      if (rc != TPM_RC_SUCCESS) {
32767        return rc;
32768      }
32769      command_size +=
32770          authorization_size_bytes.size() + authorization_section_bytes.size();
32771    }
32772  }
32773  std::string tag_bytes;
32774  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32775  if (rc != TPM_RC_SUCCESS) {
32776    return rc;
32777  }
32778  std::string command_size_bytes;
32779  rc = Serialize_UINT32(command_size, &command_size_bytes);
32780  if (rc != TPM_RC_SUCCESS) {
32781    return rc;
32782  }
32783  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32784                        handle_section_bytes + authorization_size_bytes +
32785                        authorization_section_bytes + parameter_section_bytes;
32786  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32787  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
32788                                            serialized_command->size());
32789  return TPM_RC_SUCCESS;
32790}
32791
32792TPM_RC Tpm::ParseResponse_NV_ChangeAuth(
32793    const std::string& response,
32794    AuthorizationDelegate* authorization_delegate) {
32795  VLOG(3) << __func__;
32796  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32797  TPM_RC rc = TPM_RC_SUCCESS;
32798  std::string buffer(response);
32799  TPM_ST tag;
32800  std::string tag_bytes;
32801  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32802  if (rc != TPM_RC_SUCCESS) {
32803    return rc;
32804  }
32805  UINT32 response_size;
32806  std::string response_size_bytes;
32807  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32808  if (rc != TPM_RC_SUCCESS) {
32809    return rc;
32810  }
32811  TPM_RC response_code;
32812  std::string response_code_bytes;
32813  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32814  if (rc != TPM_RC_SUCCESS) {
32815    return rc;
32816  }
32817  if (response_size != response.size()) {
32818    return TPM_RC_SIZE;
32819  }
32820  if (response_code != TPM_RC_SUCCESS) {
32821    return response_code;
32822  }
32823  TPM_CC command_code = TPM_CC_NV_ChangeAuth;
32824  std::string command_code_bytes;
32825  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32826  if (rc != TPM_RC_SUCCESS) {
32827    return rc;
32828  }
32829  std::string authorization_section_bytes;
32830  if (tag == TPM_ST_SESSIONS) {
32831    UINT32 parameter_section_size = buffer.size();
32832    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32833    if (rc != TPM_RC_SUCCESS) {
32834      return rc;
32835    }
32836    if (parameter_section_size > buffer.size()) {
32837      return TPM_RC_INSUFFICIENT;
32838    }
32839    authorization_section_bytes = buffer.substr(parameter_section_size);
32840    // Keep the parameter section in |buffer|.
32841    buffer.erase(parameter_section_size);
32842  }
32843  std::unique_ptr<crypto::SecureHash> hash(
32844      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32845  hash->Update(response_code_bytes.data(), response_code_bytes.size());
32846  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32847  hash->Update(buffer.data(), buffer.size());
32848  std::string response_hash(32, 0);
32849  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
32850  if (tag == TPM_ST_SESSIONS) {
32851    CHECK(authorization_delegate) << "Authorization delegate missing!";
32852    if (!authorization_delegate->CheckResponseAuthorization(
32853            response_hash, authorization_section_bytes)) {
32854      return TRUNKS_RC_AUTHORIZATION_FAILED;
32855    }
32856  }
32857  return TPM_RC_SUCCESS;
32858}
32859
32860void NV_ChangeAuthErrorCallback(const Tpm::NV_ChangeAuthResponse& callback,
32861                                TPM_RC response_code) {
32862  VLOG(1) << __func__;
32863  callback.Run(response_code);
32864}
32865
32866void NV_ChangeAuthResponseParser(const Tpm::NV_ChangeAuthResponse& callback,
32867                                 AuthorizationDelegate* authorization_delegate,
32868                                 const std::string& response) {
32869  VLOG(1) << __func__;
32870  base::Callback<void(TPM_RC)> error_reporter =
32871      base::Bind(NV_ChangeAuthErrorCallback, callback);
32872  TPM_RC rc =
32873      Tpm::ParseResponse_NV_ChangeAuth(response, authorization_delegate);
32874  if (rc != TPM_RC_SUCCESS) {
32875    error_reporter.Run(rc);
32876    return;
32877  }
32878  callback.Run(rc);
32879}
32880
32881void Tpm::NV_ChangeAuth(const TPMI_RH_NV_INDEX& nv_index,
32882                        const std::string& nv_index_name,
32883                        const TPM2B_AUTH& new_auth,
32884                        AuthorizationDelegate* authorization_delegate,
32885                        const NV_ChangeAuthResponse& callback) {
32886  VLOG(1) << __func__;
32887  base::Callback<void(TPM_RC)> error_reporter =
32888      base::Bind(NV_ChangeAuthErrorCallback, callback);
32889  base::Callback<void(const std::string&)> parser =
32890      base::Bind(NV_ChangeAuthResponseParser, callback, authorization_delegate);
32891  std::string command;
32892  TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
32893                                             &command, authorization_delegate);
32894  if (rc != TPM_RC_SUCCESS) {
32895    error_reporter.Run(rc);
32896    return;
32897  }
32898  transceiver_->SendCommand(command, parser);
32899}
32900
32901TPM_RC Tpm::NV_ChangeAuthSync(const TPMI_RH_NV_INDEX& nv_index,
32902                              const std::string& nv_index_name,
32903                              const TPM2B_AUTH& new_auth,
32904                              AuthorizationDelegate* authorization_delegate) {
32905  VLOG(1) << __func__;
32906  std::string command;
32907  TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
32908                                             &command, authorization_delegate);
32909  if (rc != TPM_RC_SUCCESS) {
32910    return rc;
32911  }
32912  std::string response = transceiver_->SendCommandAndWait(command);
32913  rc = ParseResponse_NV_ChangeAuth(response, authorization_delegate);
32914  return rc;
32915}
32916
32917TPM_RC Tpm::SerializeCommand_NV_Certify(
32918    const TPMI_DH_OBJECT& sign_handle,
32919    const std::string& sign_handle_name,
32920    const TPMI_RH_NV_AUTH& auth_handle,
32921    const std::string& auth_handle_name,
32922    const TPMI_RH_NV_INDEX& nv_index,
32923    const std::string& nv_index_name,
32924    const TPM2B_DATA& qualifying_data,
32925    const TPMT_SIG_SCHEME& in_scheme,
32926    const UINT16& size,
32927    const UINT16& offset,
32928    std::string* serialized_command,
32929    AuthorizationDelegate* authorization_delegate) {
32930  VLOG(3) << __func__;
32931  TPM_RC rc = TPM_RC_SUCCESS;
32932  TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32933  UINT32 command_size = 10;  // Header size.
32934  std::string handle_section_bytes;
32935  std::string parameter_section_bytes;
32936  TPM_CC command_code = TPM_CC_NV_Certify;
32937  bool is_command_parameter_encryption_possible = true;
32938  bool is_response_parameter_encryption_possible = true;
32939  std::string command_code_bytes;
32940  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32941  if (rc != TPM_RC_SUCCESS) {
32942    return rc;
32943  }
32944  std::string sign_handle_bytes;
32945  rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
32946  if (rc != TPM_RC_SUCCESS) {
32947    return rc;
32948  }
32949  std::string auth_handle_bytes;
32950  rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32951  if (rc != TPM_RC_SUCCESS) {
32952    return rc;
32953  }
32954  std::string nv_index_bytes;
32955  rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32956  if (rc != TPM_RC_SUCCESS) {
32957    return rc;
32958  }
32959  std::string qualifying_data_bytes;
32960  rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
32961  if (rc != TPM_RC_SUCCESS) {
32962    return rc;
32963  }
32964  std::string in_scheme_bytes;
32965  rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
32966  if (rc != TPM_RC_SUCCESS) {
32967    return rc;
32968  }
32969  std::string size_bytes;
32970  rc = Serialize_UINT16(size, &size_bytes);
32971  if (rc != TPM_RC_SUCCESS) {
32972    return rc;
32973  }
32974  std::string offset_bytes;
32975  rc = Serialize_UINT16(offset, &offset_bytes);
32976  if (rc != TPM_RC_SUCCESS) {
32977    return rc;
32978  }
32979  if (authorization_delegate) {
32980    // Encrypt just the parameter data, not the size.
32981    std::string tmp = qualifying_data_bytes.substr(2);
32982    if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
32983      return TRUNKS_RC_ENCRYPTION_FAILED;
32984    }
32985    qualifying_data_bytes.replace(2, std::string::npos, tmp);
32986  }
32987  std::unique_ptr<crypto::SecureHash> hash(
32988      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32989  hash->Update(command_code_bytes.data(), command_code_bytes.size());
32990  hash->Update(sign_handle_name.data(), sign_handle_name.size());
32991  handle_section_bytes += sign_handle_bytes;
32992  command_size += sign_handle_bytes.size();
32993  hash->Update(auth_handle_name.data(), auth_handle_name.size());
32994  handle_section_bytes += auth_handle_bytes;
32995  command_size += auth_handle_bytes.size();
32996  hash->Update(nv_index_name.data(), nv_index_name.size());
32997  handle_section_bytes += nv_index_bytes;
32998  command_size += nv_index_bytes.size();
32999  hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
33000  parameter_section_bytes += qualifying_data_bytes;
33001  command_size += qualifying_data_bytes.size();
33002  hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
33003  parameter_section_bytes += in_scheme_bytes;
33004  command_size += in_scheme_bytes.size();
33005  hash->Update(size_bytes.data(), size_bytes.size());
33006  parameter_section_bytes += size_bytes;
33007  command_size += size_bytes.size();
33008  hash->Update(offset_bytes.data(), offset_bytes.size());
33009  parameter_section_bytes += offset_bytes;
33010  command_size += offset_bytes.size();
33011  std::string command_hash(32, 0);
33012  hash->Finish(base::string_as_array(&command_hash), command_hash.size());
33013  std::string authorization_section_bytes;
33014  std::string authorization_size_bytes;
33015  if (authorization_delegate) {
33016    if (!authorization_delegate->GetCommandAuthorization(
33017            command_hash, is_command_parameter_encryption_possible,
33018            is_response_parameter_encryption_possible,
33019            &authorization_section_bytes)) {
33020      return TRUNKS_RC_AUTHORIZATION_FAILED;
33021    }
33022    if (!authorization_section_bytes.empty()) {
33023      tag = TPM_ST_SESSIONS;
33024      std::string tmp;
33025      rc = Serialize_UINT32(authorization_section_bytes.size(),
33026                            &authorization_size_bytes);
33027      if (rc != TPM_RC_SUCCESS) {
33028        return rc;
33029      }
33030      command_size +=
33031          authorization_size_bytes.size() + authorization_section_bytes.size();
33032    }
33033  }
33034  std::string tag_bytes;
33035  rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33036  if (rc != TPM_RC_SUCCESS) {
33037    return rc;
33038  }
33039  std::string command_size_bytes;
33040  rc = Serialize_UINT32(command_size, &command_size_bytes);
33041  if (rc != TPM_RC_SUCCESS) {
33042    return rc;
33043  }
33044  *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33045                        handle_section_bytes + authorization_size_bytes +
33046                        authorization_section_bytes + parameter_section_bytes;
33047  CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33048  VLOG(2) << "Command: " << base::HexEncode(serialized_command->data(),
33049                                            serialized_command->size());
33050  return TPM_RC_SUCCESS;
33051}
33052
33053TPM_RC Tpm::ParseResponse_NV_Certify(
33054    const std::string& response,
33055    TPM2B_ATTEST* certify_info,
33056    TPMT_SIGNATURE* signature,
33057    AuthorizationDelegate* authorization_delegate) {
33058  VLOG(3) << __func__;
33059  VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33060  TPM_RC rc = TPM_RC_SUCCESS;
33061  std::string buffer(response);
33062  TPM_ST tag;
33063  std::string tag_bytes;
33064  rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33065  if (rc != TPM_RC_SUCCESS) {
33066    return rc;
33067  }
33068  UINT32 response_size;
33069  std::string response_size_bytes;
33070  rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33071  if (rc != TPM_RC_SUCCESS) {
33072    return rc;
33073  }
33074  TPM_RC response_code;
33075  std::string response_code_bytes;
33076  rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33077  if (rc != TPM_RC_SUCCESS) {
33078    return rc;
33079  }
33080  if (response_size != response.size()) {
33081    return TPM_RC_SIZE;
33082  }
33083  if (response_code != TPM_RC_SUCCESS) {
33084    return response_code;
33085  }
33086  TPM_CC command_code = TPM_CC_NV_Certify;
33087  std::string command_code_bytes;
33088  rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33089  if (rc != TPM_RC_SUCCESS) {
33090    return rc;
33091  }
33092  std::string authorization_section_bytes;
33093  if (tag == TPM_ST_SESSIONS) {
33094    UINT32 parameter_section_size = buffer.size();
33095    rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33096    if (rc != TPM_RC_SUCCESS) {
33097      return rc;
33098    }
33099    if (parameter_section_size > buffer.size()) {
33100      return TPM_RC_INSUFFICIENT;
33101    }
33102    authorization_section_bytes = buffer.substr(parameter_section_size);
33103    // Keep the parameter section in |buffer|.
33104    buffer.erase(parameter_section_size);
33105  }
33106  std::unique_ptr<crypto::SecureHash> hash(
33107      crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33108  hash->Update(response_code_bytes.data(), response_code_bytes.size());
33109  hash->Update(command_code_bytes.data(), command_code_bytes.size());
33110  hash->Update(buffer.data(), buffer.size());
33111  std::string response_hash(32, 0);
33112  hash->Finish(base::string_as_array(&response_hash), response_hash.size());
33113  if (tag == TPM_ST_SESSIONS) {
33114    CHECK(authorization_delegate) << "Authorization delegate missing!";
33115    if (!authorization_delegate->CheckResponseAuthorization(
33116            response_hash, authorization_section_bytes)) {
33117      return TRUNKS_RC_AUTHORIZATION_FAILED;
33118    }
33119  }
33120  std::string certify_info_bytes;
33121  rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
33122  if (rc != TPM_RC_SUCCESS) {
33123    return rc;
33124  }
33125  std::string signature_bytes;
33126  rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
33127  if (rc != TPM_RC_SUCCESS) {
33128    return rc;
33129  }
33130  if (tag == TPM_ST_SESSIONS) {
33131    CHECK(authorization_delegate) << "Authorization delegate missing!";
33132    // Decrypt just the parameter data, not the size.
33133    std::string tmp = certify_info_bytes.substr(2);
33134    if (!authorization_delegate->DecryptResponseParameter(&tmp)) {
33135      return TRUNKS_RC_ENCRYPTION_FAILED;
33136    }
33137    certify_info_bytes.replace(2, std::string::npos, tmp);
33138    rc = Parse_TPM2B_ATTEST(&certify_info_bytes, certify_info, nullptr);
33139    if (rc != TPM_RC_SUCCESS) {
33140      return rc;
33141    }
33142  }
33143  return TPM_RC_SUCCESS;
33144}
33145
33146void NV_CertifyErrorCallback(const Tpm::NV_CertifyResponse& callback,
33147                             TPM_RC response_code) {
33148  VLOG(1) << __func__;
33149  callback.Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
33150}
33151
33152void NV_CertifyResponseParser(const Tpm::NV_CertifyResponse& callback,
33153                              AuthorizationDelegate* authorization_delegate,
33154                              const std::string& response) {
33155  VLOG(1) << __func__;
33156  base::Callback<void(TPM_RC)> error_reporter =
33157      base::Bind(NV_CertifyErrorCallback, callback);
33158  TPM2B_ATTEST certify_info;
33159  TPMT_SIGNATURE signature;
33160  TPM_RC rc = Tpm::ParseResponse_NV_Certify(response, &certify_info, &signature,
33161                                            authorization_delegate);
33162  if (rc != TPM_RC_SUCCESS) {
33163    error_reporter.Run(rc);
33164    return;
33165  }
33166  callback.Run(rc, certify_info, signature);
33167}
33168
33169void Tpm::NV_Certify(const TPMI_DH_OBJECT& sign_handle,
33170                     const std::string& sign_handle_name,
33171                     const TPMI_RH_NV_AUTH& auth_handle,
33172                     const std::string& auth_handle_name,
33173                     const TPMI_RH_NV_INDEX& nv_index,
33174                     const std::string& nv_index_name,
33175                     const TPM2B_DATA& qualifying_data,
33176                     const TPMT_SIG_SCHEME& in_scheme,
33177                     const UINT16& size,
33178                     const UINT16& offset,
33179                     AuthorizationDelegate* authorization_delegate,
33180                     const NV_CertifyResponse& callback) {
33181  VLOG(1) << __func__;
33182  base::Callback<void(TPM_RC)> error_reporter =
33183      base::Bind(NV_CertifyErrorCallback, callback);
33184  base::Callback<void(const std::string&)> parser =
33185      base::Bind(NV_CertifyResponseParser, callback, authorization_delegate);
33186  std::string command;
33187  TPM_RC rc = SerializeCommand_NV_Certify(
33188      sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33189      nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33190      authorization_delegate);
33191  if (rc != TPM_RC_SUCCESS) {
33192    error_reporter.Run(rc);
33193    return;
33194  }
33195  transceiver_->SendCommand(command, parser);
33196}
33197
33198TPM_RC Tpm::NV_CertifySync(const TPMI_DH_OBJECT& sign_handle,
33199                           const std::string& sign_handle_name,
33200                           const TPMI_RH_NV_AUTH& auth_handle,
33201                           const std::string& auth_handle_name,
33202                           const TPMI_RH_NV_INDEX& nv_index,
33203                           const std::string& nv_index_name,
33204                           const TPM2B_DATA& qualifying_data,
33205                           const TPMT_SIG_SCHEME& in_scheme,
33206                           const UINT16& size,
33207                           const UINT16& offset,
33208                           TPM2B_ATTEST* certify_info,
33209                           TPMT_SIGNATURE* signature,
33210                           AuthorizationDelegate* authorization_delegate) {
33211  VLOG(1) << __func__;
33212  std::string command;
33213  TPM_RC rc = SerializeCommand_NV_Certify(
33214      sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33215      nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33216      authorization_delegate);
33217  if (rc != TPM_RC_SUCCESS) {
33218    return rc;
33219  }
33220  std::string response = transceiver_->SendCommandAndWait(command);
33221  rc = ParseResponse_NV_Certify(response, certify_info, signature,
33222                                authorization_delegate);
33223  return rc;
33224}
33225
33226}  // namespace trunks
33227