blob: 28fc45a0618219def14151efdae80a3a61e2f982 [file] [log] [blame] [edit]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libhwsec/backend/tpm1/state.h"
#include <utility>
#include <libhwsec-foundation/status/status_chain_macros.h>
#include <tpm_manager/proto_bindings/tpm_manager.pb.h>
#include <tpm_manager-client/tpm_manager/dbus-proxies.h>
#include "libhwsec/error/tpm_manager_error.h"
#include "libhwsec/status.h"
using hwsec_foundation::status::MakeStatus;
namespace hwsec {
StatusOr<bool> StateTpm1::IsEnabled() {
tpm_manager::GetTpmNonsensitiveStatusRequest request;
tpm_manager::GetTpmNonsensitiveStatusReply reply;
if (brillo::ErrorPtr err; !tpm_manager_.GetTpmNonsensitiveStatus(
request, &reply, &err, Proxy::kDefaultDBusTimeoutMs)) {
return MakeStatus<TPMError>(TPMRetryAction::kCommunication)
.Wrap(std::move(err));
}
RETURN_IF_ERROR(MakeStatus<TPMManagerError>(reply.status()));
return reply.is_enabled();
}
StatusOr<bool> StateTpm1::IsReady() {
tpm_manager::GetTpmNonsensitiveStatusRequest request;
tpm_manager::GetTpmNonsensitiveStatusReply reply;
if (brillo::ErrorPtr err; !tpm_manager_.GetTpmNonsensitiveStatus(
request, &reply, &err, Proxy::kDefaultDBusTimeoutMs)) {
return MakeStatus<TPMError>(TPMRetryAction::kCommunication)
.Wrap(std::move(err));
}
RETURN_IF_ERROR(MakeStatus<TPMManagerError>(reply.status()));
return reply.is_owned();
}
Status StateTpm1::Prepare() {
tpm_manager::TakeOwnershipRequest request;
tpm_manager::TakeOwnershipReply reply;
if (brillo::ErrorPtr err; !tpm_manager_.TakeOwnership(
request, &reply, &err, Proxy::kDefaultDBusTimeoutMs)) {
return MakeStatus<TPMError>(TPMRetryAction::kCommunication)
.Wrap(std::move(err));
}
return MakeStatus<TPMManagerError>(reply.status());
}
void StateTpm1::WaitUntilReady(base::OnceCallback<void(Status)> callback) {
if (!received_ready_signal_.has_value()) {
received_ready_signal_ = false;
tpm_manager_.RegisterSignalOwnershipTakenSignalHandler(
base::IgnoreArgs<const tpm_manager::OwnershipTakenSignal&>(
base::BindRepeating(&StateTpm1::OnReady,
weak_factory_.GetWeakPtr())),
base::DoNothing());
}
if (received_ready_signal_.value() == false) {
received_ready_signal_ = IsReady().value_or(false);
}
if (received_ready_signal_.value() == true) {
std::move(callback).Run(OkStatus());
return;
}
ready_callbacks_.push_back(std::move(callback));
}
void StateTpm1::OnReady() {
received_ready_signal_ = true;
std::vector<base::OnceCallback<void(Status)>> callbacks =
std::move(ready_callbacks_);
ready_callbacks_.clear();
for (base::OnceCallback<void(Status)>& callback : callbacks) {
std::move(callback).Run(OkStatus());
}
}
} // namespace hwsec