blob: 01b628bde366f2329506056540a724c1d7ab6c99 [file] [log] [blame]
// Copyright 2018 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.
#include "attestation/common/tpm_utility_common.h"
#include <memory>
#include <vector>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <tpm_manager-client/tpm_manager/dbus-constants.h>
namespace attestation {
TpmUtilityCommon::TpmUtilityCommon()
: tpm_manager_utility_(tpm_manager::TpmManagerUtility::GetSingleton()) {}
TpmUtilityCommon::TpmUtilityCommon(
tpm_manager::TpmManagerUtility* tpm_manager_utility)
: tpm_manager_utility_(tpm_manager_utility) {}
TpmUtilityCommon::~TpmUtilityCommon() {}
bool TpmUtilityCommon::Initialize() {
BuildValidPCR0Values();
if (!tpm_manager_utility_) {
LOG(INFO) << __func__ << "Reinitialize tpm_manager utility";
tpm_manager_utility_ = tpm_manager::TpmManagerUtility::GetSingleton();
}
return tpm_manager_utility_;
}
bool TpmUtilityCommon::IsTpmReady() {
if (!is_ready_) {
CacheTpmState();
}
return is_ready_;
}
void TpmUtilityCommon::BuildValidPCR0Values() {
// 3-byte boot mode:
// - byte 0: 1 if in developer mode, 0 otherwise,
// - byte 1: 1 if in recovery mode, 0 otherwise,
// - byte 2: 1 if verified firmware, 0 if developer firmware.
constexpr char kKnownBootModes[][3] = {{0, 0, 0}, {0, 0, 1}, {0, 1, 0},
{0, 1, 1}, {1, 0, 0}, {1, 0, 1},
{1, 1, 0}, {1, 1, 1}};
for (size_t i = 0; i < base::size(kKnownBootModes); i++) {
const std::string mode(std::begin(kKnownBootModes[i]),
std::end(kKnownBootModes[i]));
valid_pcr0_values_.insert(GetPCRValueForMode(mode));
}
}
bool TpmUtilityCommon::IsPCR0Valid() {
std::string pcr0_value;
if (!ReadPCR(0, &pcr0_value)) {
LOG(ERROR) << __func__ << "Failed to read PCR0";
return false;
}
if (!base::Contains(valid_pcr0_values_, pcr0_value)) {
LOG(ERROR) << "Encountered invalid PCR0 value: "
<< base::HexEncode(pcr0_value.data(), pcr0_value.size());
return false;
}
return true;
}
bool TpmUtilityCommon::GetEndorsementPassword(std::string* password) {
if (endorsement_password_.empty()) {
if (!CacheTpmState()) {
return false;
}
if (endorsement_password_.empty()) {
LOG(WARNING) << ": TPM endorsement password is not available.";
return false;
}
}
*password = endorsement_password_;
return true;
}
bool TpmUtilityCommon::GetOwnerPassword(std::string* password) {
if (owner_password_.empty()) {
if (!CacheTpmState()) {
return false;
}
if (owner_password_.empty()) {
LOG(WARNING) << ": TPM owner password is not available.";
return false;
}
}
*password = owner_password_;
return true;
}
bool TpmUtilityCommon::CacheTpmState() {
tpm_manager::LocalData local_data;
bool is_enabled{false};
bool is_owned{false};
if (!tpm_manager_utility_) {
tpm_manager_utility_ = tpm_manager::TpmManagerUtility::GetSingleton();
if (!tpm_manager_utility_) {
LOG(ERROR) << __func__ << ": Failed to get tpm_manager utility.";
return false;
}
}
if (!tpm_manager_utility_->GetTpmStatus(&is_enabled, &is_owned,
&local_data)) {
LOG(ERROR) << __func__ << ": Failed to get tpm status from tpm_manager.";
return false;
}
is_ready_ = is_enabled && is_owned;
endorsement_password_ = local_data.endorsement_password();
owner_password_ = local_data.owner_password();
delegate_blob_ = local_data.owner_delegate().blob();
delegate_secret_ = local_data.owner_delegate().secret();
return true;
}
bool TpmUtilityCommon::RemoveOwnerDependency() {
if (!tpm_manager_utility_) {
tpm_manager_utility_ = tpm_manager::TpmManagerUtility::GetSingleton();
if (!tpm_manager_utility_) {
LOG(ERROR) << __func__ << ": Failed to get tpm_manager utility.";
return false;
}
}
return tpm_manager_utility_->RemoveOwnerDependency(
tpm_manager::kTpmOwnerDependency_Attestation);
}
} // namespace attestation