You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
548 lines
19 KiB
548 lines
19 KiB
// |
|
// Copyright (C) 2015 The Android Open Source Project |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
// |
|
|
|
#include "tpm_manager/server/tpm_nvram_impl.h" |
|
|
|
#include <arpa/inet.h> |
|
|
|
#include <string> |
|
|
|
#include <base/logging.h> |
|
#include <base/stl_util.h> |
|
#include <trousers/scoped_tss_type.h> |
|
|
|
#include "tpm_manager/common/tpm_manager.pb.h" |
|
#include "tpm_manager/server/local_data_store.h" |
|
#include "tpm_manager/server/tpm_util.h" |
|
|
|
namespace tpm_manager { |
|
|
|
using trousers::ScopedTssMemory; |
|
using trousers::ScopedTssNvStore; |
|
using trousers::ScopedTssPcrs; |
|
|
|
namespace { |
|
|
|
// PCR0 at locality 1 is used to differentiate between developed and normal |
|
// mode. Restricting nvram to the PCR0 value in locality 1 prevents nvram from |
|
// persisting across mode switch. |
|
const unsigned int kTpmBootPCR = 0; |
|
const unsigned int kTpmPCRLocality = 1; |
|
|
|
void MapAttributesFromTpm(TPM_NV_PER_ATTRIBUTES tpm_flags, |
|
std::vector<NvramSpaceAttribute>* attributes) { |
|
if (tpm_flags & TPM_NV_PER_WRITEDEFINE) |
|
attributes->push_back(NVRAM_PERSISTENT_WRITE_LOCK); |
|
if (tpm_flags & TPM_NV_PER_WRITE_STCLEAR) |
|
attributes->push_back(NVRAM_BOOT_WRITE_LOCK); |
|
if (tpm_flags & TPM_NV_PER_READ_STCLEAR) |
|
attributes->push_back(NVRAM_BOOT_READ_LOCK); |
|
if (tpm_flags & TPM_NV_PER_AUTHWRITE) |
|
attributes->push_back(NVRAM_WRITE_AUTHORIZATION); |
|
if (tpm_flags & TPM_NV_PER_AUTHREAD) |
|
attributes->push_back(NVRAM_READ_AUTHORIZATION); |
|
if (tpm_flags & TPM_NV_PER_GLOBALLOCK) |
|
attributes->push_back(NVRAM_GLOBAL_LOCK); |
|
if (tpm_flags & TPM_NV_PER_PPWRITE) |
|
attributes->push_back(NVRAM_PLATFORM_WRITE); |
|
if (tpm_flags & TPM_NV_PER_OWNERWRITE) |
|
attributes->push_back(NVRAM_OWNER_WRITE); |
|
if (tpm_flags & TPM_NV_PER_OWNERREAD) |
|
attributes->push_back(NVRAM_OWNER_READ); |
|
} |
|
|
|
TPM_NV_PER_ATTRIBUTES MapAttributesToTpm( |
|
const std::vector<NvramSpaceAttribute>& attributes) { |
|
TPM_NV_PER_ATTRIBUTES tpm_flags = 0; |
|
for (auto attribute : attributes) { |
|
switch (attribute) { |
|
case NVRAM_PERSISTENT_WRITE_LOCK: |
|
tpm_flags |= TPM_NV_PER_WRITEDEFINE; |
|
break; |
|
case NVRAM_BOOT_WRITE_LOCK: |
|
tpm_flags |= TPM_NV_PER_WRITE_STCLEAR; |
|
break; |
|
case NVRAM_BOOT_READ_LOCK: |
|
tpm_flags |= TPM_NV_PER_READ_STCLEAR; |
|
break; |
|
case NVRAM_WRITE_AUTHORIZATION: |
|
tpm_flags |= TPM_NV_PER_AUTHWRITE; |
|
break; |
|
case NVRAM_READ_AUTHORIZATION: |
|
tpm_flags |= TPM_NV_PER_AUTHREAD; |
|
break; |
|
case NVRAM_GLOBAL_LOCK: |
|
tpm_flags |= TPM_NV_PER_GLOBALLOCK; |
|
break; |
|
case NVRAM_PLATFORM_WRITE: |
|
tpm_flags |= TPM_NV_PER_PPWRITE; |
|
break; |
|
case NVRAM_OWNER_WRITE: |
|
tpm_flags |= TPM_NV_PER_OWNERWRITE; |
|
break; |
|
case NVRAM_OWNER_READ: |
|
tpm_flags |= TPM_NV_PER_OWNERREAD; |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
return tpm_flags; |
|
} |
|
|
|
NvramResult MapTpmError(TSS_RESULT tpm_error) { |
|
switch (TPM_ERROR(tpm_error)) { |
|
case TPM_SUCCESS: |
|
return NVRAM_RESULT_SUCCESS; |
|
case TPM_E_BAD_PARAMETER: |
|
case TPM_E_PER_NOWRITE: |
|
case TPM_E_AUTH_CONFLICT: |
|
return NVRAM_RESULT_INVALID_PARAMETER; |
|
case TPM_E_AREA_LOCKED: |
|
case TPM_E_READ_ONLY: |
|
case TPM_E_WRITE_LOCKED: |
|
case TPM_E_DISABLED_CMD: |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
case TPM_E_AUTHFAIL: |
|
case TPM_E_NO_NV_PERMISSION: |
|
case TPM_E_WRONGPCRVAL: |
|
return NVRAM_RESULT_ACCESS_DENIED; |
|
case TPM_E_NOSPACE: |
|
case TPM_E_RESOURCES: |
|
case TPM_E_SIZE: |
|
return NVRAM_RESULT_INSUFFICIENT_SPACE; |
|
case TPM_E_BADINDEX: |
|
case TPM_E_BAD_HANDLE: |
|
return NVRAM_RESULT_SPACE_DOES_NOT_EXIST; |
|
} |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
|
|
} // namespace |
|
|
|
TpmNvramImpl::TpmNvramImpl(LocalDataStore* local_data_store) |
|
: local_data_store_(local_data_store) {} |
|
|
|
NvramResult TpmNvramImpl::DefineSpace( |
|
uint32_t index, |
|
size_t size, |
|
const std::vector<NvramSpaceAttribute>& attributes, |
|
const std::string& authorization_value, |
|
NvramSpacePolicy policy) { |
|
std::string owner_password; |
|
if (!GetOwnerPassword(&owner_password)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
TpmConnection owner_connection(owner_password); |
|
ScopedTssNvStore nv_handle(owner_connection.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &owner_connection)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
TSS_RESULT result; |
|
result = Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_DATASIZE, 0, size); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set size on NVRAM object: " << size; |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
// Set permissions attributes. |
|
result = Tspi_SetAttribUint32(nv_handle, TSS_TSPATTRIB_NV_PERMISSIONS, 0, |
|
MapAttributesToTpm(attributes)); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set permissions on NVRAM object"; |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
// Set authorization. |
|
if (!authorization_value.empty() && |
|
!SetUsagePolicy(authorization_value, &nv_handle, &owner_connection)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
// Bind to PCR0. |
|
TSS_HPCRS pcr_handle = 0; |
|
ScopedTssPcrs scoped_pcr_handle(owner_connection.GetContext()); |
|
if (policy == NVRAM_POLICY_PCR0) { |
|
if (!SetCompositePcr0(&scoped_pcr_handle, &owner_connection)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
pcr_handle = scoped_pcr_handle; |
|
} |
|
result = Tspi_NV_DefineSpace(nv_handle, pcr_handle, /*Read*/ |
|
pcr_handle /*Write*/); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not define NVRAM space: " << index; |
|
return MapTpmError(result); |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::DestroySpace(uint32_t index) { |
|
std::string owner_password; |
|
if (!GetOwnerPassword(&owner_password)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
TpmConnection owner_connection(owner_password); |
|
ScopedTssNvStore nv_handle(owner_connection.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &owner_connection)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
TSS_RESULT result = Tspi_NV_ReleaseSpace(nv_handle); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not release NVRAM space: " << index; |
|
return MapTpmError(result); |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::WriteSpace(uint32_t index, |
|
const std::string& data, |
|
const std::string& authorization_value) { |
|
std::vector<NvramSpaceAttribute> attributes; |
|
NvramResult result = |
|
GetSpaceInfo(index, nullptr, nullptr, nullptr, &attributes, nullptr); |
|
if (result != NVRAM_RESULT_SUCCESS) { |
|
return result; |
|
} |
|
ScopedTssNvStore nv_handle(tpm_connection_.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
for (const auto& attribute : attributes) { |
|
if (attribute == NVRAM_OWNER_WRITE) { |
|
if (!SetOwnerPolicy(&nv_handle)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
break; |
|
} |
|
if (attribute == NVRAM_WRITE_AUTHORIZATION) { |
|
if (!SetUsagePolicy(authorization_value, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
break; |
|
} |
|
} |
|
TSS_RESULT tpm_result = Tspi_NV_WriteValue( |
|
nv_handle, 0 /* offset */, data.size(), |
|
reinterpret_cast<BYTE*>(const_cast<char*>(data.data()))); |
|
if (TPM_ERROR(tpm_result)) { |
|
TPM_LOG(ERROR, tpm_result) << "Could not write to NVRAM space: " << index; |
|
return MapTpmError(tpm_result); |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::ReadSpace(uint32_t index, |
|
std::string* data, |
|
const std::string& authorization_value) { |
|
CHECK(data); |
|
size_t nvram_size; |
|
std::vector<NvramSpaceAttribute> attributes; |
|
NvramResult result = |
|
GetSpaceInfo(index, &nvram_size, nullptr, nullptr, &attributes, nullptr); |
|
if (result != NVRAM_RESULT_SUCCESS) { |
|
return result; |
|
} |
|
ScopedTssNvStore nv_handle(tpm_connection_.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
for (const auto& attribute : attributes) { |
|
if (attribute == NVRAM_OWNER_READ) { |
|
if (!SetOwnerPolicy(&nv_handle)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
break; |
|
} |
|
if (attribute == NVRAM_READ_AUTHORIZATION) { |
|
if (!SetUsagePolicy(authorization_value, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
break; |
|
} |
|
} |
|
data->resize(nvram_size); |
|
// The Tpm1.2 Specification defines the maximum read size of 128 bytes. |
|
// Therefore we have to loop through the data returned. |
|
const size_t kMaxDataSize = 128; |
|
uint32_t offset = 0; |
|
while (offset < nvram_size) { |
|
uint32_t chunk_size = std::min(nvram_size - offset, kMaxDataSize); |
|
ScopedTssMemory space_data(tpm_connection_.GetContext()); |
|
TSS_RESULT tpm_result = |
|
Tspi_NV_ReadValue(nv_handle, offset, &chunk_size, space_data.ptr()); |
|
if (TPM_ERROR(tpm_result)) { |
|
TPM_LOG(ERROR, tpm_result) << "Could not read from NVRAM space: " |
|
<< index; |
|
data->clear(); |
|
return MapTpmError(tpm_result); |
|
} |
|
if (!space_data.value()) { |
|
LOG(ERROR) << "No data read from NVRAM space: " << index; |
|
data->clear(); |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
CHECK_LE((offset + chunk_size), data->size()); |
|
data->replace(offset, chunk_size, |
|
reinterpret_cast<char*>(space_data.value()), chunk_size); |
|
offset += chunk_size; |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::LockSpace(uint32_t index, |
|
bool lock_read, |
|
bool lock_write, |
|
const std::string& authorization_value) { |
|
std::vector<NvramSpaceAttribute> attributes; |
|
NvramResult result = |
|
GetSpaceInfo(index, nullptr, nullptr, nullptr, &attributes, nullptr); |
|
if (result != NVRAM_RESULT_SUCCESS) { |
|
return result; |
|
} |
|
if (lock_read) { |
|
ScopedTssNvStore nv_handle(tpm_connection_.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
for (const auto& attribute : attributes) { |
|
if (attribute == NVRAM_OWNER_READ) { |
|
if (!SetOwnerPolicy(&nv_handle)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
break; |
|
} |
|
if (attribute == NVRAM_READ_AUTHORIZATION) { |
|
if (!SetUsagePolicy(authorization_value, &nv_handle, |
|
&tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
break; |
|
} |
|
} |
|
uint32_t size = 0; |
|
ScopedTssMemory space_data(tpm_connection_.GetContext()); |
|
TSS_RESULT tpm_result = |
|
Tspi_NV_ReadValue(nv_handle, 0, &size, space_data.ptr()); |
|
if (TPM_ERROR(tpm_result)) { |
|
TPM_LOG(ERROR, tpm_result) << "Could not lock read for NVRAM space: " |
|
<< index; |
|
return MapTpmError(tpm_result); |
|
} |
|
} |
|
if (lock_write) { |
|
ScopedTssNvStore nv_handle(tpm_connection_.GetContext()); |
|
if (!InitializeNvramHandle(index, &nv_handle, &tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
for (const auto& attribute : attributes) { |
|
if (attribute == NVRAM_OWNER_WRITE) { |
|
if (!SetOwnerPolicy(&nv_handle)) { |
|
return NVRAM_RESULT_OPERATION_DISABLED; |
|
} |
|
break; |
|
} |
|
if (attribute == NVRAM_WRITE_AUTHORIZATION) { |
|
if (!SetUsagePolicy(authorization_value, &nv_handle, |
|
&tpm_connection_)) { |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
break; |
|
} |
|
} |
|
BYTE not_used; |
|
TSS_RESULT tpm_result = Tspi_NV_WriteValue(nv_handle, 0, 0, ¬_used); |
|
if (TPM_ERROR(tpm_result)) { |
|
TPM_LOG(ERROR, tpm_result) << "Could not lock write for NVRAM space: " |
|
<< index; |
|
return MapTpmError(tpm_result); |
|
} |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::ListSpaces(std::vector<uint32_t>* index_list) { |
|
uint32_t nv_list_data_length = 0; |
|
ScopedTssMemory nv_list_data(tpm_connection_.GetContext()); |
|
TSS_RESULT result = |
|
Tspi_TPM_GetCapability(tpm_connection_.GetTpm(), TSS_TPMCAP_NV_LIST, 0, |
|
nullptr, &nv_list_data_length, nv_list_data.ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability"; |
|
return MapTpmError(result); |
|
} |
|
// Walk the list and check if the index exists. |
|
uint32_t* nv_list = reinterpret_cast<uint32_t*>(nv_list_data.value()); |
|
uint32_t nv_list_length = nv_list_data_length / sizeof(uint32_t); |
|
for (uint32_t i = 0; i < nv_list_length; ++i) { |
|
// TPM data is network byte order. |
|
index_list->push_back(ntohl(nv_list[i])); |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
NvramResult TpmNvramImpl::GetSpaceInfo( |
|
uint32_t index, |
|
size_t* size, |
|
bool* is_read_locked, |
|
bool* is_write_locked, |
|
std::vector<NvramSpaceAttribute>* attributes, |
|
NvramSpacePolicy* policy) { |
|
UINT32 nv_index_data_length = 0; |
|
ScopedTssMemory nv_index_data(tpm_connection_.GetContext()); |
|
TSS_RESULT result = |
|
Tspi_TPM_GetCapability(tpm_connection_.GetTpm(), TSS_TPMCAP_NV_INDEX, |
|
sizeof(index), reinterpret_cast<BYTE*>(&index), |
|
&nv_index_data_length, nv_index_data.ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Error calling Tspi_TPM_GetCapability"; |
|
return MapTpmError(result); |
|
} |
|
UINT64 offset = 0; |
|
Trspi_UnloadBlob_NV_DATA_PUBLIC(&offset, nv_index_data.value(), nullptr); |
|
if (nv_index_data_length < offset) { |
|
LOG(ERROR) << "Not enough data from Tspi_TPM_GetCapability."; |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
TPM_NV_DATA_PUBLIC info; |
|
offset = 0; |
|
result = |
|
Trspi_UnloadBlob_NV_DATA_PUBLIC(&offset, nv_index_data.value(), &info); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Error calling Trspi_UnloadBlob_NV_DATA_PUBLIC"; |
|
return NVRAM_RESULT_DEVICE_ERROR; |
|
} |
|
if (size) { |
|
*size = info.dataSize; |
|
} |
|
if (is_read_locked) { |
|
*is_read_locked = info.bReadSTClear; |
|
} |
|
if (is_write_locked) { |
|
*is_write_locked = info.bWriteSTClear || info.bWriteDefine; |
|
} |
|
if (attributes) { |
|
MapAttributesFromTpm(info.permission.attributes, attributes); |
|
} |
|
if (policy) { |
|
if (info.pcrInfoWrite.pcrSelection.sizeOfSelect > 0 && |
|
(info.pcrInfoWrite.pcrSelection.pcrSelect[0] & 1) != 0) { |
|
*policy = NVRAM_POLICY_PCR0; |
|
} else { |
|
*policy = NVRAM_POLICY_NONE; |
|
} |
|
} |
|
return NVRAM_RESULT_SUCCESS; |
|
} |
|
|
|
bool TpmNvramImpl::InitializeNvramHandle(uint32_t index, |
|
ScopedTssNvStore* nv_handle, |
|
TpmConnection* connection) { |
|
TSS_RESULT result = Tspi_Context_CreateObject( |
|
connection->GetContext(), TSS_OBJECT_TYPE_NV, 0, nv_handle->ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not acquire an NVRAM object handle"; |
|
return false; |
|
} |
|
result = Tspi_SetAttribUint32(nv_handle->value(), TSS_TSPATTRIB_NV_INDEX, 0, |
|
index); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set index on NVRAM object: " << index; |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool TpmNvramImpl::SetOwnerPolicy(ScopedTssNvStore* nv_handle) { |
|
std::string owner_password; |
|
if (!GetOwnerPassword(&owner_password)) { |
|
return false; |
|
} |
|
return SetUsagePolicy(owner_password, nv_handle, &tpm_connection_); |
|
} |
|
|
|
bool TpmNvramImpl::SetUsagePolicy(const std::string& authorization_value, |
|
trousers::ScopedTssNvStore* nv_handle, |
|
TpmConnection* connection) { |
|
trousers::ScopedTssPolicy policy_handle(connection->GetContext()); |
|
TSS_RESULT result; |
|
result = Tspi_Context_CreateObject(connection->GetContext(), |
|
TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, |
|
policy_handle.ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Error calling Tspi_Context_CreateObject"; |
|
return false; |
|
} |
|
result = Tspi_Policy_SetSecret( |
|
policy_handle, TSS_SECRET_MODE_PLAIN, authorization_value.size(), |
|
reinterpret_cast<BYTE*>(const_cast<char*>(authorization_value.data()))); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; |
|
return false; |
|
} |
|
result = |
|
Tspi_Policy_AssignToObject(policy_handle.value(), nv_handle->value()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set NVRAM object policy."; |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool TpmNvramImpl::SetCompositePcr0(ScopedTssPcrs* pcr_handle, |
|
TpmConnection* connection) { |
|
TSS_RESULT result = Tspi_Context_CreateObject( |
|
connection->GetContext(), TSS_OBJECT_TYPE_PCRS, |
|
TSS_PCRS_STRUCT_INFO_SHORT, pcr_handle->ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not acquire PCR object handle"; |
|
return false; |
|
} |
|
uint32_t pcr_len; |
|
ScopedTssMemory pcr_value(connection->GetContext()); |
|
result = Tspi_TPM_PcrRead(connection->GetTpm(), kTpmBootPCR, &pcr_len, |
|
pcr_value.ptr()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not read PCR0 value"; |
|
return false; |
|
} |
|
result = Tspi_PcrComposite_SetPcrValue(pcr_handle->value(), kTpmBootPCR, |
|
pcr_len, pcr_value.value()); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set value for PCR0 in PCR handle"; |
|
return false; |
|
} |
|
result = |
|
Tspi_PcrComposite_SetPcrLocality(pcr_handle->value(), kTpmPCRLocality); |
|
if (TPM_ERROR(result)) { |
|
TPM_LOG(ERROR, result) << "Could not set locality for PCR0 in PCR handle"; |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
bool TpmNvramImpl::GetOwnerPassword(std::string* owner_password) { |
|
LocalData local_data; |
|
if (!local_data_store_->Read(&local_data)) { |
|
LOG(ERROR) << "Error reading local data for owner password."; |
|
return false; |
|
} |
|
if (local_data.owner_password().empty()) { |
|
LOG(ERROR) << "No owner password present in tpm local_data."; |
|
return false; |
|
} |
|
owner_password->assign(local_data.owner_password()); |
|
return true; |
|
} |
|
|
|
} // namespace tpm_manager
|
|
|