| // Copyright 2014 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // THIS CODE IS GENERATED - DO NOT MODIFY! |
| |
| #include "trunks/tpm_generated.h" |
| |
| #include <string> |
| |
| #include <base/basictypes.h> |
| #include <base/bind.h> |
| #include <base/callback.h> |
| #include <base/logging.h> |
| #include <base/stl_util.h> |
| #include <base/strings/string_number_conversions.h> |
| #include <base/sys_byteorder.h> |
| #include <crypto/secure_hash.h> |
| |
| #include "trunks/authorization_delegate.h" |
| #include "trunks/command_transceiver.h" |
| #include "trunks/error_codes.h" |
| |
| |
| namespace trunks { |
| |
| size_t GetNumberOfRequestHandles(TPM_CC command_code) { |
| switch (command_code) { |
| case TPM_CC_Startup: return 0; |
| case TPM_CC_Shutdown: return 0; |
| case TPM_CC_SelfTest: return 0; |
| case TPM_CC_IncrementalSelfTest: return 0; |
| case TPM_CC_GetTestResult: return 0; |
| case TPM_CC_StartAuthSession: return 2; |
| case TPM_CC_PolicyRestart: return 1; |
| case TPM_CC_Create: return 1; |
| case TPM_CC_Load: return 1; |
| case TPM_CC_LoadExternal: return 1; |
| case TPM_CC_ReadPublic: return 1; |
| case TPM_CC_ActivateCredential: return 2; |
| case TPM_CC_MakeCredential: return 1; |
| case TPM_CC_Unseal: return 1; |
| case TPM_CC_ObjectChangeAuth: return 2; |
| case TPM_CC_Duplicate: return 2; |
| case TPM_CC_Rewrap: return 2; |
| case TPM_CC_Import: return 1; |
| case TPM_CC_RSA_Encrypt: return 1; |
| case TPM_CC_RSA_Decrypt: return 1; |
| case TPM_CC_ECDH_KeyGen: return 1; |
| case TPM_CC_ECDH_ZGen: return 1; |
| case TPM_CC_ECC_Parameters: return 0; |
| case TPM_CC_ZGen_2Phase: return 1; |
| case TPM_CC_EncryptDecrypt: return 1; |
| case TPM_CC_Hash: return 1; |
| case TPM_CC_HMAC: return 1; |
| case TPM_CC_GetRandom: return 0; |
| case TPM_CC_StirRandom: return 0; |
| case TPM_CC_HMAC_Start: return 1; |
| case TPM_CC_HashSequenceStart: return 0; |
| case TPM_CC_SequenceUpdate: return 1; |
| case TPM_CC_SequenceComplete: return 2; |
| case TPM_CC_EventSequenceComplete: return 2; |
| case TPM_CC_Certify: return 2; |
| case TPM_CC_CertifyCreation: return 2; |
| case TPM_CC_Quote: return 1; |
| case TPM_CC_GetSessionAuditDigest: return 3; |
| case TPM_CC_GetCommandAuditDigest: return 2; |
| case TPM_CC_GetTime: return 2; |
| case TPM_CC_Commit: return 1; |
| case TPM_CC_EC_Ephemeral: return 0; |
| case TPM_CC_VerifySignature: return 1; |
| case TPM_CC_Sign: return 1; |
| case TPM_CC_SetCommandCodeAuditStatus: return 1; |
| case TPM_CC_PCR_Extend: return 1; |
| case TPM_CC_PCR_Event: return 1; |
| case TPM_CC_PCR_Read: return 0; |
| case TPM_CC_PCR_Allocate: return 1; |
| case TPM_CC_PCR_SetAuthPolicy: return 2; |
| case TPM_CC_PCR_SetAuthValue: return 1; |
| case TPM_CC_PCR_Reset: return 1; |
| case TPM_CC_PolicySigned: return 2; |
| case TPM_CC_PolicySecret: return 2; |
| case TPM_CC_PolicyTicket: return 1; |
| case TPM_CC_PolicyOR: return 1; |
| case TPM_CC_PolicyPCR: return 1; |
| case TPM_CC_PolicyLocality: return 1; |
| case TPM_CC_PolicyNV: return 3; |
| case TPM_CC_PolicyCounterTimer: return 1; |
| case TPM_CC_PolicyCommandCode: return 1; |
| case TPM_CC_PolicyPhysicalPresence: return 1; |
| case TPM_CC_PolicyCpHash: return 1; |
| case TPM_CC_PolicyNameHash: return 1; |
| case TPM_CC_PolicyDuplicationSelect: return 1; |
| case TPM_CC_PolicyAuthorize: return 1; |
| case TPM_CC_PolicyAuthValue: return 1; |
| case TPM_CC_PolicyPassword: return 1; |
| case TPM_CC_PolicyGetDigest: return 1; |
| case TPM_CC_PolicyNvWritten: return 1; |
| case TPM_CC_CreatePrimary: return 1; |
| case TPM_CC_HierarchyControl: return 1; |
| case TPM_CC_SetPrimaryPolicy: return 1; |
| case TPM_CC_ChangePPS: return 1; |
| case TPM_CC_ChangeEPS: return 1; |
| case TPM_CC_Clear: return 1; |
| case TPM_CC_ClearControl: return 1; |
| case TPM_CC_HierarchyChangeAuth: return 1; |
| case TPM_CC_DictionaryAttackLockReset: return 1; |
| case TPM_CC_DictionaryAttackParameters: return 1; |
| case TPM_CC_PP_Commands: return 1; |
| case TPM_CC_SetAlgorithmSet: return 1; |
| case TPM_CC_FieldUpgradeStart: return 2; |
| case TPM_CC_FieldUpgradeData: return 0; |
| case TPM_CC_FirmwareRead: return 0; |
| case TPM_CC_ContextSave: return 1; |
| case TPM_CC_ContextLoad: return 0; |
| case TPM_CC_FlushContext: return 0; |
| case TPM_CC_EvictControl: return 2; |
| case TPM_CC_ReadClock: return 0; |
| case TPM_CC_ClockSet: return 1; |
| case TPM_CC_ClockRateAdjust: return 1; |
| case TPM_CC_GetCapability: return 0; |
| case TPM_CC_TestParms: return 0; |
| case TPM_CC_NV_DefineSpace: return 1; |
| case TPM_CC_NV_UndefineSpace: return 2; |
| case TPM_CC_NV_UndefineSpaceSpecial: return 2; |
| case TPM_CC_NV_ReadPublic: return 1; |
| case TPM_CC_NV_Write: return 2; |
| case TPM_CC_NV_Increment: return 2; |
| case TPM_CC_NV_Extend: return 2; |
| case TPM_CC_NV_SetBits: return 2; |
| case TPM_CC_NV_WriteLock: return 2; |
| case TPM_CC_NV_GlobalWriteLock: return 1; |
| case TPM_CC_NV_Read: return 2; |
| case TPM_CC_NV_ReadLock: return 2; |
| case TPM_CC_NV_ChangeAuth: return 1; |
| case TPM_CC_NV_Certify: return 3; |
| default: NOTREACHED(); |
| } |
| return 0; |
| } |
| |
| size_t GetNumberOfResponseHandles(TPM_CC command_code) { |
| switch (command_code) { |
| case TPM_CC_Startup: return 0; |
| case TPM_CC_Shutdown: return 0; |
| case TPM_CC_SelfTest: return 0; |
| case TPM_CC_IncrementalSelfTest: return 0; |
| case TPM_CC_GetTestResult: return 0; |
| case TPM_CC_StartAuthSession: return 1; |
| case TPM_CC_PolicyRestart: return 0; |
| case TPM_CC_Create: return 0; |
| case TPM_CC_Load: return 1; |
| case TPM_CC_LoadExternal: return 1; |
| case TPM_CC_ReadPublic: return 0; |
| case TPM_CC_ActivateCredential: return 0; |
| case TPM_CC_MakeCredential: return 0; |
| case TPM_CC_Unseal: return 0; |
| case TPM_CC_ObjectChangeAuth: return 0; |
| case TPM_CC_Duplicate: return 0; |
| case TPM_CC_Rewrap: return 0; |
| case TPM_CC_Import: return 0; |
| case TPM_CC_RSA_Encrypt: return 0; |
| case TPM_CC_RSA_Decrypt: return 0; |
| case TPM_CC_ECDH_KeyGen: return 0; |
| case TPM_CC_ECDH_ZGen: return 0; |
| case TPM_CC_ECC_Parameters: return 0; |
| case TPM_CC_ZGen_2Phase: return 0; |
| case TPM_CC_EncryptDecrypt: return 0; |
| case TPM_CC_Hash: return 0; |
| case TPM_CC_HMAC: return 0; |
| case TPM_CC_GetRandom: return 0; |
| case TPM_CC_StirRandom: return 0; |
| case TPM_CC_HMAC_Start: return 1; |
| case TPM_CC_HashSequenceStart: return 1; |
| case TPM_CC_SequenceUpdate: return 0; |
| case TPM_CC_SequenceComplete: return 0; |
| case TPM_CC_EventSequenceComplete: return 0; |
| case TPM_CC_Certify: return 0; |
| case TPM_CC_CertifyCreation: return 0; |
| case TPM_CC_Quote: return 0; |
| case TPM_CC_GetSessionAuditDigest: return 0; |
| case TPM_CC_GetCommandAuditDigest: return 0; |
| case TPM_CC_GetTime: return 0; |
| case TPM_CC_Commit: return 0; |
| case TPM_CC_EC_Ephemeral: return 0; |
| case TPM_CC_VerifySignature: return 0; |
| case TPM_CC_Sign: return 0; |
| case TPM_CC_SetCommandCodeAuditStatus: return 0; |
| case TPM_CC_PCR_Extend: return 0; |
| case TPM_CC_PCR_Event: return 0; |
| case TPM_CC_PCR_Read: return 0; |
| case TPM_CC_PCR_Allocate: return 0; |
| case TPM_CC_PCR_SetAuthPolicy: return 0; |
| case TPM_CC_PCR_SetAuthValue: return 0; |
| case TPM_CC_PCR_Reset: return 0; |
| case TPM_CC_PolicySigned: return 0; |
| case TPM_CC_PolicySecret: return 0; |
| case TPM_CC_PolicyTicket: return 0; |
| case TPM_CC_PolicyOR: return 0; |
| case TPM_CC_PolicyPCR: return 0; |
| case TPM_CC_PolicyLocality: return 0; |
| case TPM_CC_PolicyNV: return 0; |
| case TPM_CC_PolicyCounterTimer: return 0; |
| case TPM_CC_PolicyCommandCode: return 0; |
| case TPM_CC_PolicyPhysicalPresence: return 0; |
| case TPM_CC_PolicyCpHash: return 0; |
| case TPM_CC_PolicyNameHash: return 0; |
| case TPM_CC_PolicyDuplicationSelect: return 0; |
| case TPM_CC_PolicyAuthorize: return 0; |
| case TPM_CC_PolicyAuthValue: return 0; |
| case TPM_CC_PolicyPassword: return 0; |
| case TPM_CC_PolicyGetDigest: return 0; |
| case TPM_CC_PolicyNvWritten: return 0; |
| case TPM_CC_CreatePrimary: return 1; |
| case TPM_CC_HierarchyControl: return 0; |
| case TPM_CC_SetPrimaryPolicy: return 0; |
| case TPM_CC_ChangePPS: return 0; |
| case TPM_CC_ChangeEPS: return 0; |
| case TPM_CC_Clear: return 0; |
| case TPM_CC_ClearControl: return 0; |
| case TPM_CC_HierarchyChangeAuth: return 0; |
| case TPM_CC_DictionaryAttackLockReset: return 0; |
| case TPM_CC_DictionaryAttackParameters: return 0; |
| case TPM_CC_PP_Commands: return 0; |
| case TPM_CC_SetAlgorithmSet: return 0; |
| case TPM_CC_FieldUpgradeStart: return 0; |
| case TPM_CC_FieldUpgradeData: return 0; |
| case TPM_CC_FirmwareRead: return 0; |
| case TPM_CC_ContextSave: return 0; |
| case TPM_CC_ContextLoad: return 1; |
| case TPM_CC_FlushContext: return 0; |
| case TPM_CC_EvictControl: return 0; |
| case TPM_CC_ReadClock: return 0; |
| case TPM_CC_ClockSet: return 0; |
| case TPM_CC_ClockRateAdjust: return 0; |
| case TPM_CC_GetCapability: return 0; |
| case TPM_CC_TestParms: return 0; |
| case TPM_CC_NV_DefineSpace: return 0; |
| case TPM_CC_NV_UndefineSpace: return 0; |
| case TPM_CC_NV_UndefineSpaceSpecial: return 0; |
| case TPM_CC_NV_ReadPublic: return 0; |
| case TPM_CC_NV_Write: return 0; |
| case TPM_CC_NV_Increment: return 0; |
| case TPM_CC_NV_Extend: return 0; |
| case TPM_CC_NV_SetBits: return 0; |
| case TPM_CC_NV_WriteLock: return 0; |
| case TPM_CC_NV_GlobalWriteLock: return 0; |
| case TPM_CC_NV_Read: return 0; |
| case TPM_CC_NV_ReadLock: return 0; |
| case TPM_CC_NV_ChangeAuth: return 0; |
| case TPM_CC_NV_Certify: return 0; |
| default: NOTREACHED(); |
| } |
| return 0; |
| } |
| |
| TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| uint8_t value_net = value; |
| switch (sizeof(uint8_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(uint8_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_uint8_t( |
| std::string* buffer, |
| uint8_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(uint8_t)) |
| return TPM_RC_INSUFFICIENT; |
| uint8_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(uint8_t)); |
| switch (sizeof(uint8_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(uint8_t))); |
| } |
| buffer->erase(0, sizeof(uint8_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| int8_t value_net = value; |
| switch (sizeof(int8_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(int8_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_int8_t( |
| std::string* buffer, |
| int8_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(int8_t)) |
| return TPM_RC_INSUFFICIENT; |
| int8_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(int8_t)); |
| switch (sizeof(int8_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(int8_t))); |
| } |
| buffer->erase(0, sizeof(int8_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_int(const int& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| int value_net = value; |
| switch (sizeof(int)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(int)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_int( |
| std::string* buffer, |
| int* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(int)) |
| return TPM_RC_INSUFFICIENT; |
| int value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(int)); |
| switch (sizeof(int)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(int))); |
| } |
| buffer->erase(0, sizeof(int)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| uint16_t value_net = value; |
| switch (sizeof(uint16_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(uint16_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_uint16_t( |
| std::string* buffer, |
| uint16_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(uint16_t)) |
| return TPM_RC_INSUFFICIENT; |
| uint16_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(uint16_t)); |
| switch (sizeof(uint16_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(uint16_t))); |
| } |
| buffer->erase(0, sizeof(uint16_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| int16_t value_net = value; |
| switch (sizeof(int16_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(int16_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_int16_t( |
| std::string* buffer, |
| int16_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(int16_t)) |
| return TPM_RC_INSUFFICIENT; |
| int16_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(int16_t)); |
| switch (sizeof(int16_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(int16_t))); |
| } |
| buffer->erase(0, sizeof(int16_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| uint32_t value_net = value; |
| switch (sizeof(uint32_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(uint32_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_uint32_t( |
| std::string* buffer, |
| uint32_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(uint32_t)) |
| return TPM_RC_INSUFFICIENT; |
| uint32_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(uint32_t)); |
| switch (sizeof(uint32_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(uint32_t))); |
| } |
| buffer->erase(0, sizeof(uint32_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| int32_t value_net = value; |
| switch (sizeof(int32_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(int32_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_int32_t( |
| std::string* buffer, |
| int32_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(int32_t)) |
| return TPM_RC_INSUFFICIENT; |
| int32_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(int32_t)); |
| switch (sizeof(int32_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(int32_t))); |
| } |
| buffer->erase(0, sizeof(int32_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| uint64_t value_net = value; |
| switch (sizeof(uint64_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(uint64_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_uint64_t( |
| std::string* buffer, |
| uint64_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(uint64_t)) |
| return TPM_RC_INSUFFICIENT; |
| uint64_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(uint64_t)); |
| switch (sizeof(uint64_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(uint64_t))); |
| } |
| buffer->erase(0, sizeof(uint64_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) { |
| VLOG(2) << __func__; |
| int64_t value_net = value; |
| switch (sizeof(int64_t)) { |
| case 2: |
| value_net = base::HostToNet16(value); |
| break; |
| case 4: |
| value_net = base::HostToNet32(value); |
| break; |
| case 8: |
| value_net = base::HostToNet64(value); |
| break; |
| default: |
| break; |
| } |
| const char* value_bytes = reinterpret_cast<const char*>(&value_net); |
| buffer->append(value_bytes, sizeof(int64_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Parse_int64_t( |
| std::string* buffer, |
| int64_t* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| if (buffer->size() < sizeof(int64_t)) |
| return TPM_RC_INSUFFICIENT; |
| int64_t value_net = 0; |
| memcpy(&value_net, buffer->data(), sizeof(int64_t)); |
| switch (sizeof(int64_t)) { |
| case 2: |
| *value = base::NetToHost16(value_net); |
| break; |
| case 4: |
| *value = base::NetToHost32(value_net); |
| break; |
| case 8: |
| *value = base::NetToHost64(value_net); |
| break; |
| default: |
| *value = value_net; |
| } |
| if (value_bytes) { |
| value_bytes->append(buffer->substr(0, sizeof(int64_t))); |
| } |
| buffer->erase(0, sizeof(int64_t)); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Serialize_UINT8( |
| const UINT8& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_uint8_t(value, buffer); |
| } |
| |
| TPM_RC Parse_UINT8( |
| std::string* buffer, |
| UINT8* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_uint8_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_BYTE( |
| const BYTE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_uint8_t(value, buffer); |
| } |
| |
| TPM_RC Parse_BYTE( |
| std::string* buffer, |
| BYTE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_uint8_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_INT8( |
| const INT8& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_int8_t(value, buffer); |
| } |
| |
| TPM_RC Parse_INT8( |
| std::string* buffer, |
| INT8* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_int8_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_BOOL( |
| const BOOL& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_int(value, buffer); |
| } |
| |
| TPM_RC Parse_BOOL( |
| std::string* buffer, |
| BOOL* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_int(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_UINT16( |
| const UINT16& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_uint16_t(value, buffer); |
| } |
| |
| TPM_RC Parse_UINT16( |
| std::string* buffer, |
| UINT16* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_uint16_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_INT16( |
| const INT16& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_int16_t(value, buffer); |
| } |
| |
| TPM_RC Parse_INT16( |
| std::string* buffer, |
| INT16* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_int16_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_UINT32( |
| const UINT32& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_uint32_t(value, buffer); |
| } |
| |
| TPM_RC Parse_UINT32( |
| std::string* buffer, |
| UINT32* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_uint32_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_INT32( |
| const INT32& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_int32_t(value, buffer); |
| } |
| |
| TPM_RC Parse_INT32( |
| std::string* buffer, |
| INT32* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_int32_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_UINT64( |
| const UINT64& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_uint64_t(value, buffer); |
| } |
| |
| TPM_RC Parse_UINT64( |
| std::string* buffer, |
| UINT64* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_uint64_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_INT64( |
| const INT64& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_int64_t(value, buffer); |
| } |
| |
| TPM_RC Parse_INT64( |
| std::string* buffer, |
| INT64* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_int64_t(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_ALGORITHM_ID( |
| const TPM_ALGORITHM_ID& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_ALGORITHM_ID( |
| std::string* buffer, |
| TPM_ALGORITHM_ID* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_MODIFIER_INDICATOR( |
| const TPM_MODIFIER_INDICATOR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_MODIFIER_INDICATOR( |
| std::string* buffer, |
| TPM_MODIFIER_INDICATOR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_AUTHORIZATION_SIZE( |
| const TPM_AUTHORIZATION_SIZE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_AUTHORIZATION_SIZE( |
| std::string* buffer, |
| TPM_AUTHORIZATION_SIZE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_PARAMETER_SIZE( |
| const TPM_PARAMETER_SIZE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_PARAMETER_SIZE( |
| std::string* buffer, |
| TPM_PARAMETER_SIZE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_KEY_SIZE( |
| const TPM_KEY_SIZE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_KEY_SIZE( |
| std::string* buffer, |
| TPM_KEY_SIZE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_KEY_BITS( |
| const TPM_KEY_BITS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_KEY_BITS( |
| std::string* buffer, |
| TPM_KEY_BITS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_HANDLE( |
| const TPM_HANDLE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_HANDLE( |
| std::string* buffer, |
| TPM_HANDLE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM2B_DIGEST( |
| const TPM2B_DIGEST& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_DIGEST( |
| std::string* buffer, |
| TPM2B_DIGEST* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_DIGEST Make_TPM2B_DIGEST( |
| const std::string& bytes) { |
| TPM2B_DIGEST tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_DIGEST)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_DIGEST( |
| const TPM2B_DIGEST& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_NONCE( |
| const TPM2B_NONCE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM2B_DIGEST(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM2B_NONCE( |
| std::string* buffer, |
| TPM2B_NONCE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM2B_DIGEST(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM2B_AUTH( |
| const TPM2B_AUTH& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM2B_DIGEST(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM2B_AUTH( |
| std::string* buffer, |
| TPM2B_AUTH* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM2B_DIGEST(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM2B_OPERAND( |
| const TPM2B_OPERAND& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM2B_DIGEST(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM2B_OPERAND( |
| std::string* buffer, |
| TPM2B_OPERAND* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM2B_DIGEST(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_ALG_ID( |
| const TPM_ALG_ID& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_ALG_ID( |
| std::string* buffer, |
| TPM_ALG_ID* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_HASH( |
| const TPMI_ALG_HASH& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_HASH( |
| std::string* buffer, |
| TPMI_ALG_HASH* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_SIGHASH( |
| const TPMS_SCHEME_SIGHASH& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_SIGHASH( |
| std::string* buffer, |
| TPMS_SCHEME_SIGHASH* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_HMAC( |
| const TPMS_SCHEME_HMAC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_HMAC( |
| std::string* buffer, |
| TPMS_SCHEME_HMAC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_RSASSA( |
| const TPMS_SCHEME_RSASSA& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_RSASSA( |
| std::string* buffer, |
| TPMS_SCHEME_RSASSA* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_RSAPSS( |
| const TPMS_SCHEME_RSAPSS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_RSAPSS( |
| std::string* buffer, |
| TPMS_SCHEME_RSAPSS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_ECDSA( |
| const TPMS_SCHEME_ECDSA& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_ECDSA( |
| std::string* buffer, |
| TPMS_SCHEME_ECDSA* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_SM2( |
| const TPMS_SCHEME_SM2& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_SM2( |
| std::string* buffer, |
| TPMS_SCHEME_SM2* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR( |
| const TPMS_SCHEME_ECSCHNORR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPMS_SCHEME_SIGHASH(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_ECSCHNORR( |
| std::string* buffer, |
| TPMS_SCHEME_ECSCHNORR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_YES_NO( |
| const TPMI_YES_NO& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_BYTE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_YES_NO( |
| std::string* buffer, |
| TPMI_YES_NO* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_BYTE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_DH_OBJECT( |
| const TPMI_DH_OBJECT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_DH_OBJECT( |
| std::string* buffer, |
| TPMI_DH_OBJECT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_DH_PERSISTENT( |
| const TPMI_DH_PERSISTENT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_DH_PERSISTENT( |
| std::string* buffer, |
| TPMI_DH_PERSISTENT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_DH_ENTITY( |
| const TPMI_DH_ENTITY& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_DH_ENTITY( |
| std::string* buffer, |
| TPMI_DH_ENTITY* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_DH_PCR( |
| const TPMI_DH_PCR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_DH_PCR( |
| std::string* buffer, |
| TPMI_DH_PCR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_SH_AUTH_SESSION( |
| const TPMI_SH_AUTH_SESSION& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_SH_AUTH_SESSION( |
| std::string* buffer, |
| TPMI_SH_AUTH_SESSION* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_SH_HMAC( |
| const TPMI_SH_HMAC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_SH_HMAC( |
| std::string* buffer, |
| TPMI_SH_HMAC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_SH_POLICY( |
| const TPMI_SH_POLICY& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_SH_POLICY( |
| std::string* buffer, |
| TPMI_SH_POLICY* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_DH_CONTEXT( |
| const TPMI_DH_CONTEXT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_DH_CONTEXT( |
| std::string* buffer, |
| TPMI_DH_CONTEXT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_HIERARCHY( |
| const TPMI_RH_HIERARCHY& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_HIERARCHY( |
| std::string* buffer, |
| TPMI_RH_HIERARCHY* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_ENABLES( |
| const TPMI_RH_ENABLES& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_ENABLES( |
| std::string* buffer, |
| TPMI_RH_ENABLES* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH( |
| const TPMI_RH_HIERARCHY_AUTH& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH( |
| std::string* buffer, |
| TPMI_RH_HIERARCHY_AUTH* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_PLATFORM( |
| const TPMI_RH_PLATFORM& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_PLATFORM( |
| std::string* buffer, |
| TPMI_RH_PLATFORM* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_OWNER( |
| const TPMI_RH_OWNER& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_OWNER( |
| std::string* buffer, |
| TPMI_RH_OWNER* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_ENDORSEMENT( |
| const TPMI_RH_ENDORSEMENT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_ENDORSEMENT( |
| std::string* buffer, |
| TPMI_RH_ENDORSEMENT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_PROVISION( |
| const TPMI_RH_PROVISION& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_PROVISION( |
| std::string* buffer, |
| TPMI_RH_PROVISION* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_CLEAR( |
| const TPMI_RH_CLEAR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_CLEAR( |
| std::string* buffer, |
| TPMI_RH_CLEAR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_NV_AUTH( |
| const TPMI_RH_NV_AUTH& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_NV_AUTH( |
| std::string* buffer, |
| TPMI_RH_NV_AUTH* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_LOCKOUT( |
| const TPMI_RH_LOCKOUT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_LOCKOUT( |
| std::string* buffer, |
| TPMI_RH_LOCKOUT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RH_NV_INDEX( |
| const TPMI_RH_NV_INDEX& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RH_NV_INDEX( |
| std::string* buffer, |
| TPMI_RH_NV_INDEX* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_ASYM( |
| const TPMI_ALG_ASYM& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_ASYM( |
| std::string* buffer, |
| TPMI_ALG_ASYM* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_SYM( |
| const TPMI_ALG_SYM& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_SYM( |
| std::string* buffer, |
| TPMI_ALG_SYM* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_SYM_OBJECT( |
| const TPMI_ALG_SYM_OBJECT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_SYM_OBJECT( |
| std::string* buffer, |
| TPMI_ALG_SYM_OBJECT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_SYM_MODE( |
| const TPMI_ALG_SYM_MODE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_SYM_MODE( |
| std::string* buffer, |
| TPMI_ALG_SYM_MODE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_KDF( |
| const TPMI_ALG_KDF& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_KDF( |
| std::string* buffer, |
| TPMI_ALG_KDF* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_SIG_SCHEME( |
| const TPMI_ALG_SIG_SCHEME& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_SIG_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_SIG_SCHEME* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE( |
| const TPMI_ECC_KEY_EXCHANGE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE( |
| std::string* buffer, |
| TPMI_ECC_KEY_EXCHANGE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_ST( |
| const TPM_ST& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_ST( |
| std::string* buffer, |
| TPM_ST* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ST_COMMAND_TAG( |
| const TPMI_ST_COMMAND_TAG& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ST(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ST_COMMAND_TAG( |
| std::string* buffer, |
| TPMI_ST_COMMAND_TAG* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ST(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ST_ATTEST( |
| const TPMI_ST_ATTEST& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ST(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ST_ATTEST( |
| std::string* buffer, |
| TPMI_ST_ATTEST* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ST(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_AES_KEY_BITS( |
| const TPMI_AES_KEY_BITS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_KEY_BITS(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_AES_KEY_BITS( |
| std::string* buffer, |
| TPMI_AES_KEY_BITS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_KEY_BITS(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_SM4_KEY_BITS( |
| const TPMI_SM4_KEY_BITS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_KEY_BITS(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_SM4_KEY_BITS( |
| std::string* buffer, |
| TPMI_SM4_KEY_BITS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_KEY_BITS(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME( |
| const TPMI_ALG_KEYEDHASH_SCHEME& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_KEYEDHASH_SCHEME* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME( |
| const TPMI_ALG_ASYM_SCHEME& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_ASYM_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_ASYM_SCHEME* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_RSA_SCHEME( |
| const TPMI_ALG_RSA_SCHEME& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_RSA_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_RSA_SCHEME* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT( |
| const TPMI_ALG_RSA_DECRYPT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_RSA_DECRYPT( |
| std::string* buffer, |
| TPMI_ALG_RSA_DECRYPT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_RSA_KEY_BITS( |
| const TPMI_RSA_KEY_BITS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_KEY_BITS(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_RSA_KEY_BITS( |
| std::string* buffer, |
| TPMI_RSA_KEY_BITS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_KEY_BITS(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_ECC_SCHEME( |
| const TPMI_ALG_ECC_SCHEME& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_ECC_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_ECC_SCHEME* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_ECC_CURVE( |
| const TPM_ECC_CURVE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_ECC_CURVE( |
| std::string* buffer, |
| TPM_ECC_CURVE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ECC_CURVE( |
| const TPMI_ECC_CURVE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ECC_CURVE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ECC_CURVE( |
| std::string* buffer, |
| TPMI_ECC_CURVE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ECC_CURVE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMI_ALG_PUBLIC( |
| const TPMI_ALG_PUBLIC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_ALG_ID(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMI_ALG_PUBLIC( |
| std::string* buffer, |
| TPMI_ALG_PUBLIC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_ALG_ID(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_ALGORITHM( |
| const TPMA_ALGORITHM& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_ALGORITHM( |
| std::string* buffer, |
| TPMA_ALGORITHM* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_OBJECT( |
| const TPMA_OBJECT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_OBJECT( |
| std::string* buffer, |
| TPMA_OBJECT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_SESSION( |
| const TPMA_SESSION& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT8(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_SESSION( |
| std::string* buffer, |
| TPMA_SESSION* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT8(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_LOCALITY( |
| const TPMA_LOCALITY& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT8(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_LOCALITY( |
| std::string* buffer, |
| TPMA_LOCALITY* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT8(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_PERMANENT( |
| const TPMA_PERMANENT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_PERMANENT( |
| std::string* buffer, |
| TPMA_PERMANENT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_STARTUP_CLEAR( |
| const TPMA_STARTUP_CLEAR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_STARTUP_CLEAR( |
| std::string* buffer, |
| TPMA_STARTUP_CLEAR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_MEMORY( |
| const TPMA_MEMORY& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_MEMORY( |
| std::string* buffer, |
| TPMA_MEMORY* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_CC( |
| const TPM_CC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_CC( |
| std::string* buffer, |
| TPM_CC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_CC( |
| const TPMA_CC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_CC(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_CC( |
| std::string* buffer, |
| TPMA_CC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_CC(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_NV_INDEX( |
| const TPM_NV_INDEX& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_NV_INDEX( |
| std::string* buffer, |
| TPM_NV_INDEX* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMA_NV( |
| const TPMA_NV& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPMA_NV( |
| std::string* buffer, |
| TPMA_NV* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_SPEC( |
| const TPM_SPEC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_SPEC( |
| std::string* buffer, |
| TPM_SPEC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_GENERATED( |
| const TPM_GENERATED& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_GENERATED( |
| std::string* buffer, |
| TPM_GENERATED* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_RC( |
| const TPM_RC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_RC( |
| std::string* buffer, |
| TPM_RC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_CLOCK_ADJUST( |
| const TPM_CLOCK_ADJUST& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_INT8(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_CLOCK_ADJUST( |
| std::string* buffer, |
| TPM_CLOCK_ADJUST* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_INT8(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_EO( |
| const TPM_EO& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_EO( |
| std::string* buffer, |
| TPM_EO* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_SU( |
| const TPM_SU& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT16(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_SU( |
| std::string* buffer, |
| TPM_SU* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT16(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_SE( |
| const TPM_SE& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT8(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_SE( |
| std::string* buffer, |
| TPM_SE* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT8(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_CAP( |
| const TPM_CAP& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_CAP( |
| std::string* buffer, |
| TPM_CAP* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_PT( |
| const TPM_PT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_PT( |
| std::string* buffer, |
| TPM_PT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_PT_PCR( |
| const TPM_PT_PCR& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_PT_PCR( |
| std::string* buffer, |
| TPM_PT_PCR* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_PS( |
| const TPM_PS& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_PS( |
| std::string* buffer, |
| TPM_PS* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_HT( |
| const TPM_HT& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT8(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_HT( |
| std::string* buffer, |
| TPM_HT* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT8(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_RH( |
| const TPM_RH& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_UINT32(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_RH( |
| std::string* buffer, |
| TPM_RH* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_UINT32(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPM_HC( |
| const TPM_HC& value, |
| std::string* buffer) { |
| VLOG(2) << __func__; |
| return Serialize_TPM_HANDLE(value, buffer); |
| } |
| |
| TPM_RC Parse_TPM_HC( |
| std::string* buffer, |
| TPM_HC* value, |
| std::string* value_bytes) { |
| VLOG(2) << __func__; |
| return Parse_TPM_HANDLE(buffer, value, value_bytes); |
| } |
| |
| TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION( |
| const TPMS_ALGORITHM_DESCRIPTION& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ALG_ID(value.alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_ALGORITHM(value.attributes, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION( |
| std::string* buffer, |
| TPMS_ALGORITHM_DESCRIPTION* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ALG_ID( |
| buffer, |
| &value->alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_ALGORITHM( |
| buffer, |
| &value->attributes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_HA( |
| const TPMU_HA& value, |
| TPMI_ALG_HASH selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_SHA384) { |
| if (arraysize(value.sha384) < SHA384_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) { |
| result = Serialize_BYTE(value.sha384[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SHA1) { |
| if (arraysize(value.sha1) < SHA1_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) { |
| result = Serialize_BYTE(value.sha1[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SM3_256) { |
| if (arraysize(value.sm3_256) < SM3_256_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) { |
| result = Serialize_BYTE(value.sm3_256[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SHA256) { |
| if (arraysize(value.sha256) < SHA256_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) { |
| result = Serialize_BYTE(value.sha256[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SHA512) { |
| if (arraysize(value.sha512) < SHA512_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) { |
| result = Serialize_BYTE(value.sha512[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_HA( |
| std::string* buffer, |
| TPMI_ALG_HASH selector, |
| TPMU_HA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_SHA384) { |
| if (arraysize(value->sha384) < SHA384_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->sha384[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SHA1) { |
| if (arraysize(value->sha1) < SHA1_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->sha1[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SM3_256) { |
| if (arraysize(value->sm3_256) < SM3_256_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->sm3_256[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SHA256) { |
| if (arraysize(value->sha256) < SHA256_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->sha256[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| |
| if (selector == TPM_ALG_SHA512) { |
| if (arraysize(value->sha512) < SHA512_DIGEST_SIZE) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->sha512[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_HA( |
| const TPMT_HA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_HA( |
| value.digest, |
| value.hash_alg, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_HA( |
| std::string* buffer, |
| TPMT_HA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_HA( |
| buffer, |
| value->hash_alg, |
| &value->digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_DATA( |
| const TPM2B_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_DATA( |
| std::string* buffer, |
| TPM2B_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_DATA Make_TPM2B_DATA( |
| const std::string& bytes) { |
| TPM2B_DATA tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_DATA)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_DATA( |
| const TPM2B_DATA& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_EVENT( |
| const TPM2B_EVENT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_EVENT( |
| std::string* buffer, |
| TPM2B_EVENT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_EVENT Make_TPM2B_EVENT( |
| const std::string& bytes) { |
| TPM2B_EVENT tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_EVENT)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_EVENT( |
| const TPM2B_EVENT& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_MAX_BUFFER( |
| const TPM2B_MAX_BUFFER& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_MAX_BUFFER( |
| std::string* buffer, |
| TPM2B_MAX_BUFFER* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER( |
| const std::string& bytes) { |
| TPM2B_MAX_BUFFER tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_MAX_BUFFER( |
| const TPM2B_MAX_BUFFER& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_MAX_NV_BUFFER( |
| const TPM2B_MAX_NV_BUFFER& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_MAX_NV_BUFFER( |
| std::string* buffer, |
| TPM2B_MAX_NV_BUFFER* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER( |
| const std::string& bytes) { |
| TPM2B_MAX_NV_BUFFER tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_MAX_NV_BUFFER( |
| const TPM2B_MAX_NV_BUFFER& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_TIMEOUT( |
| const TPM2B_TIMEOUT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_TIMEOUT( |
| std::string* buffer, |
| TPM2B_TIMEOUT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_TIMEOUT Make_TPM2B_TIMEOUT( |
| const std::string& bytes) { |
| TPM2B_TIMEOUT tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_TIMEOUT( |
| const TPM2B_TIMEOUT& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_IV( |
| const TPM2B_IV& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_IV( |
| std::string* buffer, |
| TPM2B_IV* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_IV Make_TPM2B_IV( |
| const std::string& bytes) { |
| TPM2B_IV tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_IV)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_IV( |
| const TPM2B_IV& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_NAME( |
| const TPM2B_NAME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.name) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.name[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_NAME( |
| std::string* buffer, |
| TPM2B_NAME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->name) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->name[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_NAME Make_TPM2B_NAME( |
| const std::string& bytes) { |
| TPM2B_NAME tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.name)); |
| memset(&tpm2b, 0, sizeof(TPM2B_NAME)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.name, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_NAME( |
| const TPM2B_NAME& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.name); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_PCR_SELECT( |
| const TPMS_PCR_SELECT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT8(value.sizeof_select, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.pcr_select) < value.sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.sizeof_select; ++i) { |
| result = Serialize_BYTE(value.pcr_select[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_PCR_SELECT( |
| std::string* buffer, |
| TPMS_PCR_SELECT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT8( |
| buffer, |
| &value->sizeof_select, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->pcr_select) < value->sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->sizeof_select; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->pcr_select[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_PCR_SELECTION( |
| const TPMS_PCR_SELECTION& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT8(value.sizeof_select, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.pcr_select) < value.sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.sizeof_select; ++i) { |
| result = Serialize_BYTE(value.pcr_select[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_PCR_SELECTION( |
| std::string* buffer, |
| TPMS_PCR_SELECTION* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT8( |
| buffer, |
| &value->sizeof_select, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->pcr_select) < value->sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->sizeof_select; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->pcr_select[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_TK_CREATION( |
| const TPMT_TK_CREATION& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ST(value.tag, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_TK_CREATION( |
| std::string* buffer, |
| TPMT_TK_CREATION* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ST( |
| buffer, |
| &value->tag, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_RH_HIERARCHY( |
| buffer, |
| &value->hierarchy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_TK_VERIFIED( |
| const TPMT_TK_VERIFIED& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ST(value.tag, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_TK_VERIFIED( |
| std::string* buffer, |
| TPMT_TK_VERIFIED* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ST( |
| buffer, |
| &value->tag, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_RH_HIERARCHY( |
| buffer, |
| &value->hierarchy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_TK_AUTH( |
| const TPMT_TK_AUTH& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_TK_AUTH( |
| std::string* buffer, |
| TPMT_TK_AUTH* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_RH_HIERARCHY( |
| buffer, |
| &value->hierarchy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_TK_HASHCHECK( |
| const TPMT_TK_HASHCHECK& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ST(value.tag, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_TK_HASHCHECK( |
| std::string* buffer, |
| TPMT_TK_HASHCHECK* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ST( |
| buffer, |
| &value->tag, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_RH_HIERARCHY( |
| buffer, |
| &value->hierarchy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_ALG_PROPERTY( |
| const TPMS_ALG_PROPERTY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ALG_ID(value.alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ALG_PROPERTY( |
| std::string* buffer, |
| TPMS_ALG_PROPERTY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ALG_ID( |
| buffer, |
| &value->alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_ALGORITHM( |
| buffer, |
| &value->alg_properties, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_TAGGED_PROPERTY( |
| const TPMS_TAGGED_PROPERTY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_PT(value.property, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT32(value.value, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_TAGGED_PROPERTY( |
| std::string* buffer, |
| TPMS_TAGGED_PROPERTY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_PT( |
| buffer, |
| &value->property, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->value, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT( |
| const TPMS_TAGGED_PCR_SELECT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_PT(value.tag, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT8(value.sizeof_select, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.pcr_select) < value.sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.sizeof_select; ++i) { |
| result = Serialize_BYTE(value.pcr_select[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_TAGGED_PCR_SELECT( |
| std::string* buffer, |
| TPMS_TAGGED_PCR_SELECT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_PT( |
| buffer, |
| &value->tag, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT8( |
| buffer, |
| &value->sizeof_select, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->pcr_select) < value->sizeof_select) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->sizeof_select; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->pcr_select[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_CC( |
| const TPML_CC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.command_codes) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPM_CC(value.command_codes[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_CC( |
| std::string* buffer, |
| TPML_CC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->command_codes) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPM_CC( |
| buffer, |
| &value->command_codes[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_CCA( |
| const TPML_CCA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.command_attributes) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMA_CC(value.command_attributes[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_CCA( |
| std::string* buffer, |
| TPML_CCA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->command_attributes) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMA_CC( |
| buffer, |
| &value->command_attributes[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_ALG( |
| const TPML_ALG& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.algorithms) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_ALG( |
| std::string* buffer, |
| TPML_ALG* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->algorithms) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPM_ALG_ID( |
| buffer, |
| &value->algorithms[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_HANDLE( |
| const TPML_HANDLE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.handle) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPM_HANDLE(value.handle[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_HANDLE( |
| std::string* buffer, |
| TPML_HANDLE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->handle) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPM_HANDLE( |
| buffer, |
| &value->handle[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_DIGEST( |
| const TPML_DIGEST& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.digests) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPM2B_DIGEST(value.digests[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_DIGEST( |
| std::string* buffer, |
| TPML_DIGEST* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->digests) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->digests[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_DIGEST_VALUES( |
| const TPML_DIGEST_VALUES& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.digests) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMT_HA(value.digests[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_DIGEST_VALUES( |
| std::string* buffer, |
| TPML_DIGEST_VALUES* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->digests) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMT_HA( |
| buffer, |
| &value->digests[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_DIGEST_VALUES( |
| const TPM2B_DIGEST_VALUES& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_DIGEST_VALUES( |
| std::string* buffer, |
| TPM2B_DIGEST_VALUES* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES( |
| const std::string& bytes) { |
| TPM2B_DIGEST_VALUES tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_DIGEST_VALUES( |
| const TPM2B_DIGEST_VALUES& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPML_PCR_SELECTION( |
| const TPML_PCR_SELECTION& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.pcr_selections) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_PCR_SELECTION( |
| std::string* buffer, |
| TPML_PCR_SELECTION* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->pcr_selections) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMS_PCR_SELECTION( |
| buffer, |
| &value->pcr_selections[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_ALG_PROPERTY( |
| const TPML_ALG_PROPERTY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.alg_properties) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_ALG_PROPERTY( |
| std::string* buffer, |
| TPML_ALG_PROPERTY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->alg_properties) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMS_ALG_PROPERTY( |
| buffer, |
| &value->alg_properties[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY( |
| const TPML_TAGGED_TPM_PROPERTY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.tpm_property) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY( |
| std::string* buffer, |
| TPML_TAGGED_TPM_PROPERTY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->tpm_property) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMS_TAGGED_PROPERTY( |
| buffer, |
| &value->tpm_property[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY( |
| const TPML_TAGGED_PCR_PROPERTY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.pcr_property) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY( |
| std::string* buffer, |
| TPML_TAGGED_PCR_PROPERTY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->pcr_property) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPMS_TAGGED_PCR_SELECT( |
| buffer, |
| &value->pcr_property[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPML_ECC_CURVE( |
| const TPML_ECC_CURVE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT32(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.ecc_curves) < value.count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.count; ++i) { |
| result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPML_ECC_CURVE( |
| std::string* buffer, |
| TPML_ECC_CURVE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->ecc_curves) < value->count) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->count; ++i) { |
| result = Parse_TPM_ECC_CURVE( |
| buffer, |
| &value->ecc_curves[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_CAPABILITIES( |
| const TPMU_CAPABILITIES& value, |
| TPM_CAP selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_CAP_PCRS) { |
| result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_TPM_PROPERTIES) { |
| result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_PP_COMMANDS) { |
| result = Serialize_TPML_CC(value.pp_commands, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_AUDIT_COMMANDS) { |
| result = Serialize_TPML_CC(value.audit_commands, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_COMMANDS) { |
| result = Serialize_TPML_CCA(value.command, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_ECC_CURVES) { |
| result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_PCR_PROPERTIES) { |
| result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_HANDLES) { |
| result = Serialize_TPML_HANDLE(value.handles, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_ALGS) { |
| result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_CAPABILITIES( |
| std::string* buffer, |
| TPM_CAP selector, |
| TPMU_CAPABILITIES* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_CAP_PCRS) { |
| result = Parse_TPML_PCR_SELECTION( |
| buffer, |
| &value->assigned_pcr, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_TPM_PROPERTIES) { |
| result = Parse_TPML_TAGGED_TPM_PROPERTY( |
| buffer, |
| &value->tpm_properties, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_PP_COMMANDS) { |
| result = Parse_TPML_CC( |
| buffer, |
| &value->pp_commands, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_AUDIT_COMMANDS) { |
| result = Parse_TPML_CC( |
| buffer, |
| &value->audit_commands, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_COMMANDS) { |
| result = Parse_TPML_CCA( |
| buffer, |
| &value->command, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_ECC_CURVES) { |
| result = Parse_TPML_ECC_CURVE( |
| buffer, |
| &value->ecc_curves, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_PCR_PROPERTIES) { |
| result = Parse_TPML_TAGGED_PCR_PROPERTY( |
| buffer, |
| &value->pcr_properties, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_HANDLES) { |
| result = Parse_TPML_HANDLE( |
| buffer, |
| &value->handles, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_CAP_ALGS) { |
| result = Parse_TPML_ALG_PROPERTY( |
| buffer, |
| &value->algorithms, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_CAPABILITY_DATA( |
| const TPMS_CAPABILITY_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_CAP(value.capability, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_CAPABILITIES( |
| value.data, |
| value.capability, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CAPABILITY_DATA( |
| std::string* buffer, |
| TPMS_CAPABILITY_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_CAP( |
| buffer, |
| &value->capability, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_CAPABILITIES( |
| buffer, |
| value->capability, |
| &value->data, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_CLOCK_INFO( |
| const TPMS_CLOCK_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT64(value.clock, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT32(value.reset_count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT32(value.restart_count, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_YES_NO(value.safe, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CLOCK_INFO( |
| std::string* buffer, |
| TPMS_CLOCK_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->clock, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->reset_count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->restart_count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_YES_NO( |
| buffer, |
| &value->safe, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_TIME_INFO( |
| const TPMS_TIME_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT64(value.time, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_TIME_INFO( |
| std::string* buffer, |
| TPMS_TIME_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->time, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_CLOCK_INFO( |
| buffer, |
| &value->clock_info, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_TIME_ATTEST_INFO( |
| const TPMS_TIME_ATTEST_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMS_TIME_INFO(value.time, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT64(value.firmware_version, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_TIME_ATTEST_INFO( |
| std::string* buffer, |
| TPMS_TIME_ATTEST_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMS_TIME_INFO( |
| buffer, |
| &value->time, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->firmware_version, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_CERTIFY_INFO( |
| const TPMS_CERTIFY_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_NAME(value.name, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_NAME(value.qualified_name, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CERTIFY_INFO( |
| std::string* buffer, |
| TPMS_CERTIFY_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->qualified_name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_QUOTE_INFO( |
| const TPMS_QUOTE_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_QUOTE_INFO( |
| std::string* buffer, |
| TPMS_QUOTE_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPML_PCR_SELECTION( |
| buffer, |
| &value->pcr_select, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->pcr_digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO( |
| const TPMS_COMMAND_AUDIT_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT64(value.audit_counter, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM_ALG_ID(value.digest_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.command_digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO( |
| std::string* buffer, |
| TPMS_COMMAND_AUDIT_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->audit_counter, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM_ALG_ID( |
| buffer, |
| &value->digest_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->audit_digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->command_digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO( |
| const TPMS_SESSION_AUDIT_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.session_digest, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SESSION_AUDIT_INFO( |
| std::string* buffer, |
| TPMS_SESSION_AUDIT_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_YES_NO( |
| buffer, |
| &value->exclusive_session, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->session_digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_CREATION_INFO( |
| const TPMS_CREATION_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_NAME(value.object_name, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CREATION_INFO( |
| std::string* buffer, |
| TPMS_CREATION_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->object_name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->creation_hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_NV_CERTIFY_INFO( |
| const TPMS_NV_CERTIFY_INFO& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_NAME(value.index_name, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT16(value.offset, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_NV_CERTIFY_INFO( |
| std::string* buffer, |
| TPMS_NV_CERTIFY_INFO* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->index_name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->offset, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_MAX_NV_BUFFER( |
| buffer, |
| &value->nv_contents, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_ATTEST( |
| const TPMU_ATTEST& value, |
| TPMI_ST_ATTEST selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ST_ATTEST_SESSION_AUDIT) { |
| result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_QUOTE) { |
| result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) { |
| result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_CERTIFY) { |
| result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_NV) { |
| result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_TIME) { |
| result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_CREATION) { |
| result = Serialize_TPMS_CREATION_INFO(value.creation, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_ATTEST( |
| std::string* buffer, |
| TPMI_ST_ATTEST selector, |
| TPMU_ATTEST* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ST_ATTEST_SESSION_AUDIT) { |
| result = Parse_TPMS_SESSION_AUDIT_INFO( |
| buffer, |
| &value->session_audit, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_QUOTE) { |
| result = Parse_TPMS_QUOTE_INFO( |
| buffer, |
| &value->quote, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) { |
| result = Parse_TPMS_COMMAND_AUDIT_INFO( |
| buffer, |
| &value->command_audit, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_CERTIFY) { |
| result = Parse_TPMS_CERTIFY_INFO( |
| buffer, |
| &value->certify, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_NV) { |
| result = Parse_TPMS_NV_CERTIFY_INFO( |
| buffer, |
| &value->nv, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_TIME) { |
| result = Parse_TPMS_TIME_ATTEST_INFO( |
| buffer, |
| &value->time, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ST_ATTEST_CREATION) { |
| result = Parse_TPMS_CREATION_INFO( |
| buffer, |
| &value->creation, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_ATTEST( |
| const TPMS_ATTEST& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_GENERATED(value.magic, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_ST_ATTEST(value.type, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_NAME(value.qualified_signer, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DATA(value.extra_data, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT64(value.firmware_version, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_ATTEST( |
| value.attested, |
| value.type, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ATTEST( |
| std::string* buffer, |
| TPMS_ATTEST* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_GENERATED( |
| buffer, |
| &value->magic, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_ST_ATTEST( |
| buffer, |
| &value->type, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->qualified_signer, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DATA( |
| buffer, |
| &value->extra_data, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_CLOCK_INFO( |
| buffer, |
| &value->clock_info, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->firmware_version, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_ATTEST( |
| buffer, |
| value->type, |
| &value->attested, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_ATTEST( |
| const TPM2B_ATTEST& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.attestation_data) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.attestation_data[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_ATTEST( |
| std::string* buffer, |
| TPM2B_ATTEST* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->attestation_data) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->attestation_data[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_ATTEST Make_TPM2B_ATTEST( |
| const std::string& bytes) { |
| TPM2B_ATTEST tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.attestation_data)); |
| memset(&tpm2b, 0, sizeof(TPM2B_ATTEST)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.attestation_data, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_ATTEST( |
| const TPM2B_ATTEST& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.attestation_data); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_AUTH_COMMAND( |
| const TPMS_AUTH_COMMAND& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_NONCE(value.nonce, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_SESSION(value.session_attributes, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_AUTH(value.hmac, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_AUTH_COMMAND( |
| std::string* buffer, |
| TPMS_AUTH_COMMAND* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_SH_AUTH_SESSION( |
| buffer, |
| &value->session_handle, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_NONCE( |
| buffer, |
| &value->nonce, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_SESSION( |
| buffer, |
| &value->session_attributes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_AUTH( |
| buffer, |
| &value->hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_AUTH_RESPONSE( |
| const TPMS_AUTH_RESPONSE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_NONCE(value.nonce, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_SESSION(value.session_attributes, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_AUTH(value.hmac, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_AUTH_RESPONSE( |
| std::string* buffer, |
| TPMS_AUTH_RESPONSE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_NONCE( |
| buffer, |
| &value->nonce, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_SESSION( |
| buffer, |
| &value->session_attributes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_AUTH( |
| buffer, |
| &value->hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SYM_KEY_BITS( |
| const TPMU_SYM_KEY_BITS& value, |
| TPMI_ALG_SYM selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SM4) { |
| result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_AES) { |
| result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| result = Serialize_TPMI_ALG_HASH(value.xor_, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SYM_KEY_BITS( |
| std::string* buffer, |
| TPMI_ALG_SYM selector, |
| TPMU_SYM_KEY_BITS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SM4) { |
| result = Parse_TPMI_SM4_KEY_BITS( |
| buffer, |
| &value->sm4, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_AES) { |
| result = Parse_TPMI_AES_KEY_BITS( |
| buffer, |
| &value->aes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->xor_, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SYM_MODE( |
| const TPMU_SYM_MODE& value, |
| TPMI_ALG_SYM selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SM4) { |
| result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_AES) { |
| result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SYM_MODE( |
| std::string* buffer, |
| TPMI_ALG_SYM selector, |
| TPMU_SYM_MODE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_SM4) { |
| result = Parse_TPMI_ALG_SYM_MODE( |
| buffer, |
| &value->sm4, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_AES) { |
| result = Parse_TPMI_ALG_SYM_MODE( |
| buffer, |
| &value->aes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SYM_DETAILS( |
| const TPMU_SYM_DETAILS& value, |
| TPMI_ALG_SYM selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SYM_DETAILS( |
| std::string* buffer, |
| TPMI_ALG_SYM selector, |
| TPMU_SYM_DETAILS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_SYM_DEF( |
| const TPMT_SYM_DEF& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_KEY_BITS( |
| value.key_bits, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_MODE( |
| value.mode, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_DETAILS( |
| value.details, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_SYM_DEF( |
| std::string* buffer, |
| TPMT_SYM_DEF* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_SYM( |
| buffer, |
| &value->algorithm, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_KEY_BITS( |
| buffer, |
| value->algorithm, |
| &value->key_bits, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_MODE( |
| buffer, |
| value->algorithm, |
| &value->mode, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_DETAILS( |
| buffer, |
| value->algorithm, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_SYM_DEF_OBJECT( |
| const TPMT_SYM_DEF_OBJECT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_KEY_BITS( |
| value.key_bits, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_MODE( |
| value.mode, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SYM_DETAILS( |
| value.details, |
| value.algorithm, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_SYM_DEF_OBJECT( |
| std::string* buffer, |
| TPMT_SYM_DEF_OBJECT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_SYM_OBJECT( |
| buffer, |
| &value->algorithm, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_KEY_BITS( |
| buffer, |
| value->algorithm, |
| &value->key_bits, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_MODE( |
| buffer, |
| value->algorithm, |
| &value->mode, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SYM_DETAILS( |
| buffer, |
| value->algorithm, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_SYM_KEY( |
| const TPM2B_SYM_KEY& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_SYM_KEY( |
| std::string* buffer, |
| TPM2B_SYM_KEY* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_SYM_KEY Make_TPM2B_SYM_KEY( |
| const std::string& bytes) { |
| TPM2B_SYM_KEY tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_SYM_KEY( |
| const TPM2B_SYM_KEY& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_SYMCIPHER_PARMS( |
| const TPMS_SYMCIPHER_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SYMCIPHER_PARMS( |
| std::string* buffer, |
| TPMS_SYMCIPHER_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMT_SYM_DEF_OBJECT( |
| buffer, |
| &value->sym, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_SENSITIVE_DATA( |
| const TPM2B_SENSITIVE_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_SENSITIVE_DATA( |
| std::string* buffer, |
| TPM2B_SENSITIVE_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA( |
| const std::string& bytes) { |
| TPM2B_SENSITIVE_DATA tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_SENSITIVE_DATA( |
| const TPM2B_SENSITIVE_DATA& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_SENSITIVE_CREATE( |
| const TPMS_SENSITIVE_CREATE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_AUTH(value.user_auth, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SENSITIVE_CREATE( |
| std::string* buffer, |
| TPMS_SENSITIVE_CREATE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_AUTH( |
| buffer, |
| &value->user_auth, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_SENSITIVE_DATA( |
| buffer, |
| &value->data, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_SENSITIVE_CREATE( |
| const TPM2B_SENSITIVE_CREATE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_SENSITIVE_CREATE( |
| std::string* buffer, |
| TPM2B_SENSITIVE_CREATE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_SENSITIVE_CREATE( |
| buffer, |
| &value->sensitive, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE( |
| const TPMS_SENSITIVE_CREATE& inner) { |
| TPM2B_SENSITIVE_CREATE tpm2b; |
| tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE); |
| tpm2b.sensitive = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_XOR( |
| const TPMS_SCHEME_XOR& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_ALG_KDF(value.kdf, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_XOR( |
| std::string* buffer, |
| TPMS_SCHEME_XOR* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_ALG_KDF( |
| buffer, |
| &value->kdf, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH( |
| const TPMU_SCHEME_KEYEDHASH& value, |
| TPMI_ALG_KEYEDHASH_SCHEME selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SCHEME_KEYEDHASH( |
| std::string* buffer, |
| TPMI_ALG_KEYEDHASH_SCHEME selector, |
| TPMU_SCHEME_KEYEDHASH* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Parse_TPMS_SCHEME_HMAC( |
| buffer, |
| &value->hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_XOR) { |
| result = Parse_TPMS_SCHEME_XOR( |
| buffer, |
| &value->xor_, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME( |
| const TPMT_KEYEDHASH_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SCHEME_KEYEDHASH( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_KEYEDHASH_SCHEME( |
| std::string* buffer, |
| TPMT_KEYEDHASH_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_KEYEDHASH_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SCHEME_KEYEDHASH( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_ECDAA( |
| const TPMS_SCHEME_ECDAA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT16(value.count, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_ECDAA( |
| std::string* buffer, |
| TPMS_SCHEME_ECDAA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->count, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SIG_SCHEME( |
| const TPMU_SIG_SCHEME& value, |
| TPMI_ALG_SIG_SCHEME selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SIG_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_SIG_SCHEME selector, |
| TPMU_SIG_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Parse_TPMS_SCHEME_HMAC( |
| buffer, |
| &value->hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Parse_TPMS_SCHEME_ECSCHNORR( |
| buffer, |
| &value->ec_schnorr, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Parse_TPMS_SCHEME_RSAPSS( |
| buffer, |
| &value->rsapss, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Parse_TPMS_SCHEME_ECDAA( |
| buffer, |
| &value->ecdaa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Parse_TPMS_SCHEME_RSASSA( |
| buffer, |
| &value->rsassa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Parse_TPMS_SCHEME_SM2( |
| buffer, |
| &value->sm2, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Parse_TPMS_SCHEME_ECDSA( |
| buffer, |
| &value->ecdsa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_SIG_SCHEME( |
| const TPMT_SIG_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SIG_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_SIG_SCHEME( |
| std::string* buffer, |
| TPMT_SIG_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_SIG_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SIG_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_OAEP( |
| const TPMS_SCHEME_OAEP& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_OAEP( |
| std::string* buffer, |
| TPMS_SCHEME_OAEP* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_ECDH( |
| const TPMS_SCHEME_ECDH& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_ECDH( |
| std::string* buffer, |
| TPMS_SCHEME_ECDH* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_MGF1( |
| const TPMS_SCHEME_MGF1& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_MGF1( |
| std::string* buffer, |
| TPMS_SCHEME_MGF1* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a( |
| const TPMS_SCHEME_KDF1_SP800_56a& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a( |
| std::string* buffer, |
| TPMS_SCHEME_KDF1_SP800_56a* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_KDF2( |
| const TPMS_SCHEME_KDF2& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_KDF2( |
| std::string* buffer, |
| TPMS_SCHEME_KDF2* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108( |
| const TPMS_SCHEME_KDF1_SP800_108& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108( |
| std::string* buffer, |
| TPMS_SCHEME_KDF1_SP800_108* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_KDF_SCHEME( |
| const TPMU_KDF_SCHEME& value, |
| TPMI_ALG_KDF selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KDF1_SP800_56a) { |
| result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_MGF1) { |
| result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_KDF1_SP800_108) { |
| result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_KDF2) { |
| result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_KDF_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_KDF selector, |
| TPMU_KDF_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KDF1_SP800_56a) { |
| result = Parse_TPMS_SCHEME_KDF1_SP800_56a( |
| buffer, |
| &value->kdf1_sp800_56a, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_MGF1) { |
| result = Parse_TPMS_SCHEME_MGF1( |
| buffer, |
| &value->mgf1, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_KDF1_SP800_108) { |
| result = Parse_TPMS_SCHEME_KDF1_SP800_108( |
| buffer, |
| &value->kdf1_sp800_108, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_KDF2) { |
| result = Parse_TPMS_SCHEME_KDF2( |
| buffer, |
| &value->kdf2, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_KDF_SCHEME( |
| const TPMT_KDF_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_KDF(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_KDF_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_KDF_SCHEME( |
| std::string* buffer, |
| TPMT_KDF_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_KDF( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_KDF_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_ASYM_SCHEME( |
| const TPMU_ASYM_SCHEME& value, |
| TPMI_ALG_ASYM_SCHEME selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_RSAES) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_ECDH) { |
| result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_OAEP) { |
| result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_ASYM_SCHEME( |
| std::string* buffer, |
| TPMI_ALG_ASYM_SCHEME selector, |
| TPMU_ASYM_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_RSAES) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Parse_TPMS_SCHEME_ECSCHNORR( |
| buffer, |
| &value->ec_schnorr, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| |
| if (selector == TPM_ALG_ECDH) { |
| result = Parse_TPMS_SCHEME_ECDH( |
| buffer, |
| &value->ecdh, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_OAEP) { |
| result = Parse_TPMS_SCHEME_OAEP( |
| buffer, |
| &value->oaep, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Parse_TPMS_SCHEME_RSAPSS( |
| buffer, |
| &value->rsapss, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Parse_TPMS_SCHEME_ECDAA( |
| buffer, |
| &value->ecdaa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Parse_TPMS_SCHEME_RSASSA( |
| buffer, |
| &value->rsassa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Parse_TPMS_SCHEME_SM2( |
| buffer, |
| &value->sm2, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Parse_TPMS_SCHEME_ECDSA( |
| buffer, |
| &value->ecdsa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_ASYM_SCHEME( |
| const TPMT_ASYM_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_ASYM_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_ASYM_SCHEME( |
| std::string* buffer, |
| TPMT_ASYM_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_ASYM_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_ASYM_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_RSA_SCHEME( |
| const TPMT_RSA_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_ASYM_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_RSA_SCHEME( |
| std::string* buffer, |
| TPMT_RSA_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_RSA_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_ASYM_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_RSA_DECRYPT( |
| const TPMT_RSA_DECRYPT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_ASYM_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_RSA_DECRYPT( |
| std::string* buffer, |
| TPMT_RSA_DECRYPT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_RSA_DECRYPT( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_ASYM_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA( |
| const TPM2B_PUBLIC_KEY_RSA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA( |
| std::string* buffer, |
| TPM2B_PUBLIC_KEY_RSA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA( |
| const std::string& bytes) { |
| TPM2B_PUBLIC_KEY_RSA tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_PUBLIC_KEY_RSA( |
| const TPM2B_PUBLIC_KEY_RSA& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA( |
| const TPM2B_PRIVATE_KEY_RSA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA( |
| std::string* buffer, |
| TPM2B_PRIVATE_KEY_RSA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA( |
| const std::string& bytes) { |
| TPM2B_PRIVATE_KEY_RSA tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_PRIVATE_KEY_RSA( |
| const TPM2B_PRIVATE_KEY_RSA& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPM2B_ECC_PARAMETER( |
| const TPM2B_ECC_PARAMETER& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_ECC_PARAMETER( |
| std::string* buffer, |
| TPM2B_ECC_PARAMETER* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER( |
| const std::string& bytes) { |
| TPM2B_ECC_PARAMETER tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_ECC_PARAMETER( |
| const TPM2B_ECC_PARAMETER& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_ECC_POINT( |
| const TPMS_ECC_POINT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ECC_POINT( |
| std::string* buffer, |
| TPMS_ECC_POINT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->x, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->y, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_ECC_POINT( |
| const TPM2B_ECC_POINT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_ECC_POINT( |
| std::string* buffer, |
| TPM2B_ECC_POINT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_ECC_POINT( |
| buffer, |
| &value->point, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_ECC_POINT Make_TPM2B_ECC_POINT( |
| const TPMS_ECC_POINT& inner) { |
| TPM2B_ECC_POINT tpm2b; |
| tpm2b.size = sizeof(TPMS_ECC_POINT); |
| tpm2b.point = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Serialize_TPMT_ECC_SCHEME( |
| const TPMT_ECC_SCHEME& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SIG_SCHEME( |
| value.details, |
| value.scheme, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_ECC_SCHEME( |
| std::string* buffer, |
| TPMT_ECC_SCHEME* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_ECC_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SIG_SCHEME( |
| buffer, |
| value->scheme, |
| &value->details, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC( |
| const TPMS_ALGORITHM_DETAIL_ECC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT16(value.key_size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC( |
| std::string* buffer, |
| TPMS_ALGORITHM_DETAIL_ECC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM_ECC_CURVE( |
| buffer, |
| &value->curve_id, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->key_size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_KDF_SCHEME( |
| buffer, |
| &value->kdf, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_ECC_SCHEME( |
| buffer, |
| &value->sign, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->p, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->a, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->b, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->g_x, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->g_y, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->n, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->h, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SIGNATURE_RSASSA( |
| const TPMS_SIGNATURE_RSASSA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SIGNATURE_RSASSA( |
| std::string* buffer, |
| TPMS_SIGNATURE_RSASSA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_PUBLIC_KEY_RSA( |
| buffer, |
| &value->sig, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS( |
| const TPMS_SIGNATURE_RSAPSS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SIGNATURE_RSAPSS( |
| std::string* buffer, |
| TPMS_SIGNATURE_RSAPSS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_PUBLIC_KEY_RSA( |
| buffer, |
| &value->sig, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_SIGNATURE_ECDSA( |
| const TPMS_SIGNATURE_ECDSA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_HASH(value.hash, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_SIGNATURE_ECDSA( |
| std::string* buffer, |
| TPMS_SIGNATURE_ECDSA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->signature_r, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->signature_s, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_SIGNATURE( |
| const TPMU_SIGNATURE& value, |
| TPMI_ALG_SIG_SCHEME selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Serialize_TPMT_HA(value.hmac, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SIGNATURE( |
| std::string* buffer, |
| TPMI_ALG_SIG_SCHEME selector, |
| TPMU_SIGNATURE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_HMAC) { |
| result = Parse_TPMT_HA( |
| buffer, |
| &value->hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECSCHNORR) { |
| result = Parse_TPMS_SIGNATURE_ECDSA( |
| buffer, |
| &value->ecschnorr, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSAPSS) { |
| result = Parse_TPMS_SIGNATURE_RSAPSS( |
| buffer, |
| &value->rsapss, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDAA) { |
| result = Parse_TPMS_SIGNATURE_ECDSA( |
| buffer, |
| &value->ecdaa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSASSA) { |
| result = Parse_TPMS_SIGNATURE_RSASSA( |
| buffer, |
| &value->rsassa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SM2) { |
| result = Parse_TPMS_SIGNATURE_ECDSA( |
| buffer, |
| &value->sm2, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECDSA) { |
| result = Parse_TPMS_SIGNATURE_ECDSA( |
| buffer, |
| &value->ecdsa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_NULL) { |
| // Do nothing. |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_SIGNATURE( |
| const TPMT_SIGNATURE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SIGNATURE( |
| value.signature, |
| value.sig_alg, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_SIGNATURE( |
| std::string* buffer, |
| TPMT_SIGNATURE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_SIG_SCHEME( |
| buffer, |
| &value->sig_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SIGNATURE( |
| buffer, |
| value->sig_alg, |
| &value->signature, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET( |
| const TPM2B_ENCRYPTED_SECRET& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.secret) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.secret[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_ENCRYPTED_SECRET( |
| std::string* buffer, |
| TPM2B_ENCRYPTED_SECRET* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->secret) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->secret[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET( |
| const std::string& bytes) { |
| TPM2B_ENCRYPTED_SECRET tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.secret)); |
| memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.secret, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_ENCRYPTED_SECRET( |
| const TPM2B_ENCRYPTED_SECRET& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.secret); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_KEYEDHASH_PARMS( |
| const TPMS_KEYEDHASH_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_KEYEDHASH_PARMS( |
| std::string* buffer, |
| TPMS_KEYEDHASH_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMT_KEYEDHASH_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_ASYM_PARMS( |
| const TPMS_ASYM_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ASYM_PARMS( |
| std::string* buffer, |
| TPMS_ASYM_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMT_SYM_DEF_OBJECT( |
| buffer, |
| &value->symmetric, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_ASYM_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_RSA_PARMS( |
| const TPMS_RSA_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT32(value.exponent, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_RSA_PARMS( |
| std::string* buffer, |
| TPMS_RSA_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMT_SYM_DEF_OBJECT( |
| buffer, |
| &value->symmetric, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_RSA_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_RSA_KEY_BITS( |
| buffer, |
| &value->key_bits, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT32( |
| buffer, |
| &value->exponent, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_ECC_PARMS( |
| const TPMS_ECC_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_ECC_PARMS( |
| std::string* buffer, |
| TPMS_ECC_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMT_SYM_DEF_OBJECT( |
| buffer, |
| &value->symmetric, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_ECC_SCHEME( |
| buffer, |
| &value->scheme, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_ECC_CURVE( |
| buffer, |
| &value->curve_id, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_KDF_SCHEME( |
| buffer, |
| &value->kdf, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_PUBLIC_PARMS( |
| const TPMU_PUBLIC_PARMS& value, |
| TPMI_ALG_PUBLIC selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_PUBLIC_PARMS( |
| std::string* buffer, |
| TPMI_ALG_PUBLIC selector, |
| TPMU_PUBLIC_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Parse_TPMS_KEYEDHASH_PARMS( |
| buffer, |
| &value->keyed_hash_detail, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Parse_TPMS_RSA_PARMS( |
| buffer, |
| &value->rsa_detail, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Parse_TPMS_SYMCIPHER_PARMS( |
| buffer, |
| &value->sym_detail, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Parse_TPMS_ECC_PARMS( |
| buffer, |
| &value->ecc_detail, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_PUBLIC_PARMS( |
| const TPMT_PUBLIC_PARMS& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_PUBLIC_PARMS( |
| value.parameters, |
| value.type, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_PUBLIC_PARMS( |
| std::string* buffer, |
| TPMT_PUBLIC_PARMS* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_PUBLIC( |
| buffer, |
| &value->type, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_PUBLIC_PARMS( |
| buffer, |
| value->type, |
| &value->parameters, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMU_PUBLIC_ID( |
| const TPMU_PUBLIC_ID& value, |
| TPMI_ALG_PUBLIC selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Serialize_TPM2B_DIGEST(value.sym, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Serialize_TPMS_ECC_POINT(value.ecc, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_PUBLIC_ID( |
| std::string* buffer, |
| TPMI_ALG_PUBLIC selector, |
| TPMU_PUBLIC_ID* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->keyed_hash, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Parse_TPM2B_PUBLIC_KEY_RSA( |
| buffer, |
| &value->rsa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->sym, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Parse_TPMS_ECC_POINT( |
| buffer, |
| &value->ecc, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_PUBLIC( |
| const TPMT_PUBLIC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_OBJECT(value.object_attributes, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_PUBLIC_PARMS( |
| value.parameters, |
| value.type, |
| buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_PUBLIC_ID( |
| value.unique, |
| value.type, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_PUBLIC( |
| std::string* buffer, |
| TPMT_PUBLIC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_PUBLIC( |
| buffer, |
| &value->type, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->name_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_OBJECT( |
| buffer, |
| &value->object_attributes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->auth_policy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_PUBLIC_PARMS( |
| buffer, |
| value->type, |
| &value->parameters, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_PUBLIC_ID( |
| buffer, |
| value->type, |
| &value->unique, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_PUBLIC( |
| const TPM2B_PUBLIC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_PUBLIC( |
| std::string* buffer, |
| TPM2B_PUBLIC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_PUBLIC( |
| buffer, |
| &value->public_area, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_PUBLIC Make_TPM2B_PUBLIC( |
| const TPMT_PUBLIC& inner) { |
| TPM2B_PUBLIC tpm2b; |
| tpm2b.size = sizeof(TPMT_PUBLIC); |
| tpm2b.public_area = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC( |
| const TPM2B_PRIVATE_VENDOR_SPECIFIC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC( |
| std::string* buffer, |
| TPM2B_PRIVATE_VENDOR_SPECIFIC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC( |
| const std::string& bytes) { |
| TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC( |
| const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE( |
| const TPMU_SENSITIVE_COMPOSITE& value, |
| TPMI_ALG_PUBLIC selector, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Serialize_TPM2B_SYM_KEY(value.sym, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE( |
| std::string* buffer, |
| TPMI_ALG_PUBLIC selector, |
| TPMU_SENSITIVE_COMPOSITE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| if (selector == TPM_ALG_KEYEDHASH) { |
| result = Parse_TPM2B_SENSITIVE_DATA( |
| buffer, |
| &value->bits, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_RSA) { |
| result = Parse_TPM2B_PRIVATE_KEY_RSA( |
| buffer, |
| &value->rsa, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_SYMCIPHER) { |
| result = Parse_TPM2B_SYM_KEY( |
| buffer, |
| &value->sym, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| |
| if (selector == TPM_ALG_ECC) { |
| result = Parse_TPM2B_ECC_PARAMETER( |
| buffer, |
| &value->ecc, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMT_SENSITIVE( |
| const TPMT_SENSITIVE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_AUTH(value.auth_value, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.seed_value, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMU_SENSITIVE_COMPOSITE( |
| value.sensitive, |
| value.sensitive_type, |
| buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMT_SENSITIVE( |
| std::string* buffer, |
| TPMT_SENSITIVE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_ALG_PUBLIC( |
| buffer, |
| &value->sensitive_type, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_AUTH( |
| buffer, |
| &value->auth_value, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->seed_value, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMU_SENSITIVE_COMPOSITE( |
| buffer, |
| value->sensitive_type, |
| &value->sensitive, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_SENSITIVE( |
| const TPM2B_SENSITIVE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_SENSITIVE( |
| std::string* buffer, |
| TPM2B_SENSITIVE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_SENSITIVE( |
| buffer, |
| &value->sensitive_area, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_SENSITIVE Make_TPM2B_SENSITIVE( |
| const TPMT_SENSITIVE& inner) { |
| TPM2B_SENSITIVE tpm2b; |
| tpm2b.size = sizeof(TPMT_SENSITIVE); |
| tpm2b.sensitive_area = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Serialize__PRIVATE( |
| const _PRIVATE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_DIGEST(value.integrity_outer, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.integrity_inner, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMT_SENSITIVE(value.sensitive, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse__PRIVATE( |
| std::string* buffer, |
| _PRIVATE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->integrity_outer, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->integrity_inner, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMT_SENSITIVE( |
| buffer, |
| &value->sensitive, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_PRIVATE( |
| const TPM2B_PRIVATE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_PRIVATE( |
| std::string* buffer, |
| TPM2B_PRIVATE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_PRIVATE Make_TPM2B_PRIVATE( |
| const std::string& bytes) { |
| TPM2B_PRIVATE tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_PRIVATE( |
| const TPM2B_PRIVATE& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize__ID_OBJECT( |
| const _ID_OBJECT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_DIGEST(value.integrity_hmac, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.enc_identity, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse__ID_OBJECT( |
| std::string* buffer, |
| _ID_OBJECT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->integrity_hmac, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->enc_identity, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_ID_OBJECT( |
| const TPM2B_ID_OBJECT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.credential) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.credential[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_ID_OBJECT( |
| std::string* buffer, |
| TPM2B_ID_OBJECT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->credential) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->credential[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT( |
| const std::string& bytes) { |
| TPM2B_ID_OBJECT tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.credential)); |
| memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.credential, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_ID_OBJECT( |
| const TPM2B_ID_OBJECT& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.credential); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_NV_PUBLIC( |
| const TPMS_NV_PUBLIC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_NV(value.attributes, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_UINT16(value.data_size, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_NV_PUBLIC( |
| std::string* buffer, |
| TPMS_NV_PUBLIC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPMI_RH_NV_INDEX( |
| buffer, |
| &value->nv_index, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_ALG_HASH( |
| buffer, |
| &value->name_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_NV( |
| buffer, |
| &value->attributes, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->auth_policy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->data_size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_NV_PUBLIC( |
| const TPM2B_NV_PUBLIC& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_NV_PUBLIC( |
| std::string* buffer, |
| TPM2B_NV_PUBLIC* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_NV_PUBLIC( |
| buffer, |
| &value->nv_public, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC( |
| const TPMS_NV_PUBLIC& inner) { |
| TPM2B_NV_PUBLIC tpm2b; |
| tpm2b.size = sizeof(TPMS_NV_PUBLIC); |
| tpm2b.nv_public = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE( |
| const TPM2B_CONTEXT_SENSITIVE& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE( |
| std::string* buffer, |
| TPM2B_CONTEXT_SENSITIVE* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE( |
| const std::string& bytes) { |
| TPM2B_CONTEXT_SENSITIVE tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_CONTEXT_SENSITIVE( |
| const TPM2B_CONTEXT_SENSITIVE& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_CONTEXT_DATA( |
| const TPMS_CONTEXT_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPM2B_DIGEST(value.integrity, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CONTEXT_DATA( |
| std::string* buffer, |
| TPMS_CONTEXT_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->integrity, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_CONTEXT_SENSITIVE( |
| buffer, |
| &value->encrypted, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_CONTEXT_DATA( |
| const TPM2B_CONTEXT_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT16(value.size, buffer); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value.buffer) < value.size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value.size; ++i) { |
| result = Serialize_BYTE(value.buffer[i], buffer); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_CONTEXT_DATA( |
| std::string* buffer, |
| TPM2B_CONTEXT_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| if (arraysize(value->buffer) < value->size) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| for (uint32_t i = 0; i < value->size; ++i) { |
| result = Parse_BYTE( |
| buffer, |
| &value->buffer[i], |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| } |
| return result; |
| } |
| |
| TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA( |
| const std::string& bytes) { |
| TPM2B_CONTEXT_DATA tpm2b; |
| CHECK(bytes.size() <= sizeof(tpm2b.buffer)); |
| memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA)); |
| tpm2b.size = bytes.size(); |
| memcpy(tpm2b.buffer, bytes.data(), bytes.size()); |
| return tpm2b; |
| } |
| |
| std::string StringFrom_TPM2B_CONTEXT_DATA( |
| const TPM2B_CONTEXT_DATA& tpm2b) { |
| const char* char_buffer = reinterpret_cast<const char*>( |
| tpm2b.buffer); |
| return std::string(char_buffer, tpm2b.size); |
| } |
| |
| TPM_RC Serialize_TPMS_CONTEXT( |
| const TPMS_CONTEXT& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_UINT64(value.sequence, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CONTEXT( |
| std::string* buffer, |
| TPMS_CONTEXT* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT64( |
| buffer, |
| &value->sequence, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_DH_CONTEXT( |
| buffer, |
| &value->saved_handle, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMI_RH_HIERARCHY( |
| buffer, |
| &value->hierarchy, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_CONTEXT_DATA( |
| buffer, |
| &value->context_blob, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPMS_CREATION_DATA( |
| const TPMS_CREATION_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPMA_LOCALITY(value.locality, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_NAME(value.parent_name, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer); |
| if (result) { |
| return result; |
| } |
| |
| result = Serialize_TPM2B_DATA(value.outside_info, buffer); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Parse_TPMS_CREATION_DATA( |
| std::string* buffer, |
| TPMS_CREATION_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_TPML_PCR_SELECTION( |
| buffer, |
| &value->pcr_select, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DIGEST( |
| buffer, |
| &value->pcr_digest, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMA_LOCALITY( |
| buffer, |
| &value->locality, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM_ALG_ID( |
| buffer, |
| &value->parent_name_alg, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->parent_name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_NAME( |
| buffer, |
| &value->parent_qualified_name, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPM2B_DATA( |
| buffer, |
| &value->outside_info, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM_RC Serialize_TPM2B_CREATION_DATA( |
| const TPM2B_CREATION_DATA& value, |
| std::string* buffer) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| std::string field_bytes; |
| result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes); |
| if (result) { |
| return result; |
| } |
| std::string size_bytes; |
| result = Serialize_UINT16(field_bytes.size(), &size_bytes); |
| if (result) { |
| return result; |
| } |
| buffer->append(size_bytes + field_bytes); |
| return result; |
| } |
| |
| TPM_RC Parse_TPM2B_CREATION_DATA( |
| std::string* buffer, |
| TPM2B_CREATION_DATA* value, |
| std::string* value_bytes) { |
| TPM_RC result = TPM_RC_SUCCESS; |
| VLOG(2) << __func__; |
| |
| result = Parse_UINT16( |
| buffer, |
| &value->size, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| |
| result = Parse_TPMS_CREATION_DATA( |
| buffer, |
| &value->creation_data, |
| value_bytes); |
| if (result) { |
| return result; |
| } |
| return result; |
| } |
| |
| TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA( |
| const TPMS_CREATION_DATA& inner) { |
| TPM2B_CREATION_DATA tpm2b; |
| tpm2b.size = sizeof(TPMS_CREATION_DATA); |
| tpm2b.creation_data = inner; |
| return tpm2b; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Startup( |
| const TPM_SU& startup_type, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Startup; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string startup_type_bytes; |
| rc = Serialize_TPM_SU( |
| startup_type, |
| &startup_type_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(startup_type_bytes.data(), |
| startup_type_bytes.size()); |
| parameter_section_bytes += startup_type_bytes; |
| command_size += startup_type_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Startup( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Startup; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void StartupErrorCallback( |
| const Tpm::StartupResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void StartupResponseParser( |
| const Tpm::StartupResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StartupErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_Startup( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::Startup( |
| const TPM_SU& startup_type, |
| AuthorizationDelegate* authorization_delegate, |
| const StartupResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StartupErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(StartupResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Startup( |
| startup_type, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::StartupSync( |
| const TPM_SU& startup_type, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Startup( |
| startup_type, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Startup( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Shutdown( |
| const TPM_SU& shutdown_type, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Shutdown; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string shutdown_type_bytes; |
| rc = Serialize_TPM_SU( |
| shutdown_type, |
| &shutdown_type_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(shutdown_type_bytes.data(), |
| shutdown_type_bytes.size()); |
| parameter_section_bytes += shutdown_type_bytes; |
| command_size += shutdown_type_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Shutdown( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Shutdown; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ShutdownErrorCallback( |
| const Tpm::ShutdownResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void ShutdownResponseParser( |
| const Tpm::ShutdownResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ShutdownErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_Shutdown( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::Shutdown( |
| const TPM_SU& shutdown_type, |
| AuthorizationDelegate* authorization_delegate, |
| const ShutdownResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ShutdownErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ShutdownResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Shutdown( |
| shutdown_type, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ShutdownSync( |
| const TPM_SU& shutdown_type, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Shutdown( |
| shutdown_type, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Shutdown( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SelfTest( |
| const TPMI_YES_NO& full_test, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SelfTest; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string full_test_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| full_test, |
| &full_test_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(full_test_bytes.data(), |
| full_test_bytes.size()); |
| parameter_section_bytes += full_test_bytes; |
| command_size += full_test_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SelfTest( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SelfTest; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SelfTestErrorCallback( |
| const Tpm::SelfTestResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void SelfTestResponseParser( |
| const Tpm::SelfTestResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SelfTestErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_SelfTest( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::SelfTest( |
| const TPMI_YES_NO& full_test, |
| AuthorizationDelegate* authorization_delegate, |
| const SelfTestResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SelfTestErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SelfTestResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SelfTest( |
| full_test, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SelfTestSync( |
| const TPMI_YES_NO& full_test, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SelfTest( |
| full_test, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SelfTest( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_IncrementalSelfTest( |
| const TPML_ALG& to_test, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_IncrementalSelfTest; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string to_test_bytes; |
| rc = Serialize_TPML_ALG( |
| to_test, |
| &to_test_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(to_test_bytes.data(), |
| to_test_bytes.size()); |
| parameter_section_bytes += to_test_bytes; |
| command_size += to_test_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_IncrementalSelfTest( |
| const std::string& response, |
| TPML_ALG* to_do_list, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_IncrementalSelfTest; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string to_do_list_bytes; |
| rc = Parse_TPML_ALG( |
| &buffer, |
| to_do_list, |
| &to_do_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void IncrementalSelfTestErrorCallback( |
| const Tpm::IncrementalSelfTestResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPML_ALG()); |
| } |
| |
| void IncrementalSelfTestResponseParser( |
| const Tpm::IncrementalSelfTestResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(IncrementalSelfTestErrorCallback, callback); |
| TPML_ALG to_do_list; |
| TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest( |
| response, |
| &to_do_list, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| to_do_list); |
| } |
| |
| void Tpm::IncrementalSelfTest( |
| const TPML_ALG& to_test, |
| AuthorizationDelegate* authorization_delegate, |
| const IncrementalSelfTestResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(IncrementalSelfTestErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(IncrementalSelfTestResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_IncrementalSelfTest( |
| to_test, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::IncrementalSelfTestSync( |
| const TPML_ALG& to_test, |
| TPML_ALG* to_do_list, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_IncrementalSelfTest( |
| to_test, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_IncrementalSelfTest( |
| response, |
| to_do_list, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetTestResult( |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetTestResult; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetTestResult( |
| const std::string& response, |
| TPM2B_MAX_BUFFER* out_data, |
| TPM_RC* test_result, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetTestResult; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_data_bytes; |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &buffer, |
| out_data, |
| &out_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string test_result_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| test_result, |
| &test_result_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &out_data_bytes, |
| out_data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetTestResultErrorCallback( |
| const Tpm::GetTestResultResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_MAX_BUFFER(), |
| TPM_RC()); |
| } |
| |
| void GetTestResultResponseParser( |
| const Tpm::GetTestResultResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetTestResultErrorCallback, callback); |
| TPM2B_MAX_BUFFER out_data; |
| TPM_RC test_result; |
| TPM_RC rc = Tpm::ParseResponse_GetTestResult( |
| response, |
| &out_data, |
| &test_result, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_data, |
| test_result); |
| } |
| |
| void Tpm::GetTestResult( |
| AuthorizationDelegate* authorization_delegate, |
| const GetTestResultResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetTestResultErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetTestResultResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetTestResult( |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetTestResultSync( |
| TPM2B_MAX_BUFFER* out_data, |
| TPM_RC* test_result, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetTestResult( |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetTestResult( |
| response, |
| out_data, |
| test_result, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_StartAuthSession( |
| const TPMI_DH_OBJECT& tpm_key, |
| const std::string& tpm_key_name, |
| const TPMI_DH_ENTITY& bind, |
| const std::string& bind_name, |
| const TPM2B_NONCE& nonce_caller, |
| const TPM2B_ENCRYPTED_SECRET& encrypted_salt, |
| const TPM_SE& session_type, |
| const TPMT_SYM_DEF& symmetric, |
| const TPMI_ALG_HASH& auth_hash, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_StartAuthSession; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string tpm_key_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| tpm_key, |
| &tpm_key_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string bind_bytes; |
| rc = Serialize_TPMI_DH_ENTITY( |
| bind, |
| &bind_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nonce_caller_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| nonce_caller, |
| &nonce_caller_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string encrypted_salt_bytes; |
| rc = Serialize_TPM2B_ENCRYPTED_SECRET( |
| encrypted_salt, |
| &encrypted_salt_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string session_type_bytes; |
| rc = Serialize_TPM_SE( |
| session_type, |
| &session_type_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string symmetric_bytes; |
| rc = Serialize_TPMT_SYM_DEF( |
| symmetric, |
| &symmetric_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_hash_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| auth_hash, |
| &auth_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = nonce_caller_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| nonce_caller_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(tpm_key_name.data(), |
| tpm_key_name.size()); |
| handle_section_bytes += tpm_key_bytes; |
| command_size += tpm_key_bytes.size(); |
| hash->Update(bind_name.data(), |
| bind_name.size()); |
| handle_section_bytes += bind_bytes; |
| command_size += bind_bytes.size(); |
| hash->Update(nonce_caller_bytes.data(), |
| nonce_caller_bytes.size()); |
| parameter_section_bytes += nonce_caller_bytes; |
| command_size += nonce_caller_bytes.size(); |
| hash->Update(encrypted_salt_bytes.data(), |
| encrypted_salt_bytes.size()); |
| parameter_section_bytes += encrypted_salt_bytes; |
| command_size += encrypted_salt_bytes.size(); |
| hash->Update(session_type_bytes.data(), |
| session_type_bytes.size()); |
| parameter_section_bytes += session_type_bytes; |
| command_size += session_type_bytes.size(); |
| hash->Update(symmetric_bytes.data(), |
| symmetric_bytes.size()); |
| parameter_section_bytes += symmetric_bytes; |
| command_size += symmetric_bytes.size(); |
| hash->Update(auth_hash_bytes.data(), |
| auth_hash_bytes.size()); |
| parameter_section_bytes += auth_hash_bytes; |
| command_size += auth_hash_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_StartAuthSession( |
| const std::string& response, |
| TPMI_SH_AUTH_SESSION* session_handle, |
| TPM2B_NONCE* nonce_tpm, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string session_handle_bytes; |
| rc = Parse_TPMI_SH_AUTH_SESSION( |
| &buffer, |
| session_handle, |
| &session_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_StartAuthSession; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string nonce_tpm_bytes; |
| rc = Parse_TPM2B_NONCE( |
| &buffer, |
| nonce_tpm, |
| &nonce_tpm_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = nonce_tpm_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| nonce_tpm_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_NONCE( |
| &nonce_tpm_bytes, |
| nonce_tpm, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void StartAuthSessionErrorCallback( |
| const Tpm::StartAuthSessionResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_SH_AUTH_SESSION(), |
| TPM2B_NONCE()); |
| } |
| |
| void StartAuthSessionResponseParser( |
| const Tpm::StartAuthSessionResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StartAuthSessionErrorCallback, callback); |
| TPMI_SH_AUTH_SESSION session_handle; |
| TPM2B_NONCE nonce_tpm; |
| TPM_RC rc = Tpm::ParseResponse_StartAuthSession( |
| response, |
| &session_handle, |
| &nonce_tpm, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| session_handle, |
| nonce_tpm); |
| } |
| |
| void Tpm::StartAuthSession( |
| const TPMI_DH_OBJECT& tpm_key, |
| const std::string& tpm_key_name, |
| const TPMI_DH_ENTITY& bind, |
| const std::string& bind_name, |
| const TPM2B_NONCE& nonce_caller, |
| const TPM2B_ENCRYPTED_SECRET& encrypted_salt, |
| const TPM_SE& session_type, |
| const TPMT_SYM_DEF& symmetric, |
| const TPMI_ALG_HASH& auth_hash, |
| AuthorizationDelegate* authorization_delegate, |
| const StartAuthSessionResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StartAuthSessionErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(StartAuthSessionResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_StartAuthSession( |
| tpm_key, |
| tpm_key_name, |
| bind, |
| bind_name, |
| nonce_caller, |
| encrypted_salt, |
| session_type, |
| symmetric, |
| auth_hash, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::StartAuthSessionSync( |
| const TPMI_DH_OBJECT& tpm_key, |
| const std::string& tpm_key_name, |
| const TPMI_DH_ENTITY& bind, |
| const std::string& bind_name, |
| const TPM2B_NONCE& nonce_caller, |
| const TPM2B_ENCRYPTED_SECRET& encrypted_salt, |
| const TPM_SE& session_type, |
| const TPMT_SYM_DEF& symmetric, |
| const TPMI_ALG_HASH& auth_hash, |
| TPMI_SH_AUTH_SESSION* session_handle, |
| TPM2B_NONCE* nonce_tpm, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_StartAuthSession( |
| tpm_key, |
| tpm_key_name, |
| bind, |
| bind_name, |
| nonce_caller, |
| encrypted_salt, |
| session_type, |
| symmetric, |
| auth_hash, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_StartAuthSession( |
| response, |
| session_handle, |
| nonce_tpm, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyRestart( |
| const TPMI_SH_POLICY& session_handle, |
| const std::string& session_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyRestart; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string session_handle_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| session_handle, |
| &session_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(session_handle_name.data(), |
| session_handle_name.size()); |
| handle_section_bytes += session_handle_bytes; |
| command_size += session_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyRestart( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyRestart; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyRestartErrorCallback( |
| const Tpm::PolicyRestartResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyRestartResponseParser( |
| const Tpm::PolicyRestartResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyRestartErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyRestart( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyRestart( |
| const TPMI_SH_POLICY& session_handle, |
| const std::string& session_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyRestartResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyRestartErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyRestartResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyRestart( |
| session_handle, |
| session_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyRestartSync( |
| const TPMI_SH_POLICY& session_handle, |
| const std::string& session_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyRestart( |
| session_handle, |
| session_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyRestart( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Create( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Create; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string parent_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| parent_handle, |
| &parent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_sensitive_bytes; |
| rc = Serialize_TPM2B_SENSITIVE_CREATE( |
| in_sensitive, |
| &in_sensitive_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_public_bytes; |
| rc = Serialize_TPM2B_PUBLIC( |
| in_public, |
| &in_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string outside_info_bytes; |
| rc = Serialize_TPM2B_DATA( |
| outside_info, |
| &outside_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_pcr_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| creation_pcr, |
| &creation_pcr_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_sensitive_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_sensitive_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(parent_handle_name.data(), |
| parent_handle_name.size()); |
| handle_section_bytes += parent_handle_bytes; |
| command_size += parent_handle_bytes.size(); |
| hash->Update(in_sensitive_bytes.data(), |
| in_sensitive_bytes.size()); |
| parameter_section_bytes += in_sensitive_bytes; |
| command_size += in_sensitive_bytes.size(); |
| hash->Update(in_public_bytes.data(), |
| in_public_bytes.size()); |
| parameter_section_bytes += in_public_bytes; |
| command_size += in_public_bytes.size(); |
| hash->Update(outside_info_bytes.data(), |
| outside_info_bytes.size()); |
| parameter_section_bytes += outside_info_bytes; |
| command_size += outside_info_bytes.size(); |
| hash->Update(creation_pcr_bytes.data(), |
| creation_pcr_bytes.size()); |
| parameter_section_bytes += creation_pcr_bytes; |
| command_size += creation_pcr_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Create( |
| const std::string& response, |
| TPM2B_PRIVATE* out_private, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_CREATION_DATA* creation_data, |
| TPM2B_DIGEST* creation_hash, |
| TPMT_TK_CREATION* creation_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Create; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_private_bytes; |
| rc = Parse_TPM2B_PRIVATE( |
| &buffer, |
| out_private, |
| &out_private_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string out_public_bytes; |
| rc = Parse_TPM2B_PUBLIC( |
| &buffer, |
| out_public, |
| &out_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_data_bytes; |
| rc = Parse_TPM2B_CREATION_DATA( |
| &buffer, |
| creation_data, |
| &creation_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_hash_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| creation_hash, |
| &creation_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_ticket_bytes; |
| rc = Parse_TPMT_TK_CREATION( |
| &buffer, |
| creation_ticket, |
| &creation_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_private_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_private_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PRIVATE( |
| &out_private_bytes, |
| out_private, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void CreateErrorCallback( |
| const Tpm::CreateResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PRIVATE(), |
| TPM2B_PUBLIC(), |
| TPM2B_CREATION_DATA(), |
| TPM2B_DIGEST(), |
| TPMT_TK_CREATION()); |
| } |
| |
| void CreateResponseParser( |
| const Tpm::CreateResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CreateErrorCallback, callback); |
| TPM2B_PRIVATE out_private; |
| TPM2B_PUBLIC out_public; |
| TPM2B_CREATION_DATA creation_data; |
| TPM2B_DIGEST creation_hash; |
| TPMT_TK_CREATION creation_ticket; |
| TPM_RC rc = Tpm::ParseResponse_Create( |
| response, |
| &out_private, |
| &out_public, |
| &creation_data, |
| &creation_hash, |
| &creation_ticket, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_private, |
| out_public, |
| creation_data, |
| creation_hash, |
| creation_ticket); |
| } |
| |
| void Tpm::Create( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| AuthorizationDelegate* authorization_delegate, |
| const CreateResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CreateErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(CreateResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Create( |
| parent_handle, |
| parent_handle_name, |
| in_sensitive, |
| in_public, |
| outside_info, |
| creation_pcr, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::CreateSync( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| TPM2B_PRIVATE* out_private, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_CREATION_DATA* creation_data, |
| TPM2B_DIGEST* creation_hash, |
| TPMT_TK_CREATION* creation_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Create( |
| parent_handle, |
| parent_handle_name, |
| in_sensitive, |
| in_public, |
| outside_info, |
| creation_pcr, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Create( |
| response, |
| out_private, |
| out_public, |
| creation_data, |
| creation_hash, |
| creation_ticket, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Load( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_PRIVATE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Load; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string parent_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| parent_handle, |
| &parent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_private_bytes; |
| rc = Serialize_TPM2B_PRIVATE( |
| in_private, |
| &in_private_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_public_bytes; |
| rc = Serialize_TPM2B_PUBLIC( |
| in_public, |
| &in_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_private_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_private_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(parent_handle_name.data(), |
| parent_handle_name.size()); |
| handle_section_bytes += parent_handle_bytes; |
| command_size += parent_handle_bytes.size(); |
| hash->Update(in_private_bytes.data(), |
| in_private_bytes.size()); |
| parameter_section_bytes += in_private_bytes; |
| command_size += in_private_bytes.size(); |
| hash->Update(in_public_bytes.data(), |
| in_public_bytes.size()); |
| parameter_section_bytes += in_public_bytes; |
| command_size += in_public_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Load( |
| const std::string& response, |
| TPM_HANDLE* object_handle, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string object_handle_bytes; |
| rc = Parse_TPM_HANDLE( |
| &buffer, |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_Load; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| name, |
| &name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = name_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| name_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_NAME( |
| &name_bytes, |
| name, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void LoadErrorCallback( |
| const Tpm::LoadResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_HANDLE(), |
| TPM2B_NAME()); |
| } |
| |
| void LoadResponseParser( |
| const Tpm::LoadResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(LoadErrorCallback, callback); |
| TPM_HANDLE object_handle; |
| TPM2B_NAME name; |
| TPM_RC rc = Tpm::ParseResponse_Load( |
| response, |
| &object_handle, |
| &name, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| object_handle, |
| name); |
| } |
| |
| void Tpm::Load( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_PRIVATE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| AuthorizationDelegate* authorization_delegate, |
| const LoadResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(LoadErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(LoadResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Load( |
| parent_handle, |
| parent_handle_name, |
| in_private, |
| in_public, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::LoadSync( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_PRIVATE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| TPM_HANDLE* object_handle, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Load( |
| parent_handle, |
| parent_handle_name, |
| in_private, |
| in_public, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Load( |
| response, |
| object_handle, |
| name, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_LoadExternal( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_SENSITIVE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_LoadExternal; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_private_bytes; |
| rc = Serialize_TPM2B_SENSITIVE( |
| in_private, |
| &in_private_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_public_bytes; |
| rc = Serialize_TPM2B_PUBLIC( |
| in_public, |
| &in_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hierarchy_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| hierarchy, |
| &hierarchy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_private_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_private_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(hierarchy_name.data(), |
| hierarchy_name.size()); |
| handle_section_bytes += hierarchy_bytes; |
| command_size += hierarchy_bytes.size(); |
| hash->Update(in_private_bytes.data(), |
| in_private_bytes.size()); |
| parameter_section_bytes += in_private_bytes; |
| command_size += in_private_bytes.size(); |
| hash->Update(in_public_bytes.data(), |
| in_public_bytes.size()); |
| parameter_section_bytes += in_public_bytes; |
| command_size += in_public_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_LoadExternal( |
| const std::string& response, |
| TPM_HANDLE* object_handle, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string object_handle_bytes; |
| rc = Parse_TPM_HANDLE( |
| &buffer, |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_LoadExternal; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| name, |
| &name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = name_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| name_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_NAME( |
| &name_bytes, |
| name, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void LoadExternalErrorCallback( |
| const Tpm::LoadExternalResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_HANDLE(), |
| TPM2B_NAME()); |
| } |
| |
| void LoadExternalResponseParser( |
| const Tpm::LoadExternalResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(LoadExternalErrorCallback, callback); |
| TPM_HANDLE object_handle; |
| TPM2B_NAME name; |
| TPM_RC rc = Tpm::ParseResponse_LoadExternal( |
| response, |
| &object_handle, |
| &name, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| object_handle, |
| name); |
| } |
| |
| void Tpm::LoadExternal( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_SENSITIVE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| AuthorizationDelegate* authorization_delegate, |
| const LoadExternalResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(LoadExternalErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(LoadExternalResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_LoadExternal( |
| hierarchy, |
| hierarchy_name, |
| in_private, |
| in_public, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::LoadExternalSync( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_SENSITIVE& in_private, |
| const TPM2B_PUBLIC& in_public, |
| TPM_HANDLE* object_handle, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_LoadExternal( |
| hierarchy, |
| hierarchy_name, |
| in_private, |
| in_public, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_LoadExternal( |
| response, |
| object_handle, |
| name, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ReadPublic( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ReadPublic; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ReadPublic( |
| const std::string& response, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_NAME* name, |
| TPM2B_NAME* qualified_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ReadPublic; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_public_bytes; |
| rc = Parse_TPM2B_PUBLIC( |
| &buffer, |
| out_public, |
| &out_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| name, |
| &name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualified_name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| qualified_name, |
| &qualified_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_public_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_public_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PUBLIC( |
| &out_public_bytes, |
| out_public, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ReadPublicErrorCallback( |
| const Tpm::ReadPublicResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PUBLIC(), |
| TPM2B_NAME(), |
| TPM2B_NAME()); |
| } |
| |
| void ReadPublicResponseParser( |
| const Tpm::ReadPublicResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ReadPublicErrorCallback, callback); |
| TPM2B_PUBLIC out_public; |
| TPM2B_NAME name; |
| TPM2B_NAME qualified_name; |
| TPM_RC rc = Tpm::ParseResponse_ReadPublic( |
| response, |
| &out_public, |
| &name, |
| &qualified_name, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_public, |
| name, |
| qualified_name); |
| } |
| |
| void Tpm::ReadPublic( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ReadPublicResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ReadPublicErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ReadPublicResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ReadPublic( |
| object_handle, |
| object_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ReadPublicSync( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_NAME* name, |
| TPM2B_NAME* qualified_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ReadPublic( |
| object_handle, |
| object_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ReadPublic( |
| response, |
| out_public, |
| name, |
| qualified_name, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ActivateCredential( |
| const TPMI_DH_OBJECT& activate_handle, |
| const std::string& activate_handle_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ID_OBJECT& credential_blob, |
| const TPM2B_ENCRYPTED_SECRET& secret, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ActivateCredential; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string activate_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| activate_handle, |
| &activate_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string credential_blob_bytes; |
| rc = Serialize_TPM2B_ID_OBJECT( |
| credential_blob, |
| &credential_blob_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string secret_bytes; |
| rc = Serialize_TPM2B_ENCRYPTED_SECRET( |
| secret, |
| &secret_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = credential_blob_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| credential_blob_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(activate_handle_name.data(), |
| activate_handle_name.size()); |
| handle_section_bytes += activate_handle_bytes; |
| command_size += activate_handle_bytes.size(); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(credential_blob_bytes.data(), |
| credential_blob_bytes.size()); |
| parameter_section_bytes += credential_blob_bytes; |
| command_size += credential_blob_bytes.size(); |
| hash->Update(secret_bytes.data(), |
| secret_bytes.size()); |
| parameter_section_bytes += secret_bytes; |
| command_size += secret_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ActivateCredential( |
| const std::string& response, |
| TPM2B_DIGEST* cert_info, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ActivateCredential; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string cert_info_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| cert_info, |
| &cert_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = cert_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| cert_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &cert_info_bytes, |
| cert_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ActivateCredentialErrorCallback( |
| const Tpm::ActivateCredentialResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST()); |
| } |
| |
| void ActivateCredentialResponseParser( |
| const Tpm::ActivateCredentialResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ActivateCredentialErrorCallback, callback); |
| TPM2B_DIGEST cert_info; |
| TPM_RC rc = Tpm::ParseResponse_ActivateCredential( |
| response, |
| &cert_info, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| cert_info); |
| } |
| |
| void Tpm::ActivateCredential( |
| const TPMI_DH_OBJECT& activate_handle, |
| const std::string& activate_handle_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ID_OBJECT& credential_blob, |
| const TPM2B_ENCRYPTED_SECRET& secret, |
| AuthorizationDelegate* authorization_delegate, |
| const ActivateCredentialResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ActivateCredentialErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ActivateCredentialResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ActivateCredential( |
| activate_handle, |
| activate_handle_name, |
| key_handle, |
| key_handle_name, |
| credential_blob, |
| secret, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ActivateCredentialSync( |
| const TPMI_DH_OBJECT& activate_handle, |
| const std::string& activate_handle_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ID_OBJECT& credential_blob, |
| const TPM2B_ENCRYPTED_SECRET& secret, |
| TPM2B_DIGEST* cert_info, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ActivateCredential( |
| activate_handle, |
| activate_handle_name, |
| key_handle, |
| key_handle_name, |
| credential_blob, |
| secret, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ActivateCredential( |
| response, |
| cert_info, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_MakeCredential( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_DIGEST& credential, |
| const TPM2B_NAME& object_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_MakeCredential; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| handle, |
| &handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string credential_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| credential, |
| &credential_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_name_bytes; |
| rc = Serialize_TPM2B_NAME( |
| object_name, |
| &object_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = credential_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| credential_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(handle_name.data(), |
| handle_name.size()); |
| handle_section_bytes += handle_bytes; |
| command_size += handle_bytes.size(); |
| hash->Update(credential_bytes.data(), |
| credential_bytes.size()); |
| parameter_section_bytes += credential_bytes; |
| command_size += credential_bytes.size(); |
| hash->Update(object_name_bytes.data(), |
| object_name_bytes.size()); |
| parameter_section_bytes += object_name_bytes; |
| command_size += object_name_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_MakeCredential( |
| const std::string& response, |
| TPM2B_ID_OBJECT* credential_blob, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_MakeCredential; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string credential_blob_bytes; |
| rc = Parse_TPM2B_ID_OBJECT( |
| &buffer, |
| credential_blob, |
| &credential_blob_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = credential_blob_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| credential_blob_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ID_OBJECT( |
| &credential_blob_bytes, |
| credential_blob, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void MakeCredentialErrorCallback( |
| const Tpm::MakeCredentialResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ID_OBJECT()); |
| } |
| |
| void MakeCredentialResponseParser( |
| const Tpm::MakeCredentialResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(MakeCredentialErrorCallback, callback); |
| TPM2B_ID_OBJECT credential_blob; |
| TPM_RC rc = Tpm::ParseResponse_MakeCredential( |
| response, |
| &credential_blob, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| credential_blob); |
| } |
| |
| void Tpm::MakeCredential( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_DIGEST& credential, |
| const TPM2B_NAME& object_name, |
| AuthorizationDelegate* authorization_delegate, |
| const MakeCredentialResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(MakeCredentialErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(MakeCredentialResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_MakeCredential( |
| handle, |
| handle_name, |
| credential, |
| object_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::MakeCredentialSync( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_DIGEST& credential, |
| const TPM2B_NAME& object_name, |
| TPM2B_ID_OBJECT* credential_blob, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_MakeCredential( |
| handle, |
| handle_name, |
| credential, |
| object_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_MakeCredential( |
| response, |
| credential_blob, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Unseal( |
| const TPMI_DH_OBJECT& item_handle, |
| const std::string& item_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Unseal; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string item_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| item_handle, |
| &item_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(item_handle_name.data(), |
| item_handle_name.size()); |
| handle_section_bytes += item_handle_bytes; |
| command_size += item_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Unseal( |
| const std::string& response, |
| TPM2B_SENSITIVE_DATA* out_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Unseal; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_data_bytes; |
| rc = Parse_TPM2B_SENSITIVE_DATA( |
| &buffer, |
| out_data, |
| &out_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_SENSITIVE_DATA( |
| &out_data_bytes, |
| out_data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void UnsealErrorCallback( |
| const Tpm::UnsealResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_SENSITIVE_DATA()); |
| } |
| |
| void UnsealResponseParser( |
| const Tpm::UnsealResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(UnsealErrorCallback, callback); |
| TPM2B_SENSITIVE_DATA out_data; |
| TPM_RC rc = Tpm::ParseResponse_Unseal( |
| response, |
| &out_data, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_data); |
| } |
| |
| void Tpm::Unseal( |
| const TPMI_DH_OBJECT& item_handle, |
| const std::string& item_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const UnsealResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(UnsealErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(UnsealResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Unseal( |
| item_handle, |
| item_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::UnsealSync( |
| const TPMI_DH_OBJECT& item_handle, |
| const std::string& item_handle_name, |
| TPM2B_SENSITIVE_DATA* out_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Unseal( |
| item_handle, |
| item_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Unseal( |
| response, |
| out_data, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ObjectChangeAuth( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_AUTH& new_auth, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ObjectChangeAuth; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string parent_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| parent_handle, |
| &parent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| new_auth, |
| &new_auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = new_auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| new_auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| hash->Update(parent_handle_name.data(), |
| parent_handle_name.size()); |
| handle_section_bytes += parent_handle_bytes; |
| command_size += parent_handle_bytes.size(); |
| hash->Update(new_auth_bytes.data(), |
| new_auth_bytes.size()); |
| parameter_section_bytes += new_auth_bytes; |
| command_size += new_auth_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ObjectChangeAuth( |
| const std::string& response, |
| TPM2B_PRIVATE* out_private, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ObjectChangeAuth; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_private_bytes; |
| rc = Parse_TPM2B_PRIVATE( |
| &buffer, |
| out_private, |
| &out_private_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_private_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_private_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PRIVATE( |
| &out_private_bytes, |
| out_private, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ObjectChangeAuthErrorCallback( |
| const Tpm::ObjectChangeAuthResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PRIVATE()); |
| } |
| |
| void ObjectChangeAuthResponseParser( |
| const Tpm::ObjectChangeAuthResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ObjectChangeAuthErrorCallback, callback); |
| TPM2B_PRIVATE out_private; |
| TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth( |
| response, |
| &out_private, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_private); |
| } |
| |
| void Tpm::ObjectChangeAuth( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_AUTH& new_auth, |
| AuthorizationDelegate* authorization_delegate, |
| const ObjectChangeAuthResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ObjectChangeAuthErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ObjectChangeAuthResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ObjectChangeAuth( |
| object_handle, |
| object_handle_name, |
| parent_handle, |
| parent_handle_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ObjectChangeAuthSync( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_AUTH& new_auth, |
| TPM2B_PRIVATE* out_private, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ObjectChangeAuth( |
| object_handle, |
| object_handle_name, |
| parent_handle, |
| parent_handle_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ObjectChangeAuth( |
| response, |
| out_private, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Duplicate( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& new_parent_handle, |
| const std::string& new_parent_handle_name, |
| const TPM2B_DATA& encryption_key_in, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Duplicate; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_parent_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| new_parent_handle, |
| &new_parent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string encryption_key_in_bytes; |
| rc = Serialize_TPM2B_DATA( |
| encryption_key_in, |
| &encryption_key_in_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string symmetric_alg_bytes; |
| rc = Serialize_TPMT_SYM_DEF_OBJECT( |
| symmetric_alg, |
| &symmetric_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = encryption_key_in_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| encryption_key_in_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| hash->Update(new_parent_handle_name.data(), |
| new_parent_handle_name.size()); |
| handle_section_bytes += new_parent_handle_bytes; |
| command_size += new_parent_handle_bytes.size(); |
| hash->Update(encryption_key_in_bytes.data(), |
| encryption_key_in_bytes.size()); |
| parameter_section_bytes += encryption_key_in_bytes; |
| command_size += encryption_key_in_bytes.size(); |
| hash->Update(symmetric_alg_bytes.data(), |
| symmetric_alg_bytes.size()); |
| parameter_section_bytes += symmetric_alg_bytes; |
| command_size += symmetric_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Duplicate( |
| const std::string& response, |
| TPM2B_DATA* encryption_key_out, |
| TPM2B_PRIVATE* duplicate, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Duplicate; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string encryption_key_out_bytes; |
| rc = Parse_TPM2B_DATA( |
| &buffer, |
| encryption_key_out, |
| &encryption_key_out_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string duplicate_bytes; |
| rc = Parse_TPM2B_PRIVATE( |
| &buffer, |
| duplicate, |
| &duplicate_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = encryption_key_out_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| encryption_key_out_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DATA( |
| &encryption_key_out_bytes, |
| encryption_key_out, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void DuplicateErrorCallback( |
| const Tpm::DuplicateResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DATA(), |
| TPM2B_PRIVATE()); |
| } |
| |
| void DuplicateResponseParser( |
| const Tpm::DuplicateResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DuplicateErrorCallback, callback); |
| TPM2B_DATA encryption_key_out; |
| TPM2B_PRIVATE duplicate; |
| TPM_RC rc = Tpm::ParseResponse_Duplicate( |
| response, |
| &encryption_key_out, |
| &duplicate, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| encryption_key_out, |
| duplicate); |
| } |
| |
| void Tpm::Duplicate( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& new_parent_handle, |
| const std::string& new_parent_handle_name, |
| const TPM2B_DATA& encryption_key_in, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const DuplicateResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DuplicateErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(DuplicateResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Duplicate( |
| object_handle, |
| object_handle_name, |
| new_parent_handle, |
| new_parent_handle_name, |
| encryption_key_in, |
| symmetric_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::DuplicateSync( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& new_parent_handle, |
| const std::string& new_parent_handle_name, |
| const TPM2B_DATA& encryption_key_in, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| TPM2B_DATA* encryption_key_out, |
| TPM2B_PRIVATE* duplicate, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Duplicate( |
| object_handle, |
| object_handle_name, |
| new_parent_handle, |
| new_parent_handle_name, |
| encryption_key_in, |
| symmetric_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Duplicate( |
| response, |
| encryption_key_out, |
| duplicate, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Rewrap( |
| const TPMI_DH_OBJECT& old_parent, |
| const std::string& old_parent_name, |
| const TPMI_DH_OBJECT& new_parent, |
| const std::string& new_parent_name, |
| const TPM2B_PRIVATE& in_duplicate, |
| const TPM2B_NAME& name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Rewrap; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string old_parent_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| old_parent, |
| &old_parent_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_parent_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| new_parent, |
| &new_parent_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_duplicate_bytes; |
| rc = Serialize_TPM2B_PRIVATE( |
| in_duplicate, |
| &in_duplicate_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string name_bytes; |
| rc = Serialize_TPM2B_NAME( |
| name, |
| &name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_duplicate_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_duplicate_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(old_parent_name.data(), |
| old_parent_name.size()); |
| handle_section_bytes += old_parent_bytes; |
| command_size += old_parent_bytes.size(); |
| hash->Update(new_parent_name.data(), |
| new_parent_name.size()); |
| handle_section_bytes += new_parent_bytes; |
| command_size += new_parent_bytes.size(); |
| hash->Update(in_duplicate_bytes.data(), |
| in_duplicate_bytes.size()); |
| parameter_section_bytes += in_duplicate_bytes; |
| command_size += in_duplicate_bytes.size(); |
| hash->Update(name_bytes.data(), |
| name_bytes.size()); |
| parameter_section_bytes += name_bytes; |
| command_size += name_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Rewrap( |
| const std::string& response, |
| TPM2B_PRIVATE* out_duplicate, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Rewrap; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_duplicate_bytes; |
| rc = Parse_TPM2B_PRIVATE( |
| &buffer, |
| out_duplicate, |
| &out_duplicate_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_duplicate_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_duplicate_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PRIVATE( |
| &out_duplicate_bytes, |
| out_duplicate, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void RewrapErrorCallback( |
| const Tpm::RewrapResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PRIVATE()); |
| } |
| |
| void RewrapResponseParser( |
| const Tpm::RewrapResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RewrapErrorCallback, callback); |
| TPM2B_PRIVATE out_duplicate; |
| TPM_RC rc = Tpm::ParseResponse_Rewrap( |
| response, |
| &out_duplicate, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_duplicate); |
| } |
| |
| void Tpm::Rewrap( |
| const TPMI_DH_OBJECT& old_parent, |
| const std::string& old_parent_name, |
| const TPMI_DH_OBJECT& new_parent, |
| const std::string& new_parent_name, |
| const TPM2B_PRIVATE& in_duplicate, |
| const TPM2B_NAME& name, |
| AuthorizationDelegate* authorization_delegate, |
| const RewrapResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RewrapErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(RewrapResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Rewrap( |
| old_parent, |
| old_parent_name, |
| new_parent, |
| new_parent_name, |
| in_duplicate, |
| name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::RewrapSync( |
| const TPMI_DH_OBJECT& old_parent, |
| const std::string& old_parent_name, |
| const TPMI_DH_OBJECT& new_parent, |
| const std::string& new_parent_name, |
| const TPM2B_PRIVATE& in_duplicate, |
| const TPM2B_NAME& name, |
| TPM2B_PRIVATE* out_duplicate, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Rewrap( |
| old_parent, |
| old_parent_name, |
| new_parent, |
| new_parent_name, |
| in_duplicate, |
| name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Rewrap( |
| response, |
| out_duplicate, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Import( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_DATA& encryption_key, |
| const TPM2B_PUBLIC& object_public, |
| const TPM2B_PRIVATE& duplicate, |
| const TPM2B_ENCRYPTED_SECRET& in_sym_seed, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Import; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string parent_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| parent_handle, |
| &parent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string encryption_key_bytes; |
| rc = Serialize_TPM2B_DATA( |
| encryption_key, |
| &encryption_key_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_public_bytes; |
| rc = Serialize_TPM2B_PUBLIC( |
| object_public, |
| &object_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string duplicate_bytes; |
| rc = Serialize_TPM2B_PRIVATE( |
| duplicate, |
| &duplicate_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_sym_seed_bytes; |
| rc = Serialize_TPM2B_ENCRYPTED_SECRET( |
| in_sym_seed, |
| &in_sym_seed_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string symmetric_alg_bytes; |
| rc = Serialize_TPMT_SYM_DEF_OBJECT( |
| symmetric_alg, |
| &symmetric_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = encryption_key_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| encryption_key_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(parent_handle_name.data(), |
| parent_handle_name.size()); |
| handle_section_bytes += parent_handle_bytes; |
| command_size += parent_handle_bytes.size(); |
| hash->Update(encryption_key_bytes.data(), |
| encryption_key_bytes.size()); |
| parameter_section_bytes += encryption_key_bytes; |
| command_size += encryption_key_bytes.size(); |
| hash->Update(object_public_bytes.data(), |
| object_public_bytes.size()); |
| parameter_section_bytes += object_public_bytes; |
| command_size += object_public_bytes.size(); |
| hash->Update(duplicate_bytes.data(), |
| duplicate_bytes.size()); |
| parameter_section_bytes += duplicate_bytes; |
| command_size += duplicate_bytes.size(); |
| hash->Update(in_sym_seed_bytes.data(), |
| in_sym_seed_bytes.size()); |
| parameter_section_bytes += in_sym_seed_bytes; |
| command_size += in_sym_seed_bytes.size(); |
| hash->Update(symmetric_alg_bytes.data(), |
| symmetric_alg_bytes.size()); |
| parameter_section_bytes += symmetric_alg_bytes; |
| command_size += symmetric_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Import( |
| const std::string& response, |
| TPM2B_PRIVATE* out_private, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Import; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_private_bytes; |
| rc = Parse_TPM2B_PRIVATE( |
| &buffer, |
| out_private, |
| &out_private_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_private_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_private_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PRIVATE( |
| &out_private_bytes, |
| out_private, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ImportErrorCallback( |
| const Tpm::ImportResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PRIVATE()); |
| } |
| |
| void ImportResponseParser( |
| const Tpm::ImportResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ImportErrorCallback, callback); |
| TPM2B_PRIVATE out_private; |
| TPM_RC rc = Tpm::ParseResponse_Import( |
| response, |
| &out_private, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_private); |
| } |
| |
| void Tpm::Import( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_DATA& encryption_key, |
| const TPM2B_PUBLIC& object_public, |
| const TPM2B_PRIVATE& duplicate, |
| const TPM2B_ENCRYPTED_SECRET& in_sym_seed, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const ImportResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ImportErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ImportResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Import( |
| parent_handle, |
| parent_handle_name, |
| encryption_key, |
| object_public, |
| duplicate, |
| in_sym_seed, |
| symmetric_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ImportSync( |
| const TPMI_DH_OBJECT& parent_handle, |
| const std::string& parent_handle_name, |
| const TPM2B_DATA& encryption_key, |
| const TPM2B_PUBLIC& object_public, |
| const TPM2B_PRIVATE& duplicate, |
| const TPM2B_ENCRYPTED_SECRET& in_sym_seed, |
| const TPMT_SYM_DEF_OBJECT& symmetric_alg, |
| TPM2B_PRIVATE* out_private, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Import( |
| parent_handle, |
| parent_handle_name, |
| encryption_key, |
| object_public, |
| duplicate, |
| in_sym_seed, |
| symmetric_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Import( |
| response, |
| out_private, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_RSA_Encrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& message, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_RSA_Encrypt; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string message_bytes; |
| rc = Serialize_TPM2B_PUBLIC_KEY_RSA( |
| message, |
| &message_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_RSA_DECRYPT( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string label_bytes; |
| rc = Serialize_TPM2B_DATA( |
| label, |
| &label_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = message_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| message_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(message_bytes.data(), |
| message_bytes.size()); |
| parameter_section_bytes += message_bytes; |
| command_size += message_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(label_bytes.data(), |
| label_bytes.size()); |
| parameter_section_bytes += label_bytes; |
| command_size += label_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_RSA_Encrypt( |
| const std::string& response, |
| TPM2B_PUBLIC_KEY_RSA* out_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_RSA_Encrypt; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_data_bytes; |
| rc = Parse_TPM2B_PUBLIC_KEY_RSA( |
| &buffer, |
| out_data, |
| &out_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PUBLIC_KEY_RSA( |
| &out_data_bytes, |
| out_data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void RSA_EncryptErrorCallback( |
| const Tpm::RSA_EncryptResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PUBLIC_KEY_RSA()); |
| } |
| |
| void RSA_EncryptResponseParser( |
| const Tpm::RSA_EncryptResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RSA_EncryptErrorCallback, callback); |
| TPM2B_PUBLIC_KEY_RSA out_data; |
| TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt( |
| response, |
| &out_data, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_data); |
| } |
| |
| void Tpm::RSA_Encrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& message, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| AuthorizationDelegate* authorization_delegate, |
| const RSA_EncryptResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RSA_EncryptErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(RSA_EncryptResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_RSA_Encrypt( |
| key_handle, |
| key_handle_name, |
| message, |
| in_scheme, |
| label, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::RSA_EncryptSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& message, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| TPM2B_PUBLIC_KEY_RSA* out_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_RSA_Encrypt( |
| key_handle, |
| key_handle_name, |
| message, |
| in_scheme, |
| label, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_RSA_Encrypt( |
| response, |
| out_data, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_RSA_Decrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& cipher_text, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_RSA_Decrypt; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string cipher_text_bytes; |
| rc = Serialize_TPM2B_PUBLIC_KEY_RSA( |
| cipher_text, |
| &cipher_text_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_RSA_DECRYPT( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string label_bytes; |
| rc = Serialize_TPM2B_DATA( |
| label, |
| &label_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = cipher_text_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| cipher_text_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(cipher_text_bytes.data(), |
| cipher_text_bytes.size()); |
| parameter_section_bytes += cipher_text_bytes; |
| command_size += cipher_text_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(label_bytes.data(), |
| label_bytes.size()); |
| parameter_section_bytes += label_bytes; |
| command_size += label_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_RSA_Decrypt( |
| const std::string& response, |
| TPM2B_PUBLIC_KEY_RSA* message, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_RSA_Decrypt; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string message_bytes; |
| rc = Parse_TPM2B_PUBLIC_KEY_RSA( |
| &buffer, |
| message, |
| &message_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = message_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| message_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PUBLIC_KEY_RSA( |
| &message_bytes, |
| message, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void RSA_DecryptErrorCallback( |
| const Tpm::RSA_DecryptResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_PUBLIC_KEY_RSA()); |
| } |
| |
| void RSA_DecryptResponseParser( |
| const Tpm::RSA_DecryptResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RSA_DecryptErrorCallback, callback); |
| TPM2B_PUBLIC_KEY_RSA message; |
| TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt( |
| response, |
| &message, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| message); |
| } |
| |
| void Tpm::RSA_Decrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& cipher_text, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| AuthorizationDelegate* authorization_delegate, |
| const RSA_DecryptResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(RSA_DecryptErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(RSA_DecryptResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_RSA_Decrypt( |
| key_handle, |
| key_handle_name, |
| cipher_text, |
| in_scheme, |
| label, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::RSA_DecryptSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_PUBLIC_KEY_RSA& cipher_text, |
| const TPMT_RSA_DECRYPT& in_scheme, |
| const TPM2B_DATA& label, |
| TPM2B_PUBLIC_KEY_RSA* message, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_RSA_Decrypt( |
| key_handle, |
| key_handle_name, |
| cipher_text, |
| in_scheme, |
| label, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_RSA_Decrypt( |
| response, |
| message, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ECDH_KeyGen( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ECDH_KeyGen; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ECDH_KeyGen( |
| const std::string& response, |
| TPM2B_ECC_POINT* z_point, |
| TPM2B_ECC_POINT* pub_point, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ECDH_KeyGen; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string z_point_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| z_point, |
| &z_point_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pub_point_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| pub_point, |
| &pub_point_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = z_point_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| z_point_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ECC_POINT( |
| &z_point_bytes, |
| z_point, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ECDH_KeyGenErrorCallback( |
| const Tpm::ECDH_KeyGenResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ECC_POINT(), |
| TPM2B_ECC_POINT()); |
| } |
| |
| void ECDH_KeyGenResponseParser( |
| const Tpm::ECDH_KeyGenResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECDH_KeyGenErrorCallback, callback); |
| TPM2B_ECC_POINT z_point; |
| TPM2B_ECC_POINT pub_point; |
| TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen( |
| response, |
| &z_point, |
| &pub_point, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| z_point, |
| pub_point); |
| } |
| |
| void Tpm::ECDH_KeyGen( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ECDH_KeyGenResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECDH_KeyGenErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ECDH_KeyGenResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECDH_KeyGen( |
| key_handle, |
| key_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ECDH_KeyGenSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| TPM2B_ECC_POINT* z_point, |
| TPM2B_ECC_POINT* pub_point, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECDH_KeyGen( |
| key_handle, |
| key_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ECDH_KeyGen( |
| response, |
| z_point, |
| pub_point, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ECDH_ZGen( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ECC_POINT& in_point, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ECDH_ZGen; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_point_bytes; |
| rc = Serialize_TPM2B_ECC_POINT( |
| in_point, |
| &in_point_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_point_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_point_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(in_point_bytes.data(), |
| in_point_bytes.size()); |
| parameter_section_bytes += in_point_bytes; |
| command_size += in_point_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ECDH_ZGen( |
| const std::string& response, |
| TPM2B_ECC_POINT* out_point, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ECDH_ZGen; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_point_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| out_point, |
| &out_point_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_point_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_point_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ECC_POINT( |
| &out_point_bytes, |
| out_point, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ECDH_ZGenErrorCallback( |
| const Tpm::ECDH_ZGenResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ECC_POINT()); |
| } |
| |
| void ECDH_ZGenResponseParser( |
| const Tpm::ECDH_ZGenResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECDH_ZGenErrorCallback, callback); |
| TPM2B_ECC_POINT out_point; |
| TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen( |
| response, |
| &out_point, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_point); |
| } |
| |
| void Tpm::ECDH_ZGen( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ECC_POINT& in_point, |
| AuthorizationDelegate* authorization_delegate, |
| const ECDH_ZGenResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECDH_ZGenErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ECDH_ZGenResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECDH_ZGen( |
| key_handle, |
| key_handle_name, |
| in_point, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ECDH_ZGenSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_ECC_POINT& in_point, |
| TPM2B_ECC_POINT* out_point, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECDH_ZGen( |
| key_handle, |
| key_handle_name, |
| in_point, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ECDH_ZGen( |
| response, |
| out_point, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ECC_Parameters( |
| const TPMI_ECC_CURVE& curve_id, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ECC_Parameters; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string curve_id_bytes; |
| rc = Serialize_TPMI_ECC_CURVE( |
| curve_id, |
| &curve_id_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(curve_id_bytes.data(), |
| curve_id_bytes.size()); |
| parameter_section_bytes += curve_id_bytes; |
| command_size += curve_id_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ECC_Parameters( |
| const std::string& response, |
| TPMS_ALGORITHM_DETAIL_ECC* parameters, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ECC_Parameters; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string parameters_bytes; |
| rc = Parse_TPMS_ALGORITHM_DETAIL_ECC( |
| &buffer, |
| parameters, |
| ¶meters_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ECC_ParametersErrorCallback( |
| const Tpm::ECC_ParametersResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMS_ALGORITHM_DETAIL_ECC()); |
| } |
| |
| void ECC_ParametersResponseParser( |
| const Tpm::ECC_ParametersResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECC_ParametersErrorCallback, callback); |
| TPMS_ALGORITHM_DETAIL_ECC parameters; |
| TPM_RC rc = Tpm::ParseResponse_ECC_Parameters( |
| response, |
| ¶meters, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| parameters); |
| } |
| |
| void Tpm::ECC_Parameters( |
| const TPMI_ECC_CURVE& curve_id, |
| AuthorizationDelegate* authorization_delegate, |
| const ECC_ParametersResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ECC_ParametersErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ECC_ParametersResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECC_Parameters( |
| curve_id, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ECC_ParametersSync( |
| const TPMI_ECC_CURVE& curve_id, |
| TPMS_ALGORITHM_DETAIL_ECC* parameters, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ECC_Parameters( |
| curve_id, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ECC_Parameters( |
| response, |
| parameters, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ZGen_2Phase( |
| const TPMI_DH_OBJECT& key_a, |
| const std::string& key_a_name, |
| const TPM2B_ECC_POINT& in_qs_b, |
| const TPM2B_ECC_POINT& in_qe_b, |
| const TPMI_ECC_KEY_EXCHANGE& in_scheme, |
| const UINT16& counter, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ZGen_2Phase; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_a_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_a, |
| &key_a_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_qs_b_bytes; |
| rc = Serialize_TPM2B_ECC_POINT( |
| in_qs_b, |
| &in_qs_b_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_qe_b_bytes; |
| rc = Serialize_TPM2B_ECC_POINT( |
| in_qe_b, |
| &in_qe_b_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMI_ECC_KEY_EXCHANGE( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string counter_bytes; |
| rc = Serialize_UINT16( |
| counter, |
| &counter_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_qs_b_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_qs_b_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_a_name.data(), |
| key_a_name.size()); |
| handle_section_bytes += key_a_bytes; |
| command_size += key_a_bytes.size(); |
| hash->Update(in_qs_b_bytes.data(), |
| in_qs_b_bytes.size()); |
| parameter_section_bytes += in_qs_b_bytes; |
| command_size += in_qs_b_bytes.size(); |
| hash->Update(in_qe_b_bytes.data(), |
| in_qe_b_bytes.size()); |
| parameter_section_bytes += in_qe_b_bytes; |
| command_size += in_qe_b_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(counter_bytes.data(), |
| counter_bytes.size()); |
| parameter_section_bytes += counter_bytes; |
| command_size += counter_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ZGen_2Phase( |
| const std::string& response, |
| TPM2B_ECC_POINT* out_z1, |
| TPM2B_ECC_POINT* out_z2, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ZGen_2Phase; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_z1_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| out_z1, |
| &out_z1_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string out_z2_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| out_z2, |
| &out_z2_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_z1_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_z1_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ECC_POINT( |
| &out_z1_bytes, |
| out_z1, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ZGen_2PhaseErrorCallback( |
| const Tpm::ZGen_2PhaseResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ECC_POINT(), |
| TPM2B_ECC_POINT()); |
| } |
| |
| void ZGen_2PhaseResponseParser( |
| const Tpm::ZGen_2PhaseResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ZGen_2PhaseErrorCallback, callback); |
| TPM2B_ECC_POINT out_z1; |
| TPM2B_ECC_POINT out_z2; |
| TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase( |
| response, |
| &out_z1, |
| &out_z2, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_z1, |
| out_z2); |
| } |
| |
| void Tpm::ZGen_2Phase( |
| const TPMI_DH_OBJECT& key_a, |
| const std::string& key_a_name, |
| const TPM2B_ECC_POINT& in_qs_b, |
| const TPM2B_ECC_POINT& in_qe_b, |
| const TPMI_ECC_KEY_EXCHANGE& in_scheme, |
| const UINT16& counter, |
| AuthorizationDelegate* authorization_delegate, |
| const ZGen_2PhaseResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ZGen_2PhaseErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ZGen_2PhaseResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ZGen_2Phase( |
| key_a, |
| key_a_name, |
| in_qs_b, |
| in_qe_b, |
| in_scheme, |
| counter, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ZGen_2PhaseSync( |
| const TPMI_DH_OBJECT& key_a, |
| const std::string& key_a_name, |
| const TPM2B_ECC_POINT& in_qs_b, |
| const TPM2B_ECC_POINT& in_qe_b, |
| const TPMI_ECC_KEY_EXCHANGE& in_scheme, |
| const UINT16& counter, |
| TPM2B_ECC_POINT* out_z1, |
| TPM2B_ECC_POINT* out_z2, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ZGen_2Phase( |
| key_a, |
| key_a_name, |
| in_qs_b, |
| in_qe_b, |
| in_scheme, |
| counter, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ZGen_2Phase( |
| response, |
| out_z1, |
| out_z2, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_EncryptDecrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPMI_YES_NO& decrypt, |
| const TPMI_ALG_SYM_MODE& mode, |
| const TPM2B_IV& iv_in, |
| const TPM2B_MAX_BUFFER& in_data, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_EncryptDecrypt; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string decrypt_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| decrypt, |
| &decrypt_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string mode_bytes; |
| rc = Serialize_TPMI_ALG_SYM_MODE( |
| mode, |
| &mode_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string iv_in_bytes; |
| rc = Serialize_TPM2B_IV( |
| iv_in, |
| &iv_in_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_data_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| in_data, |
| &in_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(decrypt_bytes.data(), |
| decrypt_bytes.size()); |
| parameter_section_bytes += decrypt_bytes; |
| command_size += decrypt_bytes.size(); |
| hash->Update(mode_bytes.data(), |
| mode_bytes.size()); |
| parameter_section_bytes += mode_bytes; |
| command_size += mode_bytes.size(); |
| hash->Update(iv_in_bytes.data(), |
| iv_in_bytes.size()); |
| parameter_section_bytes += iv_in_bytes; |
| command_size += iv_in_bytes.size(); |
| hash->Update(in_data_bytes.data(), |
| in_data_bytes.size()); |
| parameter_section_bytes += in_data_bytes; |
| command_size += in_data_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_EncryptDecrypt( |
| const std::string& response, |
| TPM2B_MAX_BUFFER* out_data, |
| TPM2B_IV* iv_out, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_EncryptDecrypt; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_data_bytes; |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &buffer, |
| out_data, |
| &out_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string iv_out_bytes; |
| rc = Parse_TPM2B_IV( |
| &buffer, |
| iv_out, |
| &iv_out_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &out_data_bytes, |
| out_data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void EncryptDecryptErrorCallback( |
| const Tpm::EncryptDecryptResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_MAX_BUFFER(), |
| TPM2B_IV()); |
| } |
| |
| void EncryptDecryptResponseParser( |
| const Tpm::EncryptDecryptResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EncryptDecryptErrorCallback, callback); |
| TPM2B_MAX_BUFFER out_data; |
| TPM2B_IV iv_out; |
| TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt( |
| response, |
| &out_data, |
| &iv_out, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_data, |
| iv_out); |
| } |
| |
| void Tpm::EncryptDecrypt( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPMI_YES_NO& decrypt, |
| const TPMI_ALG_SYM_MODE& mode, |
| const TPM2B_IV& iv_in, |
| const TPM2B_MAX_BUFFER& in_data, |
| AuthorizationDelegate* authorization_delegate, |
| const EncryptDecryptResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EncryptDecryptErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(EncryptDecryptResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_EncryptDecrypt( |
| key_handle, |
| key_handle_name, |
| decrypt, |
| mode, |
| iv_in, |
| in_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::EncryptDecryptSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPMI_YES_NO& decrypt, |
| const TPMI_ALG_SYM_MODE& mode, |
| const TPM2B_IV& iv_in, |
| const TPM2B_MAX_BUFFER& in_data, |
| TPM2B_MAX_BUFFER* out_data, |
| TPM2B_IV* iv_out, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_EncryptDecrypt( |
| key_handle, |
| key_handle_name, |
| decrypt, |
| mode, |
| iv_in, |
| in_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_EncryptDecrypt( |
| response, |
| out_data, |
| iv_out, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Hash( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& data, |
| const TPMI_ALG_HASH& hash_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Hash; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string data_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| data, |
| &data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hash_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| hash_alg, |
| &hash_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hierarchy_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| hierarchy, |
| &hierarchy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(hierarchy_name.data(), |
| hierarchy_name.size()); |
| handle_section_bytes += hierarchy_bytes; |
| command_size += hierarchy_bytes.size(); |
| hash->Update(data_bytes.data(), |
| data_bytes.size()); |
| parameter_section_bytes += data_bytes; |
| command_size += data_bytes.size(); |
| hash->Update(hash_alg_bytes.data(), |
| hash_alg_bytes.size()); |
| parameter_section_bytes += hash_alg_bytes; |
| command_size += hash_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Hash( |
| const std::string& response, |
| TPM2B_DIGEST* out_hash, |
| TPMT_TK_HASHCHECK* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Hash; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_hash_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| out_hash, |
| &out_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string validation_bytes; |
| rc = Parse_TPMT_TK_HASHCHECK( |
| &buffer, |
| validation, |
| &validation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_hash_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_hash_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &out_hash_bytes, |
| out_hash, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HashErrorCallback( |
| const Tpm::HashResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST(), |
| TPMT_TK_HASHCHECK()); |
| } |
| |
| void HashResponseParser( |
| const Tpm::HashResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HashErrorCallback, callback); |
| TPM2B_DIGEST out_hash; |
| TPMT_TK_HASHCHECK validation; |
| TPM_RC rc = Tpm::ParseResponse_Hash( |
| response, |
| &out_hash, |
| &validation, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_hash, |
| validation); |
| } |
| |
| void Tpm::Hash( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& data, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const HashResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HashErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HashResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Hash( |
| hierarchy, |
| hierarchy_name, |
| data, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HashSync( |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& data, |
| const TPMI_ALG_HASH& hash_alg, |
| TPM2B_DIGEST* out_hash, |
| TPMT_TK_HASHCHECK* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Hash( |
| hierarchy, |
| hierarchy_name, |
| data, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Hash( |
| response, |
| out_hash, |
| validation, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_HMAC( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| const TPMI_ALG_HASH& hash_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_HMAC; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| handle, |
| &handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string buffer_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| buffer, |
| &buffer_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hash_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| hash_alg, |
| &hash_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = buffer_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| buffer_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(handle_name.data(), |
| handle_name.size()); |
| handle_section_bytes += handle_bytes; |
| command_size += handle_bytes.size(); |
| hash->Update(buffer_bytes.data(), |
| buffer_bytes.size()); |
| parameter_section_bytes += buffer_bytes; |
| command_size += buffer_bytes.size(); |
| hash->Update(hash_alg_bytes.data(), |
| hash_alg_bytes.size()); |
| parameter_section_bytes += hash_alg_bytes; |
| command_size += hash_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_HMAC( |
| const std::string& response, |
| TPM2B_DIGEST* out_hmac, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_HMAC; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_hmac_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| out_hmac, |
| &out_hmac_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_hmac_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_hmac_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &out_hmac_bytes, |
| out_hmac, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HMACErrorCallback( |
| const Tpm::HMACResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST()); |
| } |
| |
| void HMACResponseParser( |
| const Tpm::HMACResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HMACErrorCallback, callback); |
| TPM2B_DIGEST out_hmac; |
| TPM_RC rc = Tpm::ParseResponse_HMAC( |
| response, |
| &out_hmac, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| out_hmac); |
| } |
| |
| void Tpm::HMAC( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const HMACResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HMACErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HMACResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_HMAC( |
| handle, |
| handle_name, |
| buffer, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HMACSync( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| const TPMI_ALG_HASH& hash_alg, |
| TPM2B_DIGEST* out_hmac, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_HMAC( |
| handle, |
| handle_name, |
| buffer, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_HMAC( |
| response, |
| out_hmac, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetRandom( |
| const UINT16& bytes_requested, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetRandom; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string bytes_requested_bytes; |
| rc = Serialize_UINT16( |
| bytes_requested, |
| &bytes_requested_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(bytes_requested_bytes.data(), |
| bytes_requested_bytes.size()); |
| parameter_section_bytes += bytes_requested_bytes; |
| command_size += bytes_requested_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetRandom( |
| const std::string& response, |
| TPM2B_DIGEST* random_bytes, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetRandom; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string random_bytes_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| random_bytes, |
| &random_bytes_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = random_bytes_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| random_bytes_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &random_bytes_bytes, |
| random_bytes, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetRandomErrorCallback( |
| const Tpm::GetRandomResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST()); |
| } |
| |
| void GetRandomResponseParser( |
| const Tpm::GetRandomResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetRandomErrorCallback, callback); |
| TPM2B_DIGEST random_bytes; |
| TPM_RC rc = Tpm::ParseResponse_GetRandom( |
| response, |
| &random_bytes, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| random_bytes); |
| } |
| |
| void Tpm::GetRandom( |
| const UINT16& bytes_requested, |
| AuthorizationDelegate* authorization_delegate, |
| const GetRandomResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetRandomErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetRandomResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetRandom( |
| bytes_requested, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetRandomSync( |
| const UINT16& bytes_requested, |
| TPM2B_DIGEST* random_bytes, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetRandom( |
| bytes_requested, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetRandom( |
| response, |
| random_bytes, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_StirRandom( |
| const TPM2B_SENSITIVE_DATA& in_data, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_StirRandom; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_data_bytes; |
| rc = Serialize_TPM2B_SENSITIVE_DATA( |
| in_data, |
| &in_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(in_data_bytes.data(), |
| in_data_bytes.size()); |
| parameter_section_bytes += in_data_bytes; |
| command_size += in_data_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_StirRandom( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_StirRandom; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void StirRandomErrorCallback( |
| const Tpm::StirRandomResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void StirRandomResponseParser( |
| const Tpm::StirRandomResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StirRandomErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_StirRandom( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::StirRandom( |
| const TPM2B_SENSITIVE_DATA& in_data, |
| AuthorizationDelegate* authorization_delegate, |
| const StirRandomResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(StirRandomErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(StirRandomResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_StirRandom( |
| in_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::StirRandomSync( |
| const TPM2B_SENSITIVE_DATA& in_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_StirRandom( |
| in_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_StirRandom( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_HMAC_Start( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_HMAC_Start; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| handle, |
| &handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hash_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| hash_alg, |
| &hash_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(handle_name.data(), |
| handle_name.size()); |
| handle_section_bytes += handle_bytes; |
| command_size += handle_bytes.size(); |
| hash->Update(auth_bytes.data(), |
| auth_bytes.size()); |
| parameter_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(hash_alg_bytes.data(), |
| hash_alg_bytes.size()); |
| parameter_section_bytes += hash_alg_bytes; |
| command_size += hash_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_HMAC_Start( |
| const std::string& response, |
| TPMI_DH_OBJECT* sequence_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string sequence_handle_bytes; |
| rc = Parse_TPMI_DH_OBJECT( |
| &buffer, |
| sequence_handle, |
| &sequence_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_HMAC_Start; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HMAC_StartErrorCallback( |
| const Tpm::HMAC_StartResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_DH_OBJECT()); |
| } |
| |
| void HMAC_StartResponseParser( |
| const Tpm::HMAC_StartResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HMAC_StartErrorCallback, callback); |
| TPMI_DH_OBJECT sequence_handle; |
| TPM_RC rc = Tpm::ParseResponse_HMAC_Start( |
| response, |
| &sequence_handle, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| sequence_handle); |
| } |
| |
| void Tpm::HMAC_Start( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const HMAC_StartResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HMAC_StartErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HMAC_StartResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_HMAC_Start( |
| handle, |
| handle_name, |
| auth, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HMAC_StartSync( |
| const TPMI_DH_OBJECT& handle, |
| const std::string& handle_name, |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| TPMI_DH_OBJECT* sequence_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_HMAC_Start( |
| handle, |
| handle_name, |
| auth, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_HMAC_Start( |
| response, |
| sequence_handle, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_HashSequenceStart( |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_HashSequenceStart; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hash_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| hash_alg, |
| &hash_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_bytes.data(), |
| auth_bytes.size()); |
| parameter_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(hash_alg_bytes.data(), |
| hash_alg_bytes.size()); |
| parameter_section_bytes += hash_alg_bytes; |
| command_size += hash_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_HashSequenceStart( |
| const std::string& response, |
| TPMI_DH_OBJECT* sequence_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string sequence_handle_bytes; |
| rc = Parse_TPMI_DH_OBJECT( |
| &buffer, |
| sequence_handle, |
| &sequence_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_HashSequenceStart; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HashSequenceStartErrorCallback( |
| const Tpm::HashSequenceStartResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_DH_OBJECT()); |
| } |
| |
| void HashSequenceStartResponseParser( |
| const Tpm::HashSequenceStartResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HashSequenceStartErrorCallback, callback); |
| TPMI_DH_OBJECT sequence_handle; |
| TPM_RC rc = Tpm::ParseResponse_HashSequenceStart( |
| response, |
| &sequence_handle, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| sequence_handle); |
| } |
| |
| void Tpm::HashSequenceStart( |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const HashSequenceStartResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HashSequenceStartErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HashSequenceStartResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_HashSequenceStart( |
| auth, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HashSequenceStartSync( |
| const TPM2B_AUTH& auth, |
| const TPMI_ALG_HASH& hash_alg, |
| TPMI_DH_OBJECT* sequence_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_HashSequenceStart( |
| auth, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_HashSequenceStart( |
| response, |
| sequence_handle, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SequenceUpdate( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SequenceUpdate; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sequence_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sequence_handle, |
| &sequence_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string buffer_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| buffer, |
| &buffer_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = buffer_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| buffer_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sequence_handle_name.data(), |
| sequence_handle_name.size()); |
| handle_section_bytes += sequence_handle_bytes; |
| command_size += sequence_handle_bytes.size(); |
| hash->Update(buffer_bytes.data(), |
| buffer_bytes.size()); |
| parameter_section_bytes += buffer_bytes; |
| command_size += buffer_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SequenceUpdate( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SequenceUpdate; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SequenceUpdateErrorCallback( |
| const Tpm::SequenceUpdateResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void SequenceUpdateResponseParser( |
| const Tpm::SequenceUpdateResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SequenceUpdateErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_SequenceUpdate( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::SequenceUpdate( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| AuthorizationDelegate* authorization_delegate, |
| const SequenceUpdateResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SequenceUpdateErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SequenceUpdateResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SequenceUpdate( |
| sequence_handle, |
| sequence_handle_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SequenceUpdateSync( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SequenceUpdate( |
| sequence_handle, |
| sequence_handle_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SequenceUpdate( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SequenceComplete( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SequenceComplete; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sequence_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sequence_handle, |
| &sequence_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string buffer_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| buffer, |
| &buffer_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hierarchy_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| hierarchy, |
| &hierarchy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = buffer_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| buffer_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sequence_handle_name.data(), |
| sequence_handle_name.size()); |
| handle_section_bytes += sequence_handle_bytes; |
| command_size += sequence_handle_bytes.size(); |
| hash->Update(hierarchy_name.data(), |
| hierarchy_name.size()); |
| handle_section_bytes += hierarchy_bytes; |
| command_size += hierarchy_bytes.size(); |
| hash->Update(buffer_bytes.data(), |
| buffer_bytes.size()); |
| parameter_section_bytes += buffer_bytes; |
| command_size += buffer_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SequenceComplete( |
| const std::string& response, |
| TPM2B_DIGEST* result, |
| TPMT_TK_HASHCHECK* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SequenceComplete; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string result_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| result, |
| &result_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string validation_bytes; |
| rc = Parse_TPMT_TK_HASHCHECK( |
| &buffer, |
| validation, |
| &validation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = result_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| result_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &result_bytes, |
| result, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SequenceCompleteErrorCallback( |
| const Tpm::SequenceCompleteResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST(), |
| TPMT_TK_HASHCHECK()); |
| } |
| |
| void SequenceCompleteResponseParser( |
| const Tpm::SequenceCompleteResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SequenceCompleteErrorCallback, callback); |
| TPM2B_DIGEST result; |
| TPMT_TK_HASHCHECK validation; |
| TPM_RC rc = Tpm::ParseResponse_SequenceComplete( |
| response, |
| &result, |
| &validation, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| result, |
| validation); |
| } |
| |
| void Tpm::SequenceComplete( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| AuthorizationDelegate* authorization_delegate, |
| const SequenceCompleteResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SequenceCompleteErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SequenceCompleteResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SequenceComplete( |
| sequence_handle, |
| sequence_handle_name, |
| hierarchy, |
| hierarchy_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SequenceCompleteSync( |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPMI_RH_HIERARCHY& hierarchy, |
| const std::string& hierarchy_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| TPM2B_DIGEST* result, |
| TPMT_TK_HASHCHECK* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SequenceComplete( |
| sequence_handle, |
| sequence_handle_name, |
| hierarchy, |
| hierarchy_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SequenceComplete( |
| response, |
| result, |
| validation, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_EventSequenceComplete( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_EventSequenceComplete; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_handle_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_handle, |
| &pcr_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sequence_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sequence_handle, |
| &sequence_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string buffer_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| buffer, |
| &buffer_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = buffer_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| buffer_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_handle_name.data(), |
| pcr_handle_name.size()); |
| handle_section_bytes += pcr_handle_bytes; |
| command_size += pcr_handle_bytes.size(); |
| hash->Update(sequence_handle_name.data(), |
| sequence_handle_name.size()); |
| handle_section_bytes += sequence_handle_bytes; |
| command_size += sequence_handle_bytes.size(); |
| hash->Update(buffer_bytes.data(), |
| buffer_bytes.size()); |
| parameter_section_bytes += buffer_bytes; |
| command_size += buffer_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_EventSequenceComplete( |
| const std::string& response, |
| TPML_DIGEST_VALUES* results, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_EventSequenceComplete; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string results_bytes; |
| rc = Parse_TPML_DIGEST_VALUES( |
| &buffer, |
| results, |
| &results_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void EventSequenceCompleteErrorCallback( |
| const Tpm::EventSequenceCompleteResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPML_DIGEST_VALUES()); |
| } |
| |
| void EventSequenceCompleteResponseParser( |
| const Tpm::EventSequenceCompleteResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EventSequenceCompleteErrorCallback, callback); |
| TPML_DIGEST_VALUES results; |
| TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete( |
| response, |
| &results, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| results); |
| } |
| |
| void Tpm::EventSequenceComplete( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| AuthorizationDelegate* authorization_delegate, |
| const EventSequenceCompleteResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EventSequenceCompleteErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(EventSequenceCompleteResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_EventSequenceComplete( |
| pcr_handle, |
| pcr_handle_name, |
| sequence_handle, |
| sequence_handle_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::EventSequenceCompleteSync( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPMI_DH_OBJECT& sequence_handle, |
| const std::string& sequence_handle_name, |
| const TPM2B_MAX_BUFFER& buffer, |
| TPML_DIGEST_VALUES* results, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_EventSequenceComplete( |
| pcr_handle, |
| pcr_handle_name, |
| sequence_handle, |
| sequence_handle_name, |
| buffer, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_EventSequenceComplete( |
| response, |
| results, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Certify( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Certify; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Certify( |
| const std::string& response, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Certify; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string certify_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| certify_info, |
| &certify_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = certify_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| certify_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &certify_info_bytes, |
| certify_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void CertifyErrorCallback( |
| const Tpm::CertifyResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void CertifyResponseParser( |
| const Tpm::CertifyResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CertifyErrorCallback, callback); |
| TPM2B_ATTEST certify_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_Certify( |
| response, |
| &certify_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| certify_info, |
| signature); |
| } |
| |
| void Tpm::Certify( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| AuthorizationDelegate* authorization_delegate, |
| const CertifyResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CertifyErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(CertifyResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Certify( |
| object_handle, |
| object_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::CertifySync( |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Certify( |
| object_handle, |
| object_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Certify( |
| response, |
| certify_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_CertifyCreation( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPM2B_DIGEST& creation_hash, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_CREATION& creation_ticket, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_CertifyCreation; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_hash_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| creation_hash, |
| &creation_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_ticket_bytes; |
| rc = Serialize_TPMT_TK_CREATION( |
| creation_ticket, |
| &creation_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(creation_hash_bytes.data(), |
| creation_hash_bytes.size()); |
| parameter_section_bytes += creation_hash_bytes; |
| command_size += creation_hash_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(creation_ticket_bytes.data(), |
| creation_ticket_bytes.size()); |
| parameter_section_bytes += creation_ticket_bytes; |
| command_size += creation_ticket_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_CertifyCreation( |
| const std::string& response, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_CertifyCreation; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string certify_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| certify_info, |
| &certify_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = certify_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| certify_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &certify_info_bytes, |
| certify_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void CertifyCreationErrorCallback( |
| const Tpm::CertifyCreationResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void CertifyCreationResponseParser( |
| const Tpm::CertifyCreationResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CertifyCreationErrorCallback, callback); |
| TPM2B_ATTEST certify_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_CertifyCreation( |
| response, |
| &certify_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| certify_info, |
| signature); |
| } |
| |
| void Tpm::CertifyCreation( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPM2B_DIGEST& creation_hash, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_CREATION& creation_ticket, |
| AuthorizationDelegate* authorization_delegate, |
| const CertifyCreationResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CertifyCreationErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(CertifyCreationResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_CertifyCreation( |
| sign_handle, |
| sign_handle_name, |
| object_handle, |
| object_handle_name, |
| qualifying_data, |
| creation_hash, |
| in_scheme, |
| creation_ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::CertifyCreationSync( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPM2B_DIGEST& creation_hash, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_CREATION& creation_ticket, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_CertifyCreation( |
| sign_handle, |
| sign_handle_name, |
| object_handle, |
| object_handle_name, |
| qualifying_data, |
| creation_hash, |
| in_scheme, |
| creation_ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_CertifyCreation( |
| response, |
| certify_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Quote( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPML_PCR_SELECTION& pcrselect, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Quote; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcrselect_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| pcrselect, |
| &pcrselect_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(pcrselect_bytes.data(), |
| pcrselect_bytes.size()); |
| parameter_section_bytes += pcrselect_bytes; |
| command_size += pcrselect_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Quote( |
| const std::string& response, |
| TPM2B_ATTEST* quoted, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Quote; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string quoted_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| quoted, |
| "ed_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = quoted_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| quoted_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| "ed_bytes, |
| quoted, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void QuoteErrorCallback( |
| const Tpm::QuoteResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void QuoteResponseParser( |
| const Tpm::QuoteResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(QuoteErrorCallback, callback); |
| TPM2B_ATTEST quoted; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_Quote( |
| response, |
| "ed, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| quoted, |
| signature); |
| } |
| |
| void Tpm::Quote( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPML_PCR_SELECTION& pcrselect, |
| AuthorizationDelegate* authorization_delegate, |
| const QuoteResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(QuoteErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(QuoteResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Quote( |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| pcrselect, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::QuoteSync( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPML_PCR_SELECTION& pcrselect, |
| TPM2B_ATTEST* quoted, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Quote( |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| pcrselect, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Quote( |
| response, |
| quoted, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_SH_HMAC& session_handle, |
| const std::string& session_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetSessionAuditDigest; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string privacy_admin_handle_bytes; |
| rc = Serialize_TPMI_RH_ENDORSEMENT( |
| privacy_admin_handle, |
| &privacy_admin_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string session_handle_bytes; |
| rc = Serialize_TPMI_SH_HMAC( |
| session_handle, |
| &session_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(privacy_admin_handle_name.data(), |
| privacy_admin_handle_name.size()); |
| handle_section_bytes += privacy_admin_handle_bytes; |
| command_size += privacy_admin_handle_bytes.size(); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(session_handle_name.data(), |
| session_handle_name.size()); |
| handle_section_bytes += session_handle_bytes; |
| command_size += session_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetSessionAuditDigest( |
| const std::string& response, |
| TPM2B_ATTEST* audit_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetSessionAuditDigest; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string audit_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| audit_info, |
| &audit_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = audit_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| audit_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &audit_info_bytes, |
| audit_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetSessionAuditDigestErrorCallback( |
| const Tpm::GetSessionAuditDigestResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void GetSessionAuditDigestResponseParser( |
| const Tpm::GetSessionAuditDigestResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetSessionAuditDigestErrorCallback, callback); |
| TPM2B_ATTEST audit_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest( |
| response, |
| &audit_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| audit_info, |
| signature); |
| } |
| |
| void Tpm::GetSessionAuditDigest( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_SH_HMAC& session_handle, |
| const std::string& session_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| AuthorizationDelegate* authorization_delegate, |
| const GetSessionAuditDigestResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetSessionAuditDigestErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetSessionAuditDigestResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetSessionAuditDigest( |
| privacy_admin_handle, |
| privacy_admin_handle_name, |
| sign_handle, |
| sign_handle_name, |
| session_handle, |
| session_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetSessionAuditDigestSync( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_SH_HMAC& session_handle, |
| const std::string& session_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| TPM2B_ATTEST* audit_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetSessionAuditDigest( |
| privacy_admin_handle, |
| privacy_admin_handle_name, |
| sign_handle, |
| sign_handle_name, |
| session_handle, |
| session_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetSessionAuditDigest( |
| response, |
| audit_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest( |
| const TPMI_RH_ENDORSEMENT& privacy_handle, |
| const std::string& privacy_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetCommandAuditDigest; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string privacy_handle_bytes; |
| rc = Serialize_TPMI_RH_ENDORSEMENT( |
| privacy_handle, |
| &privacy_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(privacy_handle_name.data(), |
| privacy_handle_name.size()); |
| handle_section_bytes += privacy_handle_bytes; |
| command_size += privacy_handle_bytes.size(); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetCommandAuditDigest( |
| const std::string& response, |
| TPM2B_ATTEST* audit_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetCommandAuditDigest; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string audit_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| audit_info, |
| &audit_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = audit_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| audit_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &audit_info_bytes, |
| audit_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetCommandAuditDigestErrorCallback( |
| const Tpm::GetCommandAuditDigestResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void GetCommandAuditDigestResponseParser( |
| const Tpm::GetCommandAuditDigestResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetCommandAuditDigestErrorCallback, callback); |
| TPM2B_ATTEST audit_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest( |
| response, |
| &audit_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| audit_info, |
| signature); |
| } |
| |
| void Tpm::GetCommandAuditDigest( |
| const TPMI_RH_ENDORSEMENT& privacy_handle, |
| const std::string& privacy_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| AuthorizationDelegate* authorization_delegate, |
| const GetCommandAuditDigestResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetCommandAuditDigestErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetCommandAuditDigestResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetCommandAuditDigest( |
| privacy_handle, |
| privacy_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetCommandAuditDigestSync( |
| const TPMI_RH_ENDORSEMENT& privacy_handle, |
| const std::string& privacy_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| TPM2B_ATTEST* audit_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetCommandAuditDigest( |
| privacy_handle, |
| privacy_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetCommandAuditDigest( |
| response, |
| audit_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetTime( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetTime; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string privacy_admin_handle_bytes; |
| rc = Serialize_TPMI_RH_ENDORSEMENT( |
| privacy_admin_handle, |
| &privacy_admin_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(privacy_admin_handle_name.data(), |
| privacy_admin_handle_name.size()); |
| handle_section_bytes += privacy_admin_handle_bytes; |
| command_size += privacy_admin_handle_bytes.size(); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetTime( |
| const std::string& response, |
| TPM2B_ATTEST* time_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetTime; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string time_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| time_info, |
| &time_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = time_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| time_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &time_info_bytes, |
| time_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetTimeErrorCallback( |
| const Tpm::GetTimeResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void GetTimeResponseParser( |
| const Tpm::GetTimeResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetTimeErrorCallback, callback); |
| TPM2B_ATTEST time_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_GetTime( |
| response, |
| &time_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| time_info, |
| signature); |
| } |
| |
| void Tpm::GetTime( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| AuthorizationDelegate* authorization_delegate, |
| const GetTimeResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetTimeErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetTimeResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetTime( |
| privacy_admin_handle, |
| privacy_admin_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetTimeSync( |
| const TPMI_RH_ENDORSEMENT& privacy_admin_handle, |
| const std::string& privacy_admin_handle_name, |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| TPM2B_ATTEST* time_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetTime( |
| privacy_admin_handle, |
| privacy_admin_handle_name, |
| sign_handle, |
| sign_handle_name, |
| qualifying_data, |
| in_scheme, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetTime( |
| response, |
| time_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Commit( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const UINT32& param_size, |
| const TPM2B_ECC_POINT& p1, |
| const TPM2B_SENSITIVE_DATA& s2, |
| const TPM2B_ECC_PARAMETER& y2, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Commit; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string param_size_bytes; |
| rc = Serialize_UINT32( |
| param_size, |
| ¶m_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string p1_bytes; |
| rc = Serialize_TPM2B_ECC_POINT( |
| p1, |
| &p1_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string s2_bytes; |
| rc = Serialize_TPM2B_SENSITIVE_DATA( |
| s2, |
| &s2_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string y2_bytes; |
| rc = Serialize_TPM2B_ECC_PARAMETER( |
| y2, |
| &y2_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(param_size_bytes.data(), |
| param_size_bytes.size()); |
| parameter_section_bytes += param_size_bytes; |
| command_size += param_size_bytes.size(); |
| hash->Update(p1_bytes.data(), |
| p1_bytes.size()); |
| parameter_section_bytes += p1_bytes; |
| command_size += p1_bytes.size(); |
| hash->Update(s2_bytes.data(), |
| s2_bytes.size()); |
| parameter_section_bytes += s2_bytes; |
| command_size += s2_bytes.size(); |
| hash->Update(y2_bytes.data(), |
| y2_bytes.size()); |
| parameter_section_bytes += y2_bytes; |
| command_size += y2_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Commit( |
| const std::string& response, |
| UINT32* param_size_out, |
| TPM2B_ECC_POINT* k, |
| TPM2B_ECC_POINT* l, |
| TPM2B_ECC_POINT* e, |
| UINT16* counter, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Commit; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string param_size_out_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| param_size_out, |
| ¶m_size_out_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string k_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| k, |
| &k_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string l_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| l, |
| &l_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string e_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| e, |
| &e_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string counter_bytes; |
| rc = Parse_UINT16( |
| &buffer, |
| counter, |
| &counter_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void CommitErrorCallback( |
| const Tpm::CommitResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| UINT32(), |
| TPM2B_ECC_POINT(), |
| TPM2B_ECC_POINT(), |
| TPM2B_ECC_POINT(), |
| UINT16()); |
| } |
| |
| void CommitResponseParser( |
| const Tpm::CommitResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CommitErrorCallback, callback); |
| UINT32 param_size_out; |
| TPM2B_ECC_POINT k; |
| TPM2B_ECC_POINT l; |
| TPM2B_ECC_POINT e; |
| UINT16 counter; |
| TPM_RC rc = Tpm::ParseResponse_Commit( |
| response, |
| ¶m_size_out, |
| &k, |
| &l, |
| &e, |
| &counter, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| param_size_out, |
| k, |
| l, |
| e, |
| counter); |
| } |
| |
| void Tpm::Commit( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const UINT32& param_size, |
| const TPM2B_ECC_POINT& p1, |
| const TPM2B_SENSITIVE_DATA& s2, |
| const TPM2B_ECC_PARAMETER& y2, |
| AuthorizationDelegate* authorization_delegate, |
| const CommitResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CommitErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(CommitResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Commit( |
| sign_handle, |
| sign_handle_name, |
| param_size, |
| p1, |
| s2, |
| y2, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::CommitSync( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const UINT32& param_size, |
| const TPM2B_ECC_POINT& p1, |
| const TPM2B_SENSITIVE_DATA& s2, |
| const TPM2B_ECC_PARAMETER& y2, |
| UINT32* param_size_out, |
| TPM2B_ECC_POINT* k, |
| TPM2B_ECC_POINT* l, |
| TPM2B_ECC_POINT* e, |
| UINT16* counter, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Commit( |
| sign_handle, |
| sign_handle_name, |
| param_size, |
| p1, |
| s2, |
| y2, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Commit( |
| response, |
| param_size_out, |
| k, |
| l, |
| e, |
| counter, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_EC_Ephemeral( |
| const UINT32& param_size, |
| const TPMI_ECC_CURVE& curve_id, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_EC_Ephemeral; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string param_size_bytes; |
| rc = Serialize_UINT32( |
| param_size, |
| ¶m_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string curve_id_bytes; |
| rc = Serialize_TPMI_ECC_CURVE( |
| curve_id, |
| &curve_id_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(param_size_bytes.data(), |
| param_size_bytes.size()); |
| parameter_section_bytes += param_size_bytes; |
| command_size += param_size_bytes.size(); |
| hash->Update(curve_id_bytes.data(), |
| curve_id_bytes.size()); |
| parameter_section_bytes += curve_id_bytes; |
| command_size += curve_id_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_EC_Ephemeral( |
| const std::string& response, |
| UINT32* param_size_out, |
| TPM2B_ECC_POINT* q, |
| UINT16* counter, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_EC_Ephemeral; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string param_size_out_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| param_size_out, |
| ¶m_size_out_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string q_bytes; |
| rc = Parse_TPM2B_ECC_POINT( |
| &buffer, |
| q, |
| &q_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string counter_bytes; |
| rc = Parse_UINT16( |
| &buffer, |
| counter, |
| &counter_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void EC_EphemeralErrorCallback( |
| const Tpm::EC_EphemeralResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| UINT32(), |
| TPM2B_ECC_POINT(), |
| UINT16()); |
| } |
| |
| void EC_EphemeralResponseParser( |
| const Tpm::EC_EphemeralResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EC_EphemeralErrorCallback, callback); |
| UINT32 param_size_out; |
| TPM2B_ECC_POINT q; |
| UINT16 counter; |
| TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral( |
| response, |
| ¶m_size_out, |
| &q, |
| &counter, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| param_size_out, |
| q, |
| counter); |
| } |
| |
| void Tpm::EC_Ephemeral( |
| const UINT32& param_size, |
| const TPMI_ECC_CURVE& curve_id, |
| AuthorizationDelegate* authorization_delegate, |
| const EC_EphemeralResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EC_EphemeralErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(EC_EphemeralResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_EC_Ephemeral( |
| param_size, |
| curve_id, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::EC_EphemeralSync( |
| const UINT32& param_size, |
| const TPMI_ECC_CURVE& curve_id, |
| UINT32* param_size_out, |
| TPM2B_ECC_POINT* q, |
| UINT16* counter, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_EC_Ephemeral( |
| param_size, |
| curve_id, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_EC_Ephemeral( |
| response, |
| param_size_out, |
| q, |
| counter, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_VerifySignature( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIGNATURE& signature, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_VerifySignature; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string digest_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| digest, |
| &digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Serialize_TPMT_SIGNATURE( |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = digest_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| digest_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(digest_bytes.data(), |
| digest_bytes.size()); |
| parameter_section_bytes += digest_bytes; |
| command_size += digest_bytes.size(); |
| hash->Update(signature_bytes.data(), |
| signature_bytes.size()); |
| parameter_section_bytes += signature_bytes; |
| command_size += signature_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_VerifySignature( |
| const std::string& response, |
| TPMT_TK_VERIFIED* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_VerifySignature; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string validation_bytes; |
| rc = Parse_TPMT_TK_VERIFIED( |
| &buffer, |
| validation, |
| &validation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void VerifySignatureErrorCallback( |
| const Tpm::VerifySignatureResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMT_TK_VERIFIED()); |
| } |
| |
| void VerifySignatureResponseParser( |
| const Tpm::VerifySignatureResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(VerifySignatureErrorCallback, callback); |
| TPMT_TK_VERIFIED validation; |
| TPM_RC rc = Tpm::ParseResponse_VerifySignature( |
| response, |
| &validation, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| validation); |
| } |
| |
| void Tpm::VerifySignature( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIGNATURE& signature, |
| AuthorizationDelegate* authorization_delegate, |
| const VerifySignatureResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(VerifySignatureErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(VerifySignatureResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_VerifySignature( |
| key_handle, |
| key_handle_name, |
| digest, |
| signature, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::VerifySignatureSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIGNATURE& signature, |
| TPMT_TK_VERIFIED* validation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_VerifySignature( |
| key_handle, |
| key_handle_name, |
| digest, |
| signature, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_VerifySignature( |
| response, |
| validation, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Sign( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_HASHCHECK& validation, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Sign; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string digest_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| digest, |
| &digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string validation_bytes; |
| rc = Serialize_TPMT_TK_HASHCHECK( |
| validation, |
| &validation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = digest_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| digest_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(digest_bytes.data(), |
| digest_bytes.size()); |
| parameter_section_bytes += digest_bytes; |
| command_size += digest_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(validation_bytes.data(), |
| validation_bytes.size()); |
| parameter_section_bytes += validation_bytes; |
| command_size += validation_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Sign( |
| const std::string& response, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Sign; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SignErrorCallback( |
| const Tpm::SignResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMT_SIGNATURE()); |
| } |
| |
| void SignResponseParser( |
| const Tpm::SignResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SignErrorCallback, callback); |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_Sign( |
| response, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| signature); |
| } |
| |
| void Tpm::Sign( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_HASHCHECK& validation, |
| AuthorizationDelegate* authorization_delegate, |
| const SignResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SignErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SignResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Sign( |
| key_handle, |
| key_handle_name, |
| digest, |
| in_scheme, |
| validation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SignSync( |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& digest, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const TPMT_TK_HASHCHECK& validation, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Sign( |
| key_handle, |
| key_handle_name, |
| digest, |
| in_scheme, |
| validation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Sign( |
| response, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_ALG_HASH& audit_alg, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string audit_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| audit_alg, |
| &audit_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string set_list_bytes; |
| rc = Serialize_TPML_CC( |
| set_list, |
| &set_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string clear_list_bytes; |
| rc = Serialize_TPML_CC( |
| clear_list, |
| &clear_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(audit_alg_bytes.data(), |
| audit_alg_bytes.size()); |
| parameter_section_bytes += audit_alg_bytes; |
| command_size += audit_alg_bytes.size(); |
| hash->Update(set_list_bytes.data(), |
| set_list_bytes.size()); |
| parameter_section_bytes += set_list_bytes; |
| command_size += set_list_bytes.size(); |
| hash->Update(clear_list_bytes.data(), |
| clear_list_bytes.size()); |
| parameter_section_bytes += clear_list_bytes; |
| command_size += clear_list_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SetCommandCodeAuditStatusErrorCallback( |
| const Tpm::SetCommandCodeAuditStatusResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void SetCommandCodeAuditStatusResponseParser( |
| const Tpm::SetCommandCodeAuditStatusResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetCommandCodeAuditStatusErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::SetCommandCodeAuditStatus( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_ALG_HASH& audit_alg, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| AuthorizationDelegate* authorization_delegate, |
| const SetCommandCodeAuditStatusResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetCommandCodeAuditStatusErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SetCommandCodeAuditStatusResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus( |
| auth, |
| auth_name, |
| audit_alg, |
| set_list, |
| clear_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SetCommandCodeAuditStatusSync( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_ALG_HASH& audit_alg, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus( |
| auth, |
| auth_name, |
| audit_alg, |
| set_list, |
| clear_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SetCommandCodeAuditStatus( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_Extend( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPML_DIGEST_VALUES& digests, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_Extend; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_handle_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_handle, |
| &pcr_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string digests_bytes; |
| rc = Serialize_TPML_DIGEST_VALUES( |
| digests, |
| &digests_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_handle_name.data(), |
| pcr_handle_name.size()); |
| handle_section_bytes += pcr_handle_bytes; |
| command_size += pcr_handle_bytes.size(); |
| hash->Update(digests_bytes.data(), |
| digests_bytes.size()); |
| parameter_section_bytes += digests_bytes; |
| command_size += digests_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_Extend( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_Extend; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_ExtendErrorCallback( |
| const Tpm::PCR_ExtendResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PCR_ExtendResponseParser( |
| const Tpm::PCR_ExtendResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ExtendErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PCR_Extend( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PCR_Extend( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPML_DIGEST_VALUES& digests, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_ExtendResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ExtendErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_ExtendResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Extend( |
| pcr_handle, |
| pcr_handle_name, |
| digests, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_ExtendSync( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPML_DIGEST_VALUES& digests, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Extend( |
| pcr_handle, |
| pcr_handle_name, |
| digests, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_Extend( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_Event( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_EVENT& event_data, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_Event; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_handle_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_handle, |
| &pcr_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string event_data_bytes; |
| rc = Serialize_TPM2B_EVENT( |
| event_data, |
| &event_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = event_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| event_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_handle_name.data(), |
| pcr_handle_name.size()); |
| handle_section_bytes += pcr_handle_bytes; |
| command_size += pcr_handle_bytes.size(); |
| hash->Update(event_data_bytes.data(), |
| event_data_bytes.size()); |
| parameter_section_bytes += event_data_bytes; |
| command_size += event_data_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_Event( |
| const std::string& response, |
| TPML_DIGEST_VALUES* digests, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_Event; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string digests_bytes; |
| rc = Parse_TPML_DIGEST_VALUES( |
| &buffer, |
| digests, |
| &digests_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_EventErrorCallback( |
| const Tpm::PCR_EventResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPML_DIGEST_VALUES()); |
| } |
| |
| void PCR_EventResponseParser( |
| const Tpm::PCR_EventResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_EventErrorCallback, callback); |
| TPML_DIGEST_VALUES digests; |
| TPM_RC rc = Tpm::ParseResponse_PCR_Event( |
| response, |
| &digests, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| digests); |
| } |
| |
| void Tpm::PCR_Event( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_EVENT& event_data, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_EventResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_EventErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_EventResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Event( |
| pcr_handle, |
| pcr_handle_name, |
| event_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_EventSync( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_EVENT& event_data, |
| TPML_DIGEST_VALUES* digests, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Event( |
| pcr_handle, |
| pcr_handle_name, |
| event_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_Event( |
| response, |
| digests, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_Read( |
| const TPML_PCR_SELECTION& pcr_selection_in, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_Read; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_selection_in_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| pcr_selection_in, |
| &pcr_selection_in_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_selection_in_bytes.data(), |
| pcr_selection_in_bytes.size()); |
| parameter_section_bytes += pcr_selection_in_bytes; |
| command_size += pcr_selection_in_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_Read( |
| const std::string& response, |
| UINT32* pcr_update_counter, |
| TPML_PCR_SELECTION* pcr_selection_out, |
| TPML_DIGEST* pcr_values, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_Read; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string pcr_update_counter_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| pcr_update_counter, |
| &pcr_update_counter_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_selection_out_bytes; |
| rc = Parse_TPML_PCR_SELECTION( |
| &buffer, |
| pcr_selection_out, |
| &pcr_selection_out_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_values_bytes; |
| rc = Parse_TPML_DIGEST( |
| &buffer, |
| pcr_values, |
| &pcr_values_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_ReadErrorCallback( |
| const Tpm::PCR_ReadResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| UINT32(), |
| TPML_PCR_SELECTION(), |
| TPML_DIGEST()); |
| } |
| |
| void PCR_ReadResponseParser( |
| const Tpm::PCR_ReadResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ReadErrorCallback, callback); |
| UINT32 pcr_update_counter; |
| TPML_PCR_SELECTION pcr_selection_out; |
| TPML_DIGEST pcr_values; |
| TPM_RC rc = Tpm::ParseResponse_PCR_Read( |
| response, |
| &pcr_update_counter, |
| &pcr_selection_out, |
| &pcr_values, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| pcr_update_counter, |
| pcr_selection_out, |
| pcr_values); |
| } |
| |
| void Tpm::PCR_Read( |
| const TPML_PCR_SELECTION& pcr_selection_in, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_ReadResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ReadErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_ReadResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Read( |
| pcr_selection_in, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_ReadSync( |
| const TPML_PCR_SELECTION& pcr_selection_in, |
| UINT32* pcr_update_counter, |
| TPML_PCR_SELECTION* pcr_selection_out, |
| TPML_DIGEST* pcr_values, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Read( |
| pcr_selection_in, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_Read( |
| response, |
| pcr_update_counter, |
| pcr_selection_out, |
| pcr_values, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_Allocate( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPML_PCR_SELECTION& pcr_allocation, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_Allocate; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_allocation_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| pcr_allocation, |
| &pcr_allocation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(pcr_allocation_bytes.data(), |
| pcr_allocation_bytes.size()); |
| parameter_section_bytes += pcr_allocation_bytes; |
| command_size += pcr_allocation_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_Allocate( |
| const std::string& response, |
| TPMI_YES_NO* allocation_success, |
| UINT32* max_pcr, |
| UINT32* size_needed, |
| UINT32* size_available, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_Allocate; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string allocation_success_bytes; |
| rc = Parse_TPMI_YES_NO( |
| &buffer, |
| allocation_success, |
| &allocation_success_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string max_pcr_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| max_pcr, |
| &max_pcr_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string size_needed_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| size_needed, |
| &size_needed_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string size_available_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| size_available, |
| &size_available_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_AllocateErrorCallback( |
| const Tpm::PCR_AllocateResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_YES_NO(), |
| UINT32(), |
| UINT32(), |
| UINT32()); |
| } |
| |
| void PCR_AllocateResponseParser( |
| const Tpm::PCR_AllocateResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_AllocateErrorCallback, callback); |
| TPMI_YES_NO allocation_success; |
| UINT32 max_pcr; |
| UINT32 size_needed; |
| UINT32 size_available; |
| TPM_RC rc = Tpm::ParseResponse_PCR_Allocate( |
| response, |
| &allocation_success, |
| &max_pcr, |
| &size_needed, |
| &size_available, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| allocation_success, |
| max_pcr, |
| size_needed, |
| size_available); |
| } |
| |
| void Tpm::PCR_Allocate( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPML_PCR_SELECTION& pcr_allocation, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_AllocateResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_AllocateErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_AllocateResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Allocate( |
| auth_handle, |
| auth_handle_name, |
| pcr_allocation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_AllocateSync( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPML_PCR_SELECTION& pcr_allocation, |
| TPMI_YES_NO* allocation_success, |
| UINT32* max_pcr, |
| UINT32* size_needed, |
| UINT32* size_available, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Allocate( |
| auth_handle, |
| auth_handle_name, |
| pcr_allocation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_Allocate( |
| response, |
| allocation_success, |
| max_pcr, |
| size_needed, |
| size_available, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_DH_PCR& pcr_num, |
| const std::string& pcr_num_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& policy_digest, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_policy_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| auth_policy, |
| &auth_policy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_digest_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| policy_digest, |
| &policy_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_num_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_num, |
| &pcr_num_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_policy_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_policy_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(pcr_num_name.data(), |
| pcr_num_name.size()); |
| handle_section_bytes += pcr_num_bytes; |
| command_size += pcr_num_bytes.size(); |
| hash->Update(auth_policy_bytes.data(), |
| auth_policy_bytes.size()); |
| parameter_section_bytes += auth_policy_bytes; |
| command_size += auth_policy_bytes.size(); |
| hash->Update(policy_digest_bytes.data(), |
| policy_digest_bytes.size()); |
| parameter_section_bytes += policy_digest_bytes; |
| command_size += policy_digest_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_SetAuthPolicyErrorCallback( |
| const Tpm::PCR_SetAuthPolicyResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PCR_SetAuthPolicyResponseParser( |
| const Tpm::PCR_SetAuthPolicyResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_SetAuthPolicyErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PCR_SetAuthPolicy( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PCR_SetAuthPolicy( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_DH_PCR& pcr_num, |
| const std::string& pcr_num_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& policy_digest, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_SetAuthPolicyResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_SetAuthPolicyErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_SetAuthPolicyResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy( |
| auth_handle, |
| auth_handle_name, |
| pcr_num, |
| pcr_num_name, |
| auth_policy, |
| policy_digest, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_SetAuthPolicySync( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_DH_PCR& pcr_num, |
| const std::string& pcr_num_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& policy_digest, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy( |
| auth_handle, |
| auth_handle_name, |
| pcr_num, |
| pcr_num_name, |
| auth_policy, |
| policy_digest, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_SetAuthPolicy( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_DIGEST& auth, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_SetAuthValue; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_handle_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_handle, |
| &pcr_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_handle_name.data(), |
| pcr_handle_name.size()); |
| handle_section_bytes += pcr_handle_bytes; |
| command_size += pcr_handle_bytes.size(); |
| hash->Update(auth_bytes.data(), |
| auth_bytes.size()); |
| parameter_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_SetAuthValue( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_SetAuthValue; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_SetAuthValueErrorCallback( |
| const Tpm::PCR_SetAuthValueResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PCR_SetAuthValueResponseParser( |
| const Tpm::PCR_SetAuthValueResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_SetAuthValueErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PCR_SetAuthValue( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PCR_SetAuthValue( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_DIGEST& auth, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_SetAuthValueResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_SetAuthValueErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_SetAuthValueResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_SetAuthValue( |
| pcr_handle, |
| pcr_handle_name, |
| auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_SetAuthValueSync( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| const TPM2B_DIGEST& auth, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_SetAuthValue( |
| pcr_handle, |
| pcr_handle_name, |
| auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_SetAuthValue( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PCR_Reset( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PCR_Reset; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_handle_bytes; |
| rc = Serialize_TPMI_DH_PCR( |
| pcr_handle, |
| &pcr_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(pcr_handle_name.data(), |
| pcr_handle_name.size()); |
| handle_section_bytes += pcr_handle_bytes; |
| command_size += pcr_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PCR_Reset( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PCR_Reset; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PCR_ResetErrorCallback( |
| const Tpm::PCR_ResetResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PCR_ResetResponseParser( |
| const Tpm::PCR_ResetResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ResetErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PCR_Reset( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PCR_Reset( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PCR_ResetResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PCR_ResetErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PCR_ResetResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Reset( |
| pcr_handle, |
| pcr_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PCR_ResetSync( |
| const TPMI_DH_PCR& pcr_handle, |
| const std::string& pcr_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PCR_Reset( |
| pcr_handle, |
| pcr_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PCR_Reset( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicySigned( |
| const TPMI_DH_OBJECT& auth_object, |
| const std::string& auth_object_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPMT_SIGNATURE& auth, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicySigned; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_object_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| auth_object, |
| &auth_object_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nonce_tpm_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| nonce_tpm, |
| &nonce_tpm_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string cp_hash_a_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| cp_hash_a, |
| &cp_hash_a_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ref_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| policy_ref, |
| &policy_ref_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMT_SIGNATURE( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = nonce_tpm_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| nonce_tpm_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_object_name.data(), |
| auth_object_name.size()); |
| handle_section_bytes += auth_object_bytes; |
| command_size += auth_object_bytes.size(); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(nonce_tpm_bytes.data(), |
| nonce_tpm_bytes.size()); |
| parameter_section_bytes += nonce_tpm_bytes; |
| command_size += nonce_tpm_bytes.size(); |
| hash->Update(cp_hash_a_bytes.data(), |
| cp_hash_a_bytes.size()); |
| parameter_section_bytes += cp_hash_a_bytes; |
| command_size += cp_hash_a_bytes.size(); |
| hash->Update(policy_ref_bytes.data(), |
| policy_ref_bytes.size()); |
| parameter_section_bytes += policy_ref_bytes; |
| command_size += policy_ref_bytes.size(); |
| hash->Update(auth_bytes.data(), |
| auth_bytes.size()); |
| parameter_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicySigned( |
| const std::string& response, |
| TPM2B_TIMEOUT* timeout, |
| TPMT_TK_AUTH* policy_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicySigned; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string timeout_bytes; |
| rc = Parse_TPM2B_TIMEOUT( |
| &buffer, |
| timeout, |
| &timeout_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ticket_bytes; |
| rc = Parse_TPMT_TK_AUTH( |
| &buffer, |
| policy_ticket, |
| &policy_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = timeout_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| timeout_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_TIMEOUT( |
| &timeout_bytes, |
| timeout, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicySignedErrorCallback( |
| const Tpm::PolicySignedResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_TIMEOUT(), |
| TPMT_TK_AUTH()); |
| } |
| |
| void PolicySignedResponseParser( |
| const Tpm::PolicySignedResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicySignedErrorCallback, callback); |
| TPM2B_TIMEOUT timeout; |
| TPMT_TK_AUTH policy_ticket; |
| TPM_RC rc = Tpm::ParseResponse_PolicySigned( |
| response, |
| &timeout, |
| &policy_ticket, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| timeout, |
| policy_ticket); |
| } |
| |
| void Tpm::PolicySigned( |
| const TPMI_DH_OBJECT& auth_object, |
| const std::string& auth_object_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPMT_SIGNATURE& auth, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicySignedResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicySignedErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicySignedResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicySigned( |
| auth_object, |
| auth_object_name, |
| policy_session, |
| policy_session_name, |
| nonce_tpm, |
| cp_hash_a, |
| policy_ref, |
| auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicySignedSync( |
| const TPMI_DH_OBJECT& auth_object, |
| const std::string& auth_object_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPMT_SIGNATURE& auth, |
| TPM2B_TIMEOUT* timeout, |
| TPMT_TK_AUTH* policy_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicySigned( |
| auth_object, |
| auth_object_name, |
| policy_session, |
| policy_session_name, |
| nonce_tpm, |
| cp_hash_a, |
| policy_ref, |
| auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicySigned( |
| response, |
| timeout, |
| policy_ticket, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicySecret( |
| const TPMI_DH_ENTITY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicySecret; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_DH_ENTITY( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nonce_tpm_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| nonce_tpm, |
| &nonce_tpm_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string cp_hash_a_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| cp_hash_a, |
| &cp_hash_a_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ref_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| policy_ref, |
| &policy_ref_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = nonce_tpm_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| nonce_tpm_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(nonce_tpm_bytes.data(), |
| nonce_tpm_bytes.size()); |
| parameter_section_bytes += nonce_tpm_bytes; |
| command_size += nonce_tpm_bytes.size(); |
| hash->Update(cp_hash_a_bytes.data(), |
| cp_hash_a_bytes.size()); |
| parameter_section_bytes += cp_hash_a_bytes; |
| command_size += cp_hash_a_bytes.size(); |
| hash->Update(policy_ref_bytes.data(), |
| policy_ref_bytes.size()); |
| parameter_section_bytes += policy_ref_bytes; |
| command_size += policy_ref_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicySecret( |
| const std::string& response, |
| TPM2B_TIMEOUT* timeout, |
| TPMT_TK_AUTH* policy_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicySecret; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string timeout_bytes; |
| rc = Parse_TPM2B_TIMEOUT( |
| &buffer, |
| timeout, |
| &timeout_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ticket_bytes; |
| rc = Parse_TPMT_TK_AUTH( |
| &buffer, |
| policy_ticket, |
| &policy_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = timeout_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| timeout_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_TIMEOUT( |
| &timeout_bytes, |
| timeout, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicySecretErrorCallback( |
| const Tpm::PolicySecretResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_TIMEOUT(), |
| TPMT_TK_AUTH()); |
| } |
| |
| void PolicySecretResponseParser( |
| const Tpm::PolicySecretResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicySecretErrorCallback, callback); |
| TPM2B_TIMEOUT timeout; |
| TPMT_TK_AUTH policy_ticket; |
| TPM_RC rc = Tpm::ParseResponse_PolicySecret( |
| response, |
| &timeout, |
| &policy_ticket, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| timeout, |
| policy_ticket); |
| } |
| |
| void Tpm::PolicySecret( |
| const TPMI_DH_ENTITY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicySecretResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicySecretErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicySecretResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicySecret( |
| auth_handle, |
| auth_handle_name, |
| policy_session, |
| policy_session_name, |
| nonce_tpm, |
| cp_hash_a, |
| policy_ref, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicySecretSync( |
| const TPMI_DH_ENTITY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NONCE& nonce_tpm, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| TPM2B_TIMEOUT* timeout, |
| TPMT_TK_AUTH* policy_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicySecret( |
| auth_handle, |
| auth_handle_name, |
| policy_session, |
| policy_session_name, |
| nonce_tpm, |
| cp_hash_a, |
| policy_ref, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicySecret( |
| response, |
| timeout, |
| policy_ticket, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyTicket( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_TIMEOUT& timeout, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& auth_name, |
| const TPMT_TK_AUTH& ticket, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyTicket; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string timeout_bytes; |
| rc = Serialize_TPM2B_TIMEOUT( |
| timeout, |
| &timeout_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string cp_hash_a_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| cp_hash_a, |
| &cp_hash_a_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ref_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| policy_ref, |
| &policy_ref_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_name_bytes; |
| rc = Serialize_TPM2B_NAME( |
| auth_name, |
| &auth_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string ticket_bytes; |
| rc = Serialize_TPMT_TK_AUTH( |
| ticket, |
| &ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = timeout_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| timeout_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(timeout_bytes.data(), |
| timeout_bytes.size()); |
| parameter_section_bytes += timeout_bytes; |
| command_size += timeout_bytes.size(); |
| hash->Update(cp_hash_a_bytes.data(), |
| cp_hash_a_bytes.size()); |
| parameter_section_bytes += cp_hash_a_bytes; |
| command_size += cp_hash_a_bytes.size(); |
| hash->Update(policy_ref_bytes.data(), |
| policy_ref_bytes.size()); |
| parameter_section_bytes += policy_ref_bytes; |
| command_size += policy_ref_bytes.size(); |
| hash->Update(auth_name_bytes.data(), |
| auth_name_bytes.size()); |
| parameter_section_bytes += auth_name_bytes; |
| command_size += auth_name_bytes.size(); |
| hash->Update(ticket_bytes.data(), |
| ticket_bytes.size()); |
| parameter_section_bytes += ticket_bytes; |
| command_size += ticket_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyTicket( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyTicket; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyTicketErrorCallback( |
| const Tpm::PolicyTicketResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyTicketResponseParser( |
| const Tpm::PolicyTicketResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyTicketErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyTicket( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyTicket( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_TIMEOUT& timeout, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& auth_name, |
| const TPMT_TK_AUTH& ticket, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyTicketResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyTicketErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyTicketResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyTicket( |
| policy_session, |
| policy_session_name, |
| timeout, |
| cp_hash_a, |
| policy_ref, |
| auth_name, |
| ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyTicketSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_TIMEOUT& timeout, |
| const TPM2B_DIGEST& cp_hash_a, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& auth_name, |
| const TPMT_TK_AUTH& ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyTicket( |
| policy_session, |
| policy_session_name, |
| timeout, |
| cp_hash_a, |
| policy_ref, |
| auth_name, |
| ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyTicket( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyOR( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPML_DIGEST& p_hash_list, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyOR; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string p_hash_list_bytes; |
| rc = Serialize_TPML_DIGEST( |
| p_hash_list, |
| &p_hash_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(p_hash_list_bytes.data(), |
| p_hash_list_bytes.size()); |
| parameter_section_bytes += p_hash_list_bytes; |
| command_size += p_hash_list_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyOR( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyOR; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyORErrorCallback( |
| const Tpm::PolicyORResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyORResponseParser( |
| const Tpm::PolicyORResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyORErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyOR( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyOR( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPML_DIGEST& p_hash_list, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyORResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyORErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyORResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyOR( |
| policy_session, |
| policy_session_name, |
| p_hash_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyORSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPML_DIGEST& p_hash_list, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyOR( |
| policy_session, |
| policy_session_name, |
| p_hash_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyOR( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyPCR( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& pcr_digest, |
| const TPML_PCR_SELECTION& pcrs, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyPCR; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcr_digest_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| pcr_digest, |
| &pcr_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string pcrs_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| pcrs, |
| &pcrs_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = pcr_digest_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| pcr_digest_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(pcr_digest_bytes.data(), |
| pcr_digest_bytes.size()); |
| parameter_section_bytes += pcr_digest_bytes; |
| command_size += pcr_digest_bytes.size(); |
| hash->Update(pcrs_bytes.data(), |
| pcrs_bytes.size()); |
| parameter_section_bytes += pcrs_bytes; |
| command_size += pcrs_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyPCR( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyPCR; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyPCRErrorCallback( |
| const Tpm::PolicyPCRResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyPCRResponseParser( |
| const Tpm::PolicyPCRResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPCRErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyPCR( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyPCR( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& pcr_digest, |
| const TPML_PCR_SELECTION& pcrs, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyPCRResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPCRErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyPCRResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPCR( |
| policy_session, |
| policy_session_name, |
| pcr_digest, |
| pcrs, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyPCRSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& pcr_digest, |
| const TPML_PCR_SELECTION& pcrs, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPCR( |
| policy_session, |
| policy_session_name, |
| pcr_digest, |
| pcrs, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyPCR( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyLocality( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMA_LOCALITY& locality, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyLocality; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string locality_bytes; |
| rc = Serialize_TPMA_LOCALITY( |
| locality, |
| &locality_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(locality_bytes.data(), |
| locality_bytes.size()); |
| parameter_section_bytes += locality_bytes; |
| command_size += locality_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyLocality( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyLocality; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyLocalityErrorCallback( |
| const Tpm::PolicyLocalityResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyLocalityResponseParser( |
| const Tpm::PolicyLocalityResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyLocalityErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyLocality( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyLocality( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMA_LOCALITY& locality, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyLocalityResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyLocalityErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyLocalityResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyLocality( |
| policy_session, |
| policy_session_name, |
| locality, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyLocalitySync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMA_LOCALITY& locality, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyLocality( |
| policy_session, |
| policy_session_name, |
| locality, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyLocality( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyNV( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyNV; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string operand_b_bytes; |
| rc = Serialize_TPM2B_OPERAND( |
| operand_b, |
| &operand_b_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string offset_bytes; |
| rc = Serialize_UINT16( |
| offset, |
| &offset_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string operation_bytes; |
| rc = Serialize_TPM_EO( |
| operation, |
| &operation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = operand_b_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| operand_b_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(operand_b_bytes.data(), |
| operand_b_bytes.size()); |
| parameter_section_bytes += operand_b_bytes; |
| command_size += operand_b_bytes.size(); |
| hash->Update(offset_bytes.data(), |
| offset_bytes.size()); |
| parameter_section_bytes += offset_bytes; |
| command_size += offset_bytes.size(); |
| hash->Update(operation_bytes.data(), |
| operation_bytes.size()); |
| parameter_section_bytes += operation_bytes; |
| command_size += operation_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyNV( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyNV; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyNVErrorCallback( |
| const Tpm::PolicyNVResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyNVResponseParser( |
| const Tpm::PolicyNVResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNVErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyNV( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyNV( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyNVResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNVErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyNVResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNV( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| policy_session, |
| policy_session_name, |
| operand_b, |
| offset, |
| operation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyNVSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNV( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| policy_session, |
| policy_session_name, |
| operand_b, |
| offset, |
| operation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyNV( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyCounterTimer( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyCounterTimer; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string operand_b_bytes; |
| rc = Serialize_TPM2B_OPERAND( |
| operand_b, |
| &operand_b_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string offset_bytes; |
| rc = Serialize_UINT16( |
| offset, |
| &offset_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string operation_bytes; |
| rc = Serialize_TPM_EO( |
| operation, |
| &operation_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = operand_b_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| operand_b_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(operand_b_bytes.data(), |
| operand_b_bytes.size()); |
| parameter_section_bytes += operand_b_bytes; |
| command_size += operand_b_bytes.size(); |
| hash->Update(offset_bytes.data(), |
| offset_bytes.size()); |
| parameter_section_bytes += offset_bytes; |
| command_size += offset_bytes.size(); |
| hash->Update(operation_bytes.data(), |
| operation_bytes.size()); |
| parameter_section_bytes += operation_bytes; |
| command_size += operation_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyCounterTimer( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyCounterTimer; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyCounterTimerErrorCallback( |
| const Tpm::PolicyCounterTimerResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyCounterTimerResponseParser( |
| const Tpm::PolicyCounterTimerResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCounterTimerErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyCounterTimer( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyCounterTimer( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyCounterTimerResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCounterTimerErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyCounterTimerResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCounterTimer( |
| policy_session, |
| policy_session_name, |
| operand_b, |
| offset, |
| operation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyCounterTimerSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_OPERAND& operand_b, |
| const UINT16& offset, |
| const TPM_EO& operation, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCounterTimer( |
| policy_session, |
| policy_session_name, |
| operand_b, |
| offset, |
| operation, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyCounterTimer( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyCommandCode( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM_CC& code, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyCommandCode; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string code_bytes; |
| rc = Serialize_TPM_CC( |
| code, |
| &code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(code_bytes.data(), |
| code_bytes.size()); |
| parameter_section_bytes += code_bytes; |
| command_size += code_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyCommandCode( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyCommandCode; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyCommandCodeErrorCallback( |
| const Tpm::PolicyCommandCodeResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyCommandCodeResponseParser( |
| const Tpm::PolicyCommandCodeResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCommandCodeErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyCommandCode( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyCommandCode( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM_CC& code, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyCommandCodeResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCommandCodeErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyCommandCodeResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCommandCode( |
| policy_session, |
| policy_session_name, |
| code, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyCommandCodeSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM_CC& code, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCommandCode( |
| policy_session, |
| policy_session_name, |
| code, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyCommandCode( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyPhysicalPresence; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyPhysicalPresence; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyPhysicalPresenceErrorCallback( |
| const Tpm::PolicyPhysicalPresenceResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyPhysicalPresenceResponseParser( |
| const Tpm::PolicyPhysicalPresenceResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPhysicalPresenceErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyPhysicalPresence( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyPhysicalPresenceResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPhysicalPresenceErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyPhysicalPresenceResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPhysicalPresence( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyPhysicalPresenceSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPhysicalPresence( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyPhysicalPresence( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyCpHash( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& cp_hash_a, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyCpHash; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string cp_hash_a_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| cp_hash_a, |
| &cp_hash_a_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = cp_hash_a_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| cp_hash_a_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(cp_hash_a_bytes.data(), |
| cp_hash_a_bytes.size()); |
| parameter_section_bytes += cp_hash_a_bytes; |
| command_size += cp_hash_a_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyCpHash( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyCpHash; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyCpHashErrorCallback( |
| const Tpm::PolicyCpHashResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyCpHashResponseParser( |
| const Tpm::PolicyCpHashResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCpHashErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyCpHash( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyCpHash( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& cp_hash_a, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyCpHashResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyCpHashErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyCpHashResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCpHash( |
| policy_session, |
| policy_session_name, |
| cp_hash_a, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyCpHashSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& cp_hash_a, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyCpHash( |
| policy_session, |
| policy_session_name, |
| cp_hash_a, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyCpHash( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyNameHash( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& name_hash, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyNameHash; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string name_hash_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| name_hash, |
| &name_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = name_hash_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| name_hash_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(name_hash_bytes.data(), |
| name_hash_bytes.size()); |
| parameter_section_bytes += name_hash_bytes; |
| command_size += name_hash_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyNameHash( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyNameHash; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyNameHashErrorCallback( |
| const Tpm::PolicyNameHashResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyNameHashResponseParser( |
| const Tpm::PolicyNameHashResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNameHashErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyNameHash( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyNameHash( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& name_hash, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyNameHashResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNameHashErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyNameHashResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNameHash( |
| policy_session, |
| policy_session_name, |
| name_hash, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyNameHashSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& name_hash, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNameHash( |
| policy_session, |
| policy_session_name, |
| name_hash, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyNameHash( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NAME& object_name, |
| const TPM2B_NAME& new_parent_name, |
| const TPMI_YES_NO& include_object, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyDuplicationSelect; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_name_bytes; |
| rc = Serialize_TPM2B_NAME( |
| object_name, |
| &object_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_parent_name_bytes; |
| rc = Serialize_TPM2B_NAME( |
| new_parent_name, |
| &new_parent_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string include_object_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| include_object, |
| &include_object_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = object_name_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| object_name_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(object_name_bytes.data(), |
| object_name_bytes.size()); |
| parameter_section_bytes += object_name_bytes; |
| command_size += object_name_bytes.size(); |
| hash->Update(new_parent_name_bytes.data(), |
| new_parent_name_bytes.size()); |
| parameter_section_bytes += new_parent_name_bytes; |
| command_size += new_parent_name_bytes.size(); |
| hash->Update(include_object_bytes.data(), |
| include_object_bytes.size()); |
| parameter_section_bytes += include_object_bytes; |
| command_size += include_object_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyDuplicationSelect; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyDuplicationSelectErrorCallback( |
| const Tpm::PolicyDuplicationSelectResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyDuplicationSelectResponseParser( |
| const Tpm::PolicyDuplicationSelectResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyDuplicationSelectErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyDuplicationSelect( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NAME& object_name, |
| const TPM2B_NAME& new_parent_name, |
| const TPMI_YES_NO& include_object, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyDuplicationSelectResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyDuplicationSelectErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyDuplicationSelectResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyDuplicationSelect( |
| policy_session, |
| policy_session_name, |
| object_name, |
| new_parent_name, |
| include_object, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyDuplicationSelectSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_NAME& object_name, |
| const TPM2B_NAME& new_parent_name, |
| const TPMI_YES_NO& include_object, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyDuplicationSelect( |
| policy_session, |
| policy_session_name, |
| object_name, |
| new_parent_name, |
| include_object, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyDuplicationSelect( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyAuthorize( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& approved_policy, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& key_sign, |
| const TPMT_TK_VERIFIED& check_ticket, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyAuthorize; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string approved_policy_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| approved_policy, |
| &approved_policy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_ref_bytes; |
| rc = Serialize_TPM2B_NONCE( |
| policy_ref, |
| &policy_ref_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_sign_bytes; |
| rc = Serialize_TPM2B_NAME( |
| key_sign, |
| &key_sign_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string check_ticket_bytes; |
| rc = Serialize_TPMT_TK_VERIFIED( |
| check_ticket, |
| &check_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = approved_policy_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| approved_policy_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(approved_policy_bytes.data(), |
| approved_policy_bytes.size()); |
| parameter_section_bytes += approved_policy_bytes; |
| command_size += approved_policy_bytes.size(); |
| hash->Update(policy_ref_bytes.data(), |
| policy_ref_bytes.size()); |
| parameter_section_bytes += policy_ref_bytes; |
| command_size += policy_ref_bytes.size(); |
| hash->Update(key_sign_bytes.data(), |
| key_sign_bytes.size()); |
| parameter_section_bytes += key_sign_bytes; |
| command_size += key_sign_bytes.size(); |
| hash->Update(check_ticket_bytes.data(), |
| check_ticket_bytes.size()); |
| parameter_section_bytes += check_ticket_bytes; |
| command_size += check_ticket_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyAuthorize( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyAuthorize; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyAuthorizeErrorCallback( |
| const Tpm::PolicyAuthorizeResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyAuthorizeResponseParser( |
| const Tpm::PolicyAuthorizeResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyAuthorizeErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyAuthorize( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyAuthorize( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& approved_policy, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& key_sign, |
| const TPMT_TK_VERIFIED& check_ticket, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyAuthorizeResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyAuthorizeErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyAuthorizeResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyAuthorize( |
| policy_session, |
| policy_session_name, |
| approved_policy, |
| policy_ref, |
| key_sign, |
| check_ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyAuthorizeSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPM2B_DIGEST& approved_policy, |
| const TPM2B_NONCE& policy_ref, |
| const TPM2B_NAME& key_sign, |
| const TPMT_TK_VERIFIED& check_ticket, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyAuthorize( |
| policy_session, |
| policy_session_name, |
| approved_policy, |
| policy_ref, |
| key_sign, |
| check_ticket, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyAuthorize( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyAuthValue( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyAuthValue; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyAuthValue( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyAuthValue; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyAuthValueErrorCallback( |
| const Tpm::PolicyAuthValueResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyAuthValueResponseParser( |
| const Tpm::PolicyAuthValueResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyAuthValueErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyAuthValue( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyAuthValue( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyAuthValueResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyAuthValueErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyAuthValueResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyAuthValue( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyAuthValueSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyAuthValue( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyAuthValue( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyPassword( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyPassword; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyPassword( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyPassword; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyPasswordErrorCallback( |
| const Tpm::PolicyPasswordResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyPasswordResponseParser( |
| const Tpm::PolicyPasswordResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPasswordErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyPassword( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyPassword( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyPasswordResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyPasswordErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyPasswordResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPassword( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyPasswordSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyPassword( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyPassword( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyGetDigest( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyGetDigest; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyGetDigest( |
| const std::string& response, |
| TPM2B_DIGEST* policy_digest, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyGetDigest; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string policy_digest_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| policy_digest, |
| &policy_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = policy_digest_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| policy_digest_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_DIGEST( |
| &policy_digest_bytes, |
| policy_digest, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyGetDigestErrorCallback( |
| const Tpm::PolicyGetDigestResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_DIGEST()); |
| } |
| |
| void PolicyGetDigestResponseParser( |
| const Tpm::PolicyGetDigestResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyGetDigestErrorCallback, callback); |
| TPM2B_DIGEST policy_digest; |
| TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest( |
| response, |
| &policy_digest, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| policy_digest); |
| } |
| |
| void Tpm::PolicyGetDigest( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyGetDigestResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyGetDigestErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyGetDigestResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyGetDigest( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyGetDigestSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| TPM2B_DIGEST* policy_digest, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyGetDigest( |
| policy_session, |
| policy_session_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyGetDigest( |
| response, |
| policy_digest, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PolicyNvWritten( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMI_YES_NO& written_set, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PolicyNvWritten; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string policy_session_bytes; |
| rc = Serialize_TPMI_SH_POLICY( |
| policy_session, |
| &policy_session_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string written_set_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| written_set, |
| &written_set_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(policy_session_name.data(), |
| policy_session_name.size()); |
| handle_section_bytes += policy_session_bytes; |
| command_size += policy_session_bytes.size(); |
| hash->Update(written_set_bytes.data(), |
| written_set_bytes.size()); |
| parameter_section_bytes += written_set_bytes; |
| command_size += written_set_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PolicyNvWritten( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PolicyNvWritten; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PolicyNvWrittenErrorCallback( |
| const Tpm::PolicyNvWrittenResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PolicyNvWrittenResponseParser( |
| const Tpm::PolicyNvWrittenResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNvWrittenErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PolicyNvWritten( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PolicyNvWritten( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMI_YES_NO& written_set, |
| AuthorizationDelegate* authorization_delegate, |
| const PolicyNvWrittenResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PolicyNvWrittenErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PolicyNvWrittenResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNvWritten( |
| policy_session, |
| policy_session_name, |
| written_set, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PolicyNvWrittenSync( |
| const TPMI_SH_POLICY& policy_session, |
| const std::string& policy_session_name, |
| const TPMI_YES_NO& written_set, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PolicyNvWritten( |
| policy_session, |
| policy_session_name, |
| written_set, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PolicyNvWritten( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_CreatePrimary( |
| const TPMI_RH_HIERARCHY& primary_handle, |
| const std::string& primary_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_CreatePrimary; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string primary_handle_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| primary_handle, |
| &primary_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_sensitive_bytes; |
| rc = Serialize_TPM2B_SENSITIVE_CREATE( |
| in_sensitive, |
| &in_sensitive_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_public_bytes; |
| rc = Serialize_TPM2B_PUBLIC( |
| in_public, |
| &in_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string outside_info_bytes; |
| rc = Serialize_TPM2B_DATA( |
| outside_info, |
| &outside_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_pcr_bytes; |
| rc = Serialize_TPML_PCR_SELECTION( |
| creation_pcr, |
| &creation_pcr_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = in_sensitive_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| in_sensitive_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(primary_handle_name.data(), |
| primary_handle_name.size()); |
| handle_section_bytes += primary_handle_bytes; |
| command_size += primary_handle_bytes.size(); |
| hash->Update(in_sensitive_bytes.data(), |
| in_sensitive_bytes.size()); |
| parameter_section_bytes += in_sensitive_bytes; |
| command_size += in_sensitive_bytes.size(); |
| hash->Update(in_public_bytes.data(), |
| in_public_bytes.size()); |
| parameter_section_bytes += in_public_bytes; |
| command_size += in_public_bytes.size(); |
| hash->Update(outside_info_bytes.data(), |
| outside_info_bytes.size()); |
| parameter_section_bytes += outside_info_bytes; |
| command_size += outside_info_bytes.size(); |
| hash->Update(creation_pcr_bytes.data(), |
| creation_pcr_bytes.size()); |
| parameter_section_bytes += creation_pcr_bytes; |
| command_size += creation_pcr_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_CreatePrimary( |
| const std::string& response, |
| TPM_HANDLE* object_handle, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_CREATION_DATA* creation_data, |
| TPM2B_DIGEST* creation_hash, |
| TPMT_TK_CREATION* creation_ticket, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string object_handle_bytes; |
| rc = Parse_TPM_HANDLE( |
| &buffer, |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_CreatePrimary; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string out_public_bytes; |
| rc = Parse_TPM2B_PUBLIC( |
| &buffer, |
| out_public, |
| &out_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_data_bytes; |
| rc = Parse_TPM2B_CREATION_DATA( |
| &buffer, |
| creation_data, |
| &creation_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_hash_bytes; |
| rc = Parse_TPM2B_DIGEST( |
| &buffer, |
| creation_hash, |
| &creation_hash_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string creation_ticket_bytes; |
| rc = Parse_TPMT_TK_CREATION( |
| &buffer, |
| creation_ticket, |
| &creation_ticket_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| name, |
| &name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = out_public_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| out_public_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_PUBLIC( |
| &out_public_bytes, |
| out_public, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void CreatePrimaryErrorCallback( |
| const Tpm::CreatePrimaryResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_HANDLE(), |
| TPM2B_PUBLIC(), |
| TPM2B_CREATION_DATA(), |
| TPM2B_DIGEST(), |
| TPMT_TK_CREATION(), |
| TPM2B_NAME()); |
| } |
| |
| void CreatePrimaryResponseParser( |
| const Tpm::CreatePrimaryResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CreatePrimaryErrorCallback, callback); |
| TPM_HANDLE object_handle; |
| TPM2B_PUBLIC out_public; |
| TPM2B_CREATION_DATA creation_data; |
| TPM2B_DIGEST creation_hash; |
| TPMT_TK_CREATION creation_ticket; |
| TPM2B_NAME name; |
| TPM_RC rc = Tpm::ParseResponse_CreatePrimary( |
| response, |
| &object_handle, |
| &out_public, |
| &creation_data, |
| &creation_hash, |
| &creation_ticket, |
| &name, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| object_handle, |
| out_public, |
| creation_data, |
| creation_hash, |
| creation_ticket, |
| name); |
| } |
| |
| void Tpm::CreatePrimary( |
| const TPMI_RH_HIERARCHY& primary_handle, |
| const std::string& primary_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| AuthorizationDelegate* authorization_delegate, |
| const CreatePrimaryResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(CreatePrimaryErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(CreatePrimaryResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_CreatePrimary( |
| primary_handle, |
| primary_handle_name, |
| in_sensitive, |
| in_public, |
| outside_info, |
| creation_pcr, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::CreatePrimarySync( |
| const TPMI_RH_HIERARCHY& primary_handle, |
| const std::string& primary_handle_name, |
| const TPM2B_SENSITIVE_CREATE& in_sensitive, |
| const TPM2B_PUBLIC& in_public, |
| const TPM2B_DATA& outside_info, |
| const TPML_PCR_SELECTION& creation_pcr, |
| TPM_HANDLE* object_handle, |
| TPM2B_PUBLIC* out_public, |
| TPM2B_CREATION_DATA* creation_data, |
| TPM2B_DIGEST* creation_hash, |
| TPMT_TK_CREATION* creation_ticket, |
| TPM2B_NAME* name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_CreatePrimary( |
| primary_handle, |
| primary_handle_name, |
| in_sensitive, |
| in_public, |
| outside_info, |
| creation_pcr, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_CreatePrimary( |
| response, |
| object_handle, |
| out_public, |
| creation_data, |
| creation_hash, |
| creation_ticket, |
| name, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_HierarchyControl( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_ENABLES& enable, |
| const TPMI_YES_NO& state, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_HierarchyControl; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string enable_bytes; |
| rc = Serialize_TPMI_RH_ENABLES( |
| enable, |
| &enable_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string state_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| state, |
| &state_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(enable_bytes.data(), |
| enable_bytes.size()); |
| parameter_section_bytes += enable_bytes; |
| command_size += enable_bytes.size(); |
| hash->Update(state_bytes.data(), |
| state_bytes.size()); |
| parameter_section_bytes += state_bytes; |
| command_size += state_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_HierarchyControl( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_HierarchyControl; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HierarchyControlErrorCallback( |
| const Tpm::HierarchyControlResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void HierarchyControlResponseParser( |
| const Tpm::HierarchyControlResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HierarchyControlErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_HierarchyControl( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::HierarchyControl( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_ENABLES& enable, |
| const TPMI_YES_NO& state, |
| AuthorizationDelegate* authorization_delegate, |
| const HierarchyControlResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HierarchyControlErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HierarchyControlResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_HierarchyControl( |
| auth_handle, |
| auth_handle_name, |
| enable, |
| state, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HierarchyControlSync( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_ENABLES& enable, |
| const TPMI_YES_NO& state, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_HierarchyControl( |
| auth_handle, |
| auth_handle_name, |
| enable, |
| state, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_HierarchyControl( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& hash_alg, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SetPrimaryPolicy; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_policy_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| auth_policy, |
| &auth_policy_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string hash_alg_bytes; |
| rc = Serialize_TPMI_ALG_HASH( |
| hash_alg, |
| &hash_alg_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_policy_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_policy_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(auth_policy_bytes.data(), |
| auth_policy_bytes.size()); |
| parameter_section_bytes += auth_policy_bytes; |
| command_size += auth_policy_bytes.size(); |
| hash->Update(hash_alg_bytes.data(), |
| hash_alg_bytes.size()); |
| parameter_section_bytes += hash_alg_bytes; |
| command_size += hash_alg_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SetPrimaryPolicy( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SetPrimaryPolicy; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SetPrimaryPolicyErrorCallback( |
| const Tpm::SetPrimaryPolicyResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void SetPrimaryPolicyResponseParser( |
| const Tpm::SetPrimaryPolicyResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetPrimaryPolicyErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_SetPrimaryPolicy( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::SetPrimaryPolicy( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate, |
| const SetPrimaryPolicyResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetPrimaryPolicyErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SetPrimaryPolicyResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetPrimaryPolicy( |
| auth_handle, |
| auth_handle_name, |
| auth_policy, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SetPrimaryPolicySync( |
| const TPMI_RH_HIERARCHY& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_DIGEST& auth_policy, |
| const TPMI_ALG_HASH& hash_alg, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetPrimaryPolicy( |
| auth_handle, |
| auth_handle_name, |
| auth_policy, |
| hash_alg, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SetPrimaryPolicy( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ChangePPS( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ChangePPS; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ChangePPS( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ChangePPS; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ChangePPSErrorCallback( |
| const Tpm::ChangePPSResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void ChangePPSResponseParser( |
| const Tpm::ChangePPSResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ChangePPSErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_ChangePPS( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::ChangePPS( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ChangePPSResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ChangePPSErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ChangePPSResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ChangePPS( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ChangePPSSync( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ChangePPS( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ChangePPS( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ChangeEPS( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ChangeEPS; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ChangeEPS( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ChangeEPS; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ChangeEPSErrorCallback( |
| const Tpm::ChangeEPSResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void ChangeEPSResponseParser( |
| const Tpm::ChangeEPSResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ChangeEPSErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_ChangeEPS( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::ChangeEPS( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ChangeEPSResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ChangeEPSErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ChangeEPSResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ChangeEPS( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ChangeEPSSync( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ChangeEPS( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ChangeEPS( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_Clear( |
| const TPMI_RH_CLEAR& auth_handle, |
| const std::string& auth_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_Clear; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_CLEAR( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_Clear( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_Clear; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ClearErrorCallback( |
| const Tpm::ClearResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void ClearResponseParser( |
| const Tpm::ClearResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClearErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_Clear( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::Clear( |
| const TPMI_RH_CLEAR& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ClearResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClearErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ClearResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_Clear( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ClearSync( |
| const TPMI_RH_CLEAR& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_Clear( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_Clear( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ClearControl( |
| const TPMI_RH_CLEAR& auth, |
| const std::string& auth_name, |
| const TPMI_YES_NO& disable, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ClearControl; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_CLEAR( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string disable_bytes; |
| rc = Serialize_TPMI_YES_NO( |
| disable, |
| &disable_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(disable_bytes.data(), |
| disable_bytes.size()); |
| parameter_section_bytes += disable_bytes; |
| command_size += disable_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ClearControl( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ClearControl; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ClearControlErrorCallback( |
| const Tpm::ClearControlResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void ClearControlResponseParser( |
| const Tpm::ClearControlResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClearControlErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_ClearControl( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::ClearControl( |
| const TPMI_RH_CLEAR& auth, |
| const std::string& auth_name, |
| const TPMI_YES_NO& disable, |
| AuthorizationDelegate* authorization_delegate, |
| const ClearControlResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClearControlErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ClearControlResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClearControl( |
| auth, |
| auth_name, |
| disable, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ClearControlSync( |
| const TPMI_RH_CLEAR& auth, |
| const std::string& auth_name, |
| const TPMI_YES_NO& disable, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClearControl( |
| auth, |
| auth_name, |
| disable, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ClearControl( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth( |
| const TPMI_RH_HIERARCHY_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& new_auth, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_HierarchyChangeAuth; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_HIERARCHY_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| new_auth, |
| &new_auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = new_auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| new_auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(new_auth_bytes.data(), |
| new_auth_bytes.size()); |
| parameter_section_bytes += new_auth_bytes; |
| command_size += new_auth_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_HierarchyChangeAuth( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_HierarchyChangeAuth; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void HierarchyChangeAuthErrorCallback( |
| const Tpm::HierarchyChangeAuthResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void HierarchyChangeAuthResponseParser( |
| const Tpm::HierarchyChangeAuthResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HierarchyChangeAuthErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_HierarchyChangeAuth( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::HierarchyChangeAuth( |
| const TPMI_RH_HIERARCHY_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& new_auth, |
| AuthorizationDelegate* authorization_delegate, |
| const HierarchyChangeAuthResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(HierarchyChangeAuthErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(HierarchyChangeAuthResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_HierarchyChangeAuth( |
| auth_handle, |
| auth_handle_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::HierarchyChangeAuthSync( |
| const TPMI_RH_HIERARCHY_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& new_auth, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_HierarchyChangeAuth( |
| auth_handle, |
| auth_handle_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_HierarchyChangeAuth( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_DictionaryAttackLockReset; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string lock_handle_bytes; |
| rc = Serialize_TPMI_RH_LOCKOUT( |
| lock_handle, |
| &lock_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(lock_handle_name.data(), |
| lock_handle_name.size()); |
| handle_section_bytes += lock_handle_bytes; |
| command_size += lock_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_DictionaryAttackLockReset; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void DictionaryAttackLockResetErrorCallback( |
| const Tpm::DictionaryAttackLockResetResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void DictionaryAttackLockResetResponseParser( |
| const Tpm::DictionaryAttackLockResetResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DictionaryAttackLockResetErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::DictionaryAttackLockReset( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const DictionaryAttackLockResetResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DictionaryAttackLockResetErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(DictionaryAttackLockResetResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_DictionaryAttackLockReset( |
| lock_handle, |
| lock_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::DictionaryAttackLockResetSync( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_DictionaryAttackLockReset( |
| lock_handle, |
| lock_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_DictionaryAttackLockReset( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| const UINT32& new_max_tries, |
| const UINT32& new_recovery_time, |
| const UINT32& lockout_recovery, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_DictionaryAttackParameters; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string lock_handle_bytes; |
| rc = Serialize_TPMI_RH_LOCKOUT( |
| lock_handle, |
| &lock_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_max_tries_bytes; |
| rc = Serialize_UINT32( |
| new_max_tries, |
| &new_max_tries_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_recovery_time_bytes; |
| rc = Serialize_UINT32( |
| new_recovery_time, |
| &new_recovery_time_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string lockout_recovery_bytes; |
| rc = Serialize_UINT32( |
| lockout_recovery, |
| &lockout_recovery_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(lock_handle_name.data(), |
| lock_handle_name.size()); |
| handle_section_bytes += lock_handle_bytes; |
| command_size += lock_handle_bytes.size(); |
| hash->Update(new_max_tries_bytes.data(), |
| new_max_tries_bytes.size()); |
| parameter_section_bytes += new_max_tries_bytes; |
| command_size += new_max_tries_bytes.size(); |
| hash->Update(new_recovery_time_bytes.data(), |
| new_recovery_time_bytes.size()); |
| parameter_section_bytes += new_recovery_time_bytes; |
| command_size += new_recovery_time_bytes.size(); |
| hash->Update(lockout_recovery_bytes.data(), |
| lockout_recovery_bytes.size()); |
| parameter_section_bytes += lockout_recovery_bytes; |
| command_size += lockout_recovery_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_DictionaryAttackParameters( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_DictionaryAttackParameters; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void DictionaryAttackParametersErrorCallback( |
| const Tpm::DictionaryAttackParametersResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void DictionaryAttackParametersResponseParser( |
| const Tpm::DictionaryAttackParametersResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DictionaryAttackParametersErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::DictionaryAttackParameters( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| const UINT32& new_max_tries, |
| const UINT32& new_recovery_time, |
| const UINT32& lockout_recovery, |
| AuthorizationDelegate* authorization_delegate, |
| const DictionaryAttackParametersResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(DictionaryAttackParametersErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(DictionaryAttackParametersResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_DictionaryAttackParameters( |
| lock_handle, |
| lock_handle_name, |
| new_max_tries, |
| new_recovery_time, |
| lockout_recovery, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::DictionaryAttackParametersSync( |
| const TPMI_RH_LOCKOUT& lock_handle, |
| const std::string& lock_handle_name, |
| const UINT32& new_max_tries, |
| const UINT32& new_recovery_time, |
| const UINT32& lockout_recovery, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_DictionaryAttackParameters( |
| lock_handle, |
| lock_handle_name, |
| new_max_tries, |
| new_recovery_time, |
| lockout_recovery, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_DictionaryAttackParameters( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_PP_Commands( |
| const TPMI_RH_PLATFORM& auth, |
| const std::string& auth_name, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_PP_Commands; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string set_list_bytes; |
| rc = Serialize_TPML_CC( |
| set_list, |
| &set_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string clear_list_bytes; |
| rc = Serialize_TPML_CC( |
| clear_list, |
| &clear_list_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(set_list_bytes.data(), |
| set_list_bytes.size()); |
| parameter_section_bytes += set_list_bytes; |
| command_size += set_list_bytes.size(); |
| hash->Update(clear_list_bytes.data(), |
| clear_list_bytes.size()); |
| parameter_section_bytes += clear_list_bytes; |
| command_size += clear_list_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_PP_Commands( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_PP_Commands; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void PP_CommandsErrorCallback( |
| const Tpm::PP_CommandsResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void PP_CommandsResponseParser( |
| const Tpm::PP_CommandsResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PP_CommandsErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_PP_Commands( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::PP_Commands( |
| const TPMI_RH_PLATFORM& auth, |
| const std::string& auth_name, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| AuthorizationDelegate* authorization_delegate, |
| const PP_CommandsResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(PP_CommandsErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(PP_CommandsResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_PP_Commands( |
| auth, |
| auth_name, |
| set_list, |
| clear_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::PP_CommandsSync( |
| const TPMI_RH_PLATFORM& auth, |
| const std::string& auth_name, |
| const TPML_CC& set_list, |
| const TPML_CC& clear_list, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_PP_Commands( |
| auth, |
| auth_name, |
| set_list, |
| clear_list, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_PP_Commands( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_SetAlgorithmSet( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const UINT32& algorithm_set, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_SetAlgorithmSet; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string algorithm_set_bytes; |
| rc = Serialize_UINT32( |
| algorithm_set, |
| &algorithm_set_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(algorithm_set_bytes.data(), |
| algorithm_set_bytes.size()); |
| parameter_section_bytes += algorithm_set_bytes; |
| command_size += algorithm_set_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_SetAlgorithmSet( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_SetAlgorithmSet; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void SetAlgorithmSetErrorCallback( |
| const Tpm::SetAlgorithmSetResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void SetAlgorithmSetResponseParser( |
| const Tpm::SetAlgorithmSetResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetAlgorithmSetErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_SetAlgorithmSet( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::SetAlgorithmSet( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const UINT32& algorithm_set, |
| AuthorizationDelegate* authorization_delegate, |
| const SetAlgorithmSetResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(SetAlgorithmSetErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(SetAlgorithmSetResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetAlgorithmSet( |
| auth_handle, |
| auth_handle_name, |
| algorithm_set, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::SetAlgorithmSetSync( |
| const TPMI_RH_PLATFORM& auth_handle, |
| const std::string& auth_handle_name, |
| const UINT32& algorithm_set, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_SetAlgorithmSet( |
| auth_handle, |
| auth_handle_name, |
| algorithm_set, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_SetAlgorithmSet( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_FieldUpgradeStart( |
| const TPMI_RH_PLATFORM& authorization, |
| const std::string& authorization_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& fu_digest, |
| const TPMT_SIGNATURE& manifest_signature, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_FieldUpgradeStart; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| authorization, |
| &authorization_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string key_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| key_handle, |
| &key_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string fu_digest_bytes; |
| rc = Serialize_TPM2B_DIGEST( |
| fu_digest, |
| &fu_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string manifest_signature_bytes; |
| rc = Serialize_TPMT_SIGNATURE( |
| manifest_signature, |
| &manifest_signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = fu_digest_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| fu_digest_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(authorization_name.data(), |
| authorization_name.size()); |
| handle_section_bytes += authorization_bytes; |
| command_size += authorization_bytes.size(); |
| hash->Update(key_handle_name.data(), |
| key_handle_name.size()); |
| handle_section_bytes += key_handle_bytes; |
| command_size += key_handle_bytes.size(); |
| hash->Update(fu_digest_bytes.data(), |
| fu_digest_bytes.size()); |
| parameter_section_bytes += fu_digest_bytes; |
| command_size += fu_digest_bytes.size(); |
| hash->Update(manifest_signature_bytes.data(), |
| manifest_signature_bytes.size()); |
| parameter_section_bytes += manifest_signature_bytes; |
| command_size += manifest_signature_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_FieldUpgradeStart( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_FieldUpgradeStart; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void FieldUpgradeStartErrorCallback( |
| const Tpm::FieldUpgradeStartResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void FieldUpgradeStartResponseParser( |
| const Tpm::FieldUpgradeStartResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FieldUpgradeStartErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_FieldUpgradeStart( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::FieldUpgradeStart( |
| const TPMI_RH_PLATFORM& authorization, |
| const std::string& authorization_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& fu_digest, |
| const TPMT_SIGNATURE& manifest_signature, |
| AuthorizationDelegate* authorization_delegate, |
| const FieldUpgradeStartResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FieldUpgradeStartErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(FieldUpgradeStartResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_FieldUpgradeStart( |
| authorization, |
| authorization_name, |
| key_handle, |
| key_handle_name, |
| fu_digest, |
| manifest_signature, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::FieldUpgradeStartSync( |
| const TPMI_RH_PLATFORM& authorization, |
| const std::string& authorization_name, |
| const TPMI_DH_OBJECT& key_handle, |
| const std::string& key_handle_name, |
| const TPM2B_DIGEST& fu_digest, |
| const TPMT_SIGNATURE& manifest_signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_FieldUpgradeStart( |
| authorization, |
| authorization_name, |
| key_handle, |
| key_handle_name, |
| fu_digest, |
| manifest_signature, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_FieldUpgradeStart( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_FieldUpgradeData( |
| const TPM2B_MAX_BUFFER& fu_data, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_FieldUpgradeData; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string fu_data_bytes; |
| rc = Serialize_TPM2B_MAX_BUFFER( |
| fu_data, |
| &fu_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = fu_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| fu_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(fu_data_bytes.data(), |
| fu_data_bytes.size()); |
| parameter_section_bytes += fu_data_bytes; |
| command_size += fu_data_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_FieldUpgradeData( |
| const std::string& response, |
| TPMT_HA* next_digest, |
| TPMT_HA* first_digest, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_FieldUpgradeData; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string next_digest_bytes; |
| rc = Parse_TPMT_HA( |
| &buffer, |
| next_digest, |
| &next_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string first_digest_bytes; |
| rc = Parse_TPMT_HA( |
| &buffer, |
| first_digest, |
| &first_digest_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void FieldUpgradeDataErrorCallback( |
| const Tpm::FieldUpgradeDataResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMT_HA(), |
| TPMT_HA()); |
| } |
| |
| void FieldUpgradeDataResponseParser( |
| const Tpm::FieldUpgradeDataResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FieldUpgradeDataErrorCallback, callback); |
| TPMT_HA next_digest; |
| TPMT_HA first_digest; |
| TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData( |
| response, |
| &next_digest, |
| &first_digest, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| next_digest, |
| first_digest); |
| } |
| |
| void Tpm::FieldUpgradeData( |
| const TPM2B_MAX_BUFFER& fu_data, |
| AuthorizationDelegate* authorization_delegate, |
| const FieldUpgradeDataResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FieldUpgradeDataErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(FieldUpgradeDataResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_FieldUpgradeData( |
| fu_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::FieldUpgradeDataSync( |
| const TPM2B_MAX_BUFFER& fu_data, |
| TPMT_HA* next_digest, |
| TPMT_HA* first_digest, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_FieldUpgradeData( |
| fu_data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_FieldUpgradeData( |
| response, |
| next_digest, |
| first_digest, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_FirmwareRead( |
| const UINT32& sequence_number, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_FirmwareRead; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sequence_number_bytes; |
| rc = Serialize_UINT32( |
| sequence_number, |
| &sequence_number_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sequence_number_bytes.data(), |
| sequence_number_bytes.size()); |
| parameter_section_bytes += sequence_number_bytes; |
| command_size += sequence_number_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_FirmwareRead( |
| const std::string& response, |
| TPM2B_MAX_BUFFER* fu_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_FirmwareRead; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string fu_data_bytes; |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &buffer, |
| fu_data, |
| &fu_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = fu_data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| fu_data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_MAX_BUFFER( |
| &fu_data_bytes, |
| fu_data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void FirmwareReadErrorCallback( |
| const Tpm::FirmwareReadResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_MAX_BUFFER()); |
| } |
| |
| void FirmwareReadResponseParser( |
| const Tpm::FirmwareReadResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FirmwareReadErrorCallback, callback); |
| TPM2B_MAX_BUFFER fu_data; |
| TPM_RC rc = Tpm::ParseResponse_FirmwareRead( |
| response, |
| &fu_data, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| fu_data); |
| } |
| |
| void Tpm::FirmwareRead( |
| const UINT32& sequence_number, |
| AuthorizationDelegate* authorization_delegate, |
| const FirmwareReadResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FirmwareReadErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(FirmwareReadResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_FirmwareRead( |
| sequence_number, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::FirmwareReadSync( |
| const UINT32& sequence_number, |
| TPM2B_MAX_BUFFER* fu_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_FirmwareRead( |
| sequence_number, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_FirmwareRead( |
| response, |
| fu_data, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ContextSave( |
| const TPMI_DH_CONTEXT& save_handle, |
| const std::string& save_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ContextSave; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string save_handle_bytes; |
| rc = Serialize_TPMI_DH_CONTEXT( |
| save_handle, |
| &save_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(save_handle_name.data(), |
| save_handle_name.size()); |
| handle_section_bytes += save_handle_bytes; |
| command_size += save_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ContextSave( |
| const std::string& response, |
| TPMS_CONTEXT* context, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ContextSave; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string context_bytes; |
| rc = Parse_TPMS_CONTEXT( |
| &buffer, |
| context, |
| &context_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ContextSaveErrorCallback( |
| const Tpm::ContextSaveResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMS_CONTEXT()); |
| } |
| |
| void ContextSaveResponseParser( |
| const Tpm::ContextSaveResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ContextSaveErrorCallback, callback); |
| TPMS_CONTEXT context; |
| TPM_RC rc = Tpm::ParseResponse_ContextSave( |
| response, |
| &context, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| context); |
| } |
| |
| void Tpm::ContextSave( |
| const TPMI_DH_CONTEXT& save_handle, |
| const std::string& save_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const ContextSaveResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ContextSaveErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ContextSaveResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ContextSave( |
| save_handle, |
| save_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ContextSaveSync( |
| const TPMI_DH_CONTEXT& save_handle, |
| const std::string& save_handle_name, |
| TPMS_CONTEXT* context, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ContextSave( |
| save_handle, |
| save_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ContextSave( |
| response, |
| context, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ContextLoad( |
| const TPMS_CONTEXT& context, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ContextLoad; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string context_bytes; |
| rc = Serialize_TPMS_CONTEXT( |
| context, |
| &context_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(context_bytes.data(), |
| context_bytes.size()); |
| parameter_section_bytes += context_bytes; |
| command_size += context_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ContextLoad( |
| const std::string& response, |
| TPMI_DH_CONTEXT* loaded_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| std::string loaded_handle_bytes; |
| rc = Parse_TPMI_DH_CONTEXT( |
| &buffer, |
| loaded_handle, |
| &loaded_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_CC command_code = TPM_CC_ContextLoad; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ContextLoadErrorCallback( |
| const Tpm::ContextLoadResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_DH_CONTEXT()); |
| } |
| |
| void ContextLoadResponseParser( |
| const Tpm::ContextLoadResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ContextLoadErrorCallback, callback); |
| TPMI_DH_CONTEXT loaded_handle; |
| TPM_RC rc = Tpm::ParseResponse_ContextLoad( |
| response, |
| &loaded_handle, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| loaded_handle); |
| } |
| |
| void Tpm::ContextLoad( |
| const TPMS_CONTEXT& context, |
| AuthorizationDelegate* authorization_delegate, |
| const ContextLoadResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ContextLoadErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ContextLoadResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ContextLoad( |
| context, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ContextLoadSync( |
| const TPMS_CONTEXT& context, |
| TPMI_DH_CONTEXT* loaded_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ContextLoad( |
| context, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ContextLoad( |
| response, |
| loaded_handle, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_FlushContext( |
| const TPMI_DH_CONTEXT& flush_handle, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_FlushContext; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string flush_handle_bytes; |
| rc = Serialize_TPMI_DH_CONTEXT( |
| flush_handle, |
| &flush_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(flush_handle_bytes.data(), |
| flush_handle_bytes.size()); |
| parameter_section_bytes += flush_handle_bytes; |
| command_size += flush_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_FlushContext( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_FlushContext; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void FlushContextErrorCallback( |
| const Tpm::FlushContextResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void FlushContextResponseParser( |
| const Tpm::FlushContextResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FlushContextErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_FlushContext( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::FlushContext( |
| const TPMI_DH_CONTEXT& flush_handle, |
| AuthorizationDelegate* authorization_delegate, |
| const FlushContextResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(FlushContextErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(FlushContextResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_FlushContext( |
| flush_handle, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::FlushContextSync( |
| const TPMI_DH_CONTEXT& flush_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_FlushContext( |
| flush_handle, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_FlushContext( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_EvictControl( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_PERSISTENT& persistent_handle, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_EvictControl; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string object_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| object_handle, |
| &object_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string persistent_handle_bytes; |
| rc = Serialize_TPMI_DH_PERSISTENT( |
| persistent_handle, |
| &persistent_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(object_handle_name.data(), |
| object_handle_name.size()); |
| handle_section_bytes += object_handle_bytes; |
| command_size += object_handle_bytes.size(); |
| hash->Update(persistent_handle_bytes.data(), |
| persistent_handle_bytes.size()); |
| parameter_section_bytes += persistent_handle_bytes; |
| command_size += persistent_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_EvictControl( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_EvictControl; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void EvictControlErrorCallback( |
| const Tpm::EvictControlResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void EvictControlResponseParser( |
| const Tpm::EvictControlResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EvictControlErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_EvictControl( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::EvictControl( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_PERSISTENT& persistent_handle, |
| AuthorizationDelegate* authorization_delegate, |
| const EvictControlResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(EvictControlErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(EvictControlResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_EvictControl( |
| auth, |
| auth_name, |
| object_handle, |
| object_handle_name, |
| persistent_handle, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::EvictControlSync( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPMI_DH_OBJECT& object_handle, |
| const std::string& object_handle_name, |
| const TPMI_DH_PERSISTENT& persistent_handle, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_EvictControl( |
| auth, |
| auth_name, |
| object_handle, |
| object_handle_name, |
| persistent_handle, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_EvictControl( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ReadClock( |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ReadClock; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ReadClock( |
| const std::string& response, |
| TPM_RC* return_code, |
| TPMS_TIME_INFO* current_time, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ReadClock; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string return_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| return_code, |
| &return_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string current_time_bytes; |
| rc = Parse_TPMS_TIME_INFO( |
| &buffer, |
| current_time, |
| ¤t_time_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ReadClockErrorCallback( |
| const Tpm::ReadClockResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_RC(), |
| TPMS_TIME_INFO()); |
| } |
| |
| void ReadClockResponseParser( |
| const Tpm::ReadClockResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ReadClockErrorCallback, callback); |
| TPM_RC return_code; |
| TPMS_TIME_INFO current_time; |
| TPM_RC rc = Tpm::ParseResponse_ReadClock( |
| response, |
| &return_code, |
| ¤t_time, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| return_code, |
| current_time); |
| } |
| |
| void Tpm::ReadClock( |
| AuthorizationDelegate* authorization_delegate, |
| const ReadClockResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ReadClockErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ReadClockResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ReadClock( |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ReadClockSync( |
| TPM_RC* return_code, |
| TPMS_TIME_INFO* current_time, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ReadClock( |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ReadClock( |
| response, |
| return_code, |
| current_time, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ClockSet( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const UINT64& new_time, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ClockSet; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_time_bytes; |
| rc = Serialize_UINT64( |
| new_time, |
| &new_time_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(new_time_bytes.data(), |
| new_time_bytes.size()); |
| parameter_section_bytes += new_time_bytes; |
| command_size += new_time_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ClockSet( |
| const std::string& response, |
| TPM_RC* return_code, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ClockSet; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string return_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| return_code, |
| &return_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ClockSetErrorCallback( |
| const Tpm::ClockSetResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_RC()); |
| } |
| |
| void ClockSetResponseParser( |
| const Tpm::ClockSetResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClockSetErrorCallback, callback); |
| TPM_RC return_code; |
| TPM_RC rc = Tpm::ParseResponse_ClockSet( |
| response, |
| &return_code, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| return_code); |
| } |
| |
| void Tpm::ClockSet( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const UINT64& new_time, |
| AuthorizationDelegate* authorization_delegate, |
| const ClockSetResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClockSetErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ClockSetResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClockSet( |
| auth, |
| auth_name, |
| new_time, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ClockSetSync( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const UINT64& new_time, |
| TPM_RC* return_code, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClockSet( |
| auth, |
| auth_name, |
| new_time, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ClockSet( |
| response, |
| return_code, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_ClockRateAdjust( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPM_CLOCK_ADJUST& rate_adjust, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_ClockRateAdjust; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string rate_adjust_bytes; |
| rc = Serialize_TPM_CLOCK_ADJUST( |
| rate_adjust, |
| &rate_adjust_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_name.data(), |
| auth_name.size()); |
| handle_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(rate_adjust_bytes.data(), |
| rate_adjust_bytes.size()); |
| parameter_section_bytes += rate_adjust_bytes; |
| command_size += rate_adjust_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_ClockRateAdjust( |
| const std::string& response, |
| TPM_RC* return_code, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_ClockRateAdjust; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string return_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| return_code, |
| &return_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void ClockRateAdjustErrorCallback( |
| const Tpm::ClockRateAdjustResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM_RC()); |
| } |
| |
| void ClockRateAdjustResponseParser( |
| const Tpm::ClockRateAdjustResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClockRateAdjustErrorCallback, callback); |
| TPM_RC return_code; |
| TPM_RC rc = Tpm::ParseResponse_ClockRateAdjust( |
| response, |
| &return_code, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| return_code); |
| } |
| |
| void Tpm::ClockRateAdjust( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPM_CLOCK_ADJUST& rate_adjust, |
| AuthorizationDelegate* authorization_delegate, |
| const ClockRateAdjustResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(ClockRateAdjustErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(ClockRateAdjustResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClockRateAdjust( |
| auth, |
| auth_name, |
| rate_adjust, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::ClockRateAdjustSync( |
| const TPMI_RH_PROVISION& auth, |
| const std::string& auth_name, |
| const TPM_CLOCK_ADJUST& rate_adjust, |
| TPM_RC* return_code, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_ClockRateAdjust( |
| auth, |
| auth_name, |
| rate_adjust, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_ClockRateAdjust( |
| response, |
| return_code, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_GetCapability( |
| const TPM_CAP& capability, |
| const UINT32& property, |
| const UINT32& property_count, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_GetCapability; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string capability_bytes; |
| rc = Serialize_TPM_CAP( |
| capability, |
| &capability_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string property_bytes; |
| rc = Serialize_UINT32( |
| property, |
| &property_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string property_count_bytes; |
| rc = Serialize_UINT32( |
| property_count, |
| &property_count_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(capability_bytes.data(), |
| capability_bytes.size()); |
| parameter_section_bytes += capability_bytes; |
| command_size += capability_bytes.size(); |
| hash->Update(property_bytes.data(), |
| property_bytes.size()); |
| parameter_section_bytes += property_bytes; |
| command_size += property_bytes.size(); |
| hash->Update(property_count_bytes.data(), |
| property_count_bytes.size()); |
| parameter_section_bytes += property_count_bytes; |
| command_size += property_count_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_GetCapability( |
| const std::string& response, |
| TPMI_YES_NO* more_data, |
| TPMS_CAPABILITY_DATA* capability_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_GetCapability; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string more_data_bytes; |
| rc = Parse_TPMI_YES_NO( |
| &buffer, |
| more_data, |
| &more_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string capability_data_bytes; |
| rc = Parse_TPMS_CAPABILITY_DATA( |
| &buffer, |
| capability_data, |
| &capability_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void GetCapabilityErrorCallback( |
| const Tpm::GetCapabilityResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPMI_YES_NO(), |
| TPMS_CAPABILITY_DATA()); |
| } |
| |
| void GetCapabilityResponseParser( |
| const Tpm::GetCapabilityResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetCapabilityErrorCallback, callback); |
| TPMI_YES_NO more_data; |
| TPMS_CAPABILITY_DATA capability_data; |
| TPM_RC rc = Tpm::ParseResponse_GetCapability( |
| response, |
| &more_data, |
| &capability_data, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| more_data, |
| capability_data); |
| } |
| |
| void Tpm::GetCapability( |
| const TPM_CAP& capability, |
| const UINT32& property, |
| const UINT32& property_count, |
| AuthorizationDelegate* authorization_delegate, |
| const GetCapabilityResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(GetCapabilityErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(GetCapabilityResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetCapability( |
| capability, |
| property, |
| property_count, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::GetCapabilitySync( |
| const TPM_CAP& capability, |
| const UINT32& property, |
| const UINT32& property_count, |
| TPMI_YES_NO* more_data, |
| TPMS_CAPABILITY_DATA* capability_data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_GetCapability( |
| capability, |
| property, |
| property_count, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_GetCapability( |
| response, |
| more_data, |
| capability_data, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_TestParms( |
| const TPMT_PUBLIC_PARMS& parameters, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_TestParms; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string parameters_bytes; |
| rc = Serialize_TPMT_PUBLIC_PARMS( |
| parameters, |
| ¶meters_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(parameters_bytes.data(), |
| parameters_bytes.size()); |
| parameter_section_bytes += parameters_bytes; |
| command_size += parameters_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_TestParms( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_TestParms; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void TestParmsErrorCallback( |
| const Tpm::TestParmsResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void TestParmsResponseParser( |
| const Tpm::TestParmsResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(TestParmsErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_TestParms( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::TestParms( |
| const TPMT_PUBLIC_PARMS& parameters, |
| AuthorizationDelegate* authorization_delegate, |
| const TestParmsResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(TestParmsErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(TestParmsResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_TestParms( |
| parameters, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::TestParmsSync( |
| const TPMT_PUBLIC_PARMS& parameters, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_TestParms( |
| parameters, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_TestParms( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_DefineSpace( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& auth, |
| const TPM2B_NV_PUBLIC& public_info, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_DefineSpace; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| auth, |
| &auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string public_info_bytes; |
| rc = Serialize_TPM2B_NV_PUBLIC( |
| public_info, |
| &public_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(auth_bytes.data(), |
| auth_bytes.size()); |
| parameter_section_bytes += auth_bytes; |
| command_size += auth_bytes.size(); |
| hash->Update(public_info_bytes.data(), |
| public_info_bytes.size()); |
| parameter_section_bytes += public_info_bytes; |
| command_size += public_info_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_DefineSpace( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_DefineSpace; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_DefineSpaceErrorCallback( |
| const Tpm::NV_DefineSpaceResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_DefineSpaceResponseParser( |
| const Tpm::NV_DefineSpaceResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_DefineSpaceErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_DefineSpace( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_DefineSpace( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& auth, |
| const TPM2B_NV_PUBLIC& public_info, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_DefineSpaceResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_DefineSpaceErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_DefineSpaceResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_DefineSpace( |
| auth_handle, |
| auth_handle_name, |
| auth, |
| public_info, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_DefineSpaceSync( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPM2B_AUTH& auth, |
| const TPM2B_NV_PUBLIC& public_info, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_DefineSpace( |
| auth_handle, |
| auth_handle_name, |
| auth, |
| public_info, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_DefineSpace( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_UndefineSpace( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_UndefineSpace; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_UndefineSpace( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_UndefineSpace; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_UndefineSpaceErrorCallback( |
| const Tpm::NV_UndefineSpaceResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_UndefineSpaceResponseParser( |
| const Tpm::NV_UndefineSpaceResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_UndefineSpaceErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpace( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_UndefineSpace( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_UndefineSpaceResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_UndefineSpaceErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_UndefineSpaceResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_UndefineSpace( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_UndefineSpaceSync( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_UndefineSpace( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_UndefineSpace( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_RH_PLATFORM& platform, |
| const std::string& platform_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string platform_bytes; |
| rc = Serialize_TPMI_RH_PLATFORM( |
| platform, |
| &platform_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(platform_name.data(), |
| platform_name.size()); |
| handle_section_bytes += platform_bytes; |
| command_size += platform_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_UndefineSpaceSpecialErrorCallback( |
| const Tpm::NV_UndefineSpaceSpecialResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_UndefineSpaceSpecialResponseParser( |
| const Tpm::NV_UndefineSpaceSpecialResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_UndefineSpaceSpecialErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_UndefineSpaceSpecial( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_RH_PLATFORM& platform, |
| const std::string& platform_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_UndefineSpaceSpecialResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_UndefineSpaceSpecialErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_UndefineSpaceSpecialResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial( |
| nv_index, |
| nv_index_name, |
| platform, |
| platform_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_UndefineSpaceSpecialSync( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPMI_RH_PLATFORM& platform, |
| const std::string& platform_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial( |
| nv_index, |
| nv_index_name, |
| platform, |
| platform_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_UndefineSpaceSpecial( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_ReadPublic( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_ReadPublic; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_ReadPublic( |
| const std::string& response, |
| TPM2B_NV_PUBLIC* nv_public, |
| TPM2B_NAME* nv_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_ReadPublic; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string nv_public_bytes; |
| rc = Parse_TPM2B_NV_PUBLIC( |
| &buffer, |
| nv_public, |
| &nv_public_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_name_bytes; |
| rc = Parse_TPM2B_NAME( |
| &buffer, |
| nv_name, |
| &nv_name_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = nv_public_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| nv_public_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_NV_PUBLIC( |
| &nv_public_bytes, |
| nv_public, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_ReadPublicErrorCallback( |
| const Tpm::NV_ReadPublicResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_NV_PUBLIC(), |
| TPM2B_NAME()); |
| } |
| |
| void NV_ReadPublicResponseParser( |
| const Tpm::NV_ReadPublicResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadPublicErrorCallback, callback); |
| TPM2B_NV_PUBLIC nv_public; |
| TPM2B_NAME nv_name; |
| TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic( |
| response, |
| &nv_public, |
| &nv_name, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| nv_public, |
| nv_name); |
| } |
| |
| void Tpm::NV_ReadPublic( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_ReadPublicResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadPublicErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_ReadPublicResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ReadPublic( |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_ReadPublicSync( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| TPM2B_NV_PUBLIC* nv_public, |
| TPM2B_NAME* nv_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ReadPublic( |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_ReadPublic( |
| response, |
| nv_public, |
| nv_name, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_Write( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| const UINT16& offset, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_Write; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string data_bytes; |
| rc = Serialize_TPM2B_MAX_NV_BUFFER( |
| data, |
| &data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string offset_bytes; |
| rc = Serialize_UINT16( |
| offset, |
| &offset_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(data_bytes.data(), |
| data_bytes.size()); |
| parameter_section_bytes += data_bytes; |
| command_size += data_bytes.size(); |
| hash->Update(offset_bytes.data(), |
| offset_bytes.size()); |
| parameter_section_bytes += offset_bytes; |
| command_size += offset_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_Write( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_Write; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_WriteErrorCallback( |
| const Tpm::NV_WriteResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_WriteResponseParser( |
| const Tpm::NV_WriteResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_WriteErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_Write( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_Write( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| const UINT16& offset, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_WriteResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_WriteErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_WriteResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Write( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| data, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_WriteSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| const UINT16& offset, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Write( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| data, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_Write( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_Increment( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_Increment; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_Increment( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_Increment; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_IncrementErrorCallback( |
| const Tpm::NV_IncrementResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_IncrementResponseParser( |
| const Tpm::NV_IncrementResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_IncrementErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_Increment( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_Increment( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_IncrementResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_IncrementErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_IncrementResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Increment( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_IncrementSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Increment( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_Increment( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_Extend( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_Extend; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string data_bytes; |
| rc = Serialize_TPM2B_MAX_NV_BUFFER( |
| data, |
| &data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(data_bytes.data(), |
| data_bytes.size()); |
| parameter_section_bytes += data_bytes; |
| command_size += data_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_Extend( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_Extend; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_ExtendErrorCallback( |
| const Tpm::NV_ExtendResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_ExtendResponseParser( |
| const Tpm::NV_ExtendResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ExtendErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_Extend( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_Extend( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_ExtendResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ExtendErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_ExtendResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Extend( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_ExtendSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_MAX_NV_BUFFER& data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Extend( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| data, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_Extend( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_SetBits( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT64& bits, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_SetBits; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string bits_bytes; |
| rc = Serialize_UINT64( |
| bits, |
| &bits_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(bits_bytes.data(), |
| bits_bytes.size()); |
| parameter_section_bytes += bits_bytes; |
| command_size += bits_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_SetBits( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_SetBits; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_SetBitsErrorCallback( |
| const Tpm::NV_SetBitsResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_SetBitsResponseParser( |
| const Tpm::NV_SetBitsResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_SetBitsErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_SetBits( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_SetBits( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT64& bits, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_SetBitsResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_SetBitsErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_SetBitsResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_SetBits( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| bits, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_SetBitsSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT64& bits, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_SetBits( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| bits, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_SetBits( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_WriteLock( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_WriteLock; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_WriteLock( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_WriteLock; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_WriteLockErrorCallback( |
| const Tpm::NV_WriteLockResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_WriteLockResponseParser( |
| const Tpm::NV_WriteLockResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_WriteLockErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_WriteLock( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_WriteLock( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_WriteLockResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_WriteLockErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_WriteLockResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_WriteLock( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_WriteLockSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_WriteLock( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_WriteLock( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_GlobalWriteLock; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_PROVISION( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_GlobalWriteLock; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_GlobalWriteLockErrorCallback( |
| const Tpm::NV_GlobalWriteLockResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_GlobalWriteLockResponseParser( |
| const Tpm::NV_GlobalWriteLockResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_GlobalWriteLockErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_GlobalWriteLock( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_GlobalWriteLock( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_GlobalWriteLockResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_GlobalWriteLockErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_GlobalWriteLockResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_GlobalWriteLock( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_GlobalWriteLockSync( |
| const TPMI_RH_PROVISION& auth_handle, |
| const std::string& auth_handle_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_GlobalWriteLock( |
| auth_handle, |
| auth_handle_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_GlobalWriteLock( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_Read( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT16& size, |
| const UINT16& offset, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_Read; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string size_bytes; |
| rc = Serialize_UINT16( |
| size, |
| &size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string offset_bytes; |
| rc = Serialize_UINT16( |
| offset, |
| &offset_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(size_bytes.data(), |
| size_bytes.size()); |
| parameter_section_bytes += size_bytes; |
| command_size += size_bytes.size(); |
| hash->Update(offset_bytes.data(), |
| offset_bytes.size()); |
| parameter_section_bytes += offset_bytes; |
| command_size += offset_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_Read( |
| const std::string& response, |
| TPM2B_MAX_NV_BUFFER* data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_Read; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string data_bytes; |
| rc = Parse_TPM2B_MAX_NV_BUFFER( |
| &buffer, |
| data, |
| &data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = data_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| data_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_MAX_NV_BUFFER( |
| &data_bytes, |
| data, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_ReadErrorCallback( |
| const Tpm::NV_ReadResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_MAX_NV_BUFFER()); |
| } |
| |
| void NV_ReadResponseParser( |
| const Tpm::NV_ReadResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadErrorCallback, callback); |
| TPM2B_MAX_NV_BUFFER data; |
| TPM_RC rc = Tpm::ParseResponse_NV_Read( |
| response, |
| &data, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| data); |
| } |
| |
| void Tpm::NV_Read( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT16& size, |
| const UINT16& offset, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_ReadResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_ReadResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Read( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| size, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_ReadSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const UINT16& size, |
| const UINT16& offset, |
| TPM2B_MAX_NV_BUFFER* data, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Read( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| size, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_Read( |
| response, |
| data, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_ReadLock( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_ReadLock; |
| bool is_command_parameter_encryption_possible = false; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_ReadLock( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_ReadLock; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_ReadLockErrorCallback( |
| const Tpm::NV_ReadLockResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_ReadLockResponseParser( |
| const Tpm::NV_ReadLockResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadLockErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_ReadLock( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_ReadLock( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_ReadLockResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ReadLockErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_ReadLockResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ReadLock( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_ReadLockSync( |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ReadLock( |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_ReadLock( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_ChangeAuth( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_AUTH& new_auth, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_ChangeAuth; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = false; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string new_auth_bytes; |
| rc = Serialize_TPM2B_AUTH( |
| new_auth, |
| &new_auth_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = new_auth_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| new_auth_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(new_auth_bytes.data(), |
| new_auth_bytes.size()); |
| parameter_section_bytes += new_auth_bytes; |
| command_size += new_auth_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_ChangeAuth( |
| const std::string& response, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_ChangeAuth; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_ChangeAuthErrorCallback( |
| const Tpm::NV_ChangeAuthResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code); |
| } |
| |
| void NV_ChangeAuthResponseParser( |
| const Tpm::NV_ChangeAuthResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ChangeAuthErrorCallback, callback); |
| TPM_RC rc = Tpm::ParseResponse_NV_ChangeAuth( |
| response, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc); |
| } |
| |
| void Tpm::NV_ChangeAuth( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_AUTH& new_auth, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_ChangeAuthResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_ChangeAuthErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_ChangeAuthResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ChangeAuth( |
| nv_index, |
| nv_index_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_ChangeAuthSync( |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_AUTH& new_auth, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_ChangeAuth( |
| nv_index, |
| nv_index_name, |
| new_auth, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_ChangeAuth( |
| response, |
| authorization_delegate); |
| return rc; |
| } |
| |
| TPM_RC Tpm::SerializeCommand_NV_Certify( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const UINT16& size, |
| const UINT16& offset, |
| std::string* serialized_command, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| TPM_RC rc = TPM_RC_SUCCESS; |
| TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS; |
| UINT32 command_size = 10; // Header size. |
| std::string handle_section_bytes; |
| std::string parameter_section_bytes; |
| TPM_CC command_code = TPM_CC_NV_Certify; |
| bool is_command_parameter_encryption_possible = true; |
| bool is_response_parameter_encryption_possible = true; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string sign_handle_bytes; |
| rc = Serialize_TPMI_DH_OBJECT( |
| sign_handle, |
| &sign_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string auth_handle_bytes; |
| rc = Serialize_TPMI_RH_NV_AUTH( |
| auth_handle, |
| &auth_handle_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string nv_index_bytes; |
| rc = Serialize_TPMI_RH_NV_INDEX( |
| nv_index, |
| &nv_index_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string qualifying_data_bytes; |
| rc = Serialize_TPM2B_DATA( |
| qualifying_data, |
| &qualifying_data_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string in_scheme_bytes; |
| rc = Serialize_TPMT_SIG_SCHEME( |
| in_scheme, |
| &in_scheme_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string size_bytes; |
| rc = Serialize_UINT16( |
| size, |
| &size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string offset_bytes; |
| rc = Serialize_UINT16( |
| offset, |
| &offset_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (authorization_delegate) { |
| // Encrypt just the parameter data, not the size. |
| std::string tmp = qualifying_data_bytes.substr(2); |
| if (!authorization_delegate->EncryptCommandParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| qualifying_data_bytes.replace(2, std::string::npos, tmp); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(sign_handle_name.data(), |
| sign_handle_name.size()); |
| handle_section_bytes += sign_handle_bytes; |
| command_size += sign_handle_bytes.size(); |
| hash->Update(auth_handle_name.data(), |
| auth_handle_name.size()); |
| handle_section_bytes += auth_handle_bytes; |
| command_size += auth_handle_bytes.size(); |
| hash->Update(nv_index_name.data(), |
| nv_index_name.size()); |
| handle_section_bytes += nv_index_bytes; |
| command_size += nv_index_bytes.size(); |
| hash->Update(qualifying_data_bytes.data(), |
| qualifying_data_bytes.size()); |
| parameter_section_bytes += qualifying_data_bytes; |
| command_size += qualifying_data_bytes.size(); |
| hash->Update(in_scheme_bytes.data(), |
| in_scheme_bytes.size()); |
| parameter_section_bytes += in_scheme_bytes; |
| command_size += in_scheme_bytes.size(); |
| hash->Update(size_bytes.data(), |
| size_bytes.size()); |
| parameter_section_bytes += size_bytes; |
| command_size += size_bytes.size(); |
| hash->Update(offset_bytes.data(), |
| offset_bytes.size()); |
| parameter_section_bytes += offset_bytes; |
| command_size += offset_bytes.size(); |
| std::string command_hash(32, 0); |
| hash->Finish(string_as_array(&command_hash), command_hash.size()); |
| std::string authorization_section_bytes; |
| std::string authorization_size_bytes; |
| if (authorization_delegate) { |
| if (!authorization_delegate->GetCommandAuthorization( |
| command_hash, |
| is_command_parameter_encryption_possible, |
| is_response_parameter_encryption_possible, |
| &authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| if (!authorization_section_bytes.empty()) { |
| tag = TPM_ST_SESSIONS; |
| std::string tmp; |
| rc = Serialize_UINT32(authorization_section_bytes.size(), |
| &authorization_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| command_size += authorization_size_bytes.size() + |
| authorization_section_bytes.size(); |
| } |
| } |
| std::string tag_bytes; |
| rc = Serialize_TPMI_ST_COMMAND_TAG( |
| tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string command_size_bytes; |
| rc = Serialize_UINT32( |
| command_size, |
| &command_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| *serialized_command = tag_bytes + |
| command_size_bytes + |
| command_code_bytes + |
| handle_section_bytes + |
| authorization_size_bytes + |
| authorization_section_bytes + |
| parameter_section_bytes; |
| CHECK(serialized_command->size() == command_size) << "Command size mismatch!"; |
| VLOG(1) << "Command: " << base::HexEncode(serialized_command->data(), |
| serialized_command->size()); |
| return TPM_RC_SUCCESS; |
| } |
| |
| TPM_RC Tpm::ParseResponse_NV_Certify( |
| const std::string& response, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(2) << __func__; |
| VLOG(1) << "Response: " << base::HexEncode(response.data(), response.size()); |
| TPM_RC rc = TPM_RC_SUCCESS; |
| std::string buffer(response); |
| TPM_ST tag; |
| std::string tag_bytes; |
| rc = Parse_TPM_ST( |
| &buffer, |
| &tag, |
| &tag_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| UINT32 response_size; |
| std::string response_size_bytes; |
| rc = Parse_UINT32( |
| &buffer, |
| &response_size, |
| &response_size_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| TPM_RC response_code; |
| std::string response_code_bytes; |
| rc = Parse_TPM_RC( |
| &buffer, |
| &response_code, |
| &response_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (response_size != response.size()) { |
| return TPM_RC_SIZE; |
| } |
| if (response_code != TPM_RC_SUCCESS) { |
| return response_code; |
| } |
| TPM_CC command_code = TPM_CC_NV_Certify; |
| std::string command_code_bytes; |
| rc = Serialize_TPM_CC( |
| command_code, |
| &command_code_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string authorization_section_bytes; |
| if (tag == TPM_ST_SESSIONS) { |
| UINT32 parameter_section_size = buffer.size(); |
| rc = Parse_UINT32(&buffer, ¶meter_section_size, NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (parameter_section_size > buffer.size()) { |
| return TPM_RC_INSUFFICIENT; |
| } |
| authorization_section_bytes = buffer.substr(parameter_section_size); |
| // Keep the parameter section in |buffer|. |
| buffer.erase(parameter_section_size); |
| } |
| scoped_ptr<crypto::SecureHash> hash(crypto::SecureHash::Create( |
| crypto::SecureHash::SHA256)); |
| hash->Update(response_code_bytes.data(), |
| response_code_bytes.size()); |
| hash->Update(command_code_bytes.data(), |
| command_code_bytes.size()); |
| hash->Update(buffer.data(), |
| buffer.size()); |
| std::string response_hash(32, 0); |
| hash->Finish(string_as_array(&response_hash), response_hash.size()); |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| if (!authorization_delegate->CheckResponseAuthorization( |
| response_hash, |
| authorization_section_bytes)) { |
| return TRUNKS_RC_AUTHORIZATION_FAILED; |
| } |
| } |
| std::string certify_info_bytes; |
| rc = Parse_TPM2B_ATTEST( |
| &buffer, |
| certify_info, |
| &certify_info_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string signature_bytes; |
| rc = Parse_TPMT_SIGNATURE( |
| &buffer, |
| signature, |
| &signature_bytes); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| if (tag == TPM_ST_SESSIONS) { |
| CHECK(authorization_delegate) << "Authorization delegate missing!"; |
| // Decrypt just the parameter data, not the size. |
| std::string tmp = certify_info_bytes.substr(2); |
| if (!authorization_delegate->DecryptResponseParameter(&tmp)) { |
| return TRUNKS_RC_ENCRYPTION_FAILED; |
| } |
| certify_info_bytes.replace(2, std::string::npos, tmp); |
| rc = Parse_TPM2B_ATTEST( |
| &certify_info_bytes, |
| certify_info, |
| NULL); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| } |
| return TPM_RC_SUCCESS; |
| } |
| |
| void NV_CertifyErrorCallback( |
| const Tpm::NV_CertifyResponse& callback, |
| TPM_RC response_code) { |
| VLOG(2) << __func__; |
| callback.Run(response_code, |
| TPM2B_ATTEST(), |
| TPMT_SIGNATURE()); |
| } |
| |
| void NV_CertifyResponseParser( |
| const Tpm::NV_CertifyResponse& callback, |
| AuthorizationDelegate* authorization_delegate, |
| const std::string& response) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_CertifyErrorCallback, callback); |
| TPM2B_ATTEST certify_info; |
| TPMT_SIGNATURE signature; |
| TPM_RC rc = Tpm::ParseResponse_NV_Certify( |
| response, |
| &certify_info, |
| &signature, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| callback.Run( |
| rc, |
| certify_info, |
| signature); |
| } |
| |
| void Tpm::NV_Certify( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const UINT16& size, |
| const UINT16& offset, |
| AuthorizationDelegate* authorization_delegate, |
| const NV_CertifyResponse& callback) { |
| VLOG(1) << __func__; |
| base::Callback<void(TPM_RC)> error_reporter = |
| base::Bind(NV_CertifyErrorCallback, callback); |
| base::Callback<void(const std::string&)> parser = |
| base::Bind(NV_CertifyResponseParser, |
| callback, |
| authorization_delegate); |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Certify( |
| sign_handle, |
| sign_handle_name, |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| qualifying_data, |
| in_scheme, |
| size, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| error_reporter.Run(rc); |
| return; |
| } |
| transceiver_->SendCommand(command, parser); |
| } |
| |
| TPM_RC Tpm::NV_CertifySync( |
| const TPMI_DH_OBJECT& sign_handle, |
| const std::string& sign_handle_name, |
| const TPMI_RH_NV_AUTH& auth_handle, |
| const std::string& auth_handle_name, |
| const TPMI_RH_NV_INDEX& nv_index, |
| const std::string& nv_index_name, |
| const TPM2B_DATA& qualifying_data, |
| const TPMT_SIG_SCHEME& in_scheme, |
| const UINT16& size, |
| const UINT16& offset, |
| TPM2B_ATTEST* certify_info, |
| TPMT_SIGNATURE* signature, |
| AuthorizationDelegate* authorization_delegate) { |
| VLOG(1) << __func__; |
| std::string command; |
| TPM_RC rc = SerializeCommand_NV_Certify( |
| sign_handle, |
| sign_handle_name, |
| auth_handle, |
| auth_handle_name, |
| nv_index, |
| nv_index_name, |
| qualifying_data, |
| in_scheme, |
| size, |
| offset, |
| &command, |
| authorization_delegate); |
| if (rc != TPM_RC_SUCCESS) { |
| return rc; |
| } |
| std::string response = transceiver_->SendCommandAndWait(command); |
| rc = ParseResponse_NV_Certify( |
| response, |
| certify_info, |
| signature, |
| authorization_delegate); |
| return rc; |
| } |
| |
| } // namespace trunks |