| // Copyright (c) 2012 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. |
| |
| #define __STDC_FORMAT_MACROS |
| #include <inttypes.h> |
| |
| #include <base/logging.h> |
| #include <base/stringprintf.h> |
| |
| #include "nvram.h" |
| #include "tpmd.h" |
| #include "volatile_nvram.h" |
| |
| namespace tpmd { |
| |
| static const char* kTpmdService = "org.chromium.tpmd"; |
| static const char* kTpmdPath = "/org/chromium/tpmd"; |
| static const char* kNvramError = "org.chromium.tpmd.nvram.error"; |
| |
| Tpmd::Tpmd(DBus::Connection* connection, DBus::BusDispatcher* dispatcher) |
| : DBus::ObjectAdaptor(*connection, kTpmdPath, REGISTER_NOW, |
| AVOID_EXCEPTIONS), |
| dbus_(connection), dispatcher_(dispatcher), |
| nvram_(new VolatileNvram()) { } |
| |
| Tpmd::~Tpmd() { } |
| |
| bool Tpmd::Init() { |
| try { |
| dbus_->request_name(kTpmdService); |
| } catch (DBus::Error e) { // NOLINT dbuscxx |
| LOG(ERROR) << "can't acquire name: " << e.what() |
| << " " << e.name() << " " << e.message(); |
| return false; |
| } |
| return true; |
| } |
| |
| void Tpmd::Run() { |
| dispatcher_->enter(); |
| while (1) |
| dispatcher_->do_iteration(); |
| // unreachable |
| dispatcher_->leave(); |
| } |
| |
| DBus::Message Tpmd::Encrypt(const DBus::CallMessage& call, |
| const Bytes& plaintext) { |
| return EncryptMakeReply(call, plaintext); |
| } |
| |
| DBus::Message Tpmd::Decrypt(const DBus::CallMessage& call, |
| const Bytes& ciphertext) { |
| return DecryptMakeReply(call, ciphertext); |
| } |
| |
| DBus::Message Tpmd::GetStatus(const DBus::CallMessage& call) { |
| return GetStatusMakeReply(call, "{}"); |
| } |
| |
| DBus::Message Tpmd::Allocate(const DBus::CallMessage& call, |
| const uint32_t& slot, const uint32_t& size, |
| const VariantMap& opts) { |
| uint32_t flags = 0; |
| if (opts.count("LockOnce") && opts.find("LockOnce")->second) |
| flags |= Nvram::NVRAM_LOCKONCE; |
| if (!nvram_->Allocate(slot, size, flags)) |
| return DBus::ErrorMessage(call, kNvramError, "Allocate() failed"); |
| return AllocateMakeReply(call); |
| } |
| |
| DBus::Message Tpmd::Free(const DBus::CallMessage& call, const uint32_t& slot) { |
| if (!nvram_->Free(slot)) |
| return DBus::ErrorMessage(call, kNvramError, "Free() failed"); |
| return FreeMakeReply(call); |
| } |
| |
| DBus::Message Tpmd::Write(const DBus::CallMessage& call, const uint32_t& slot, |
| const Bytes& bytes) { |
| if (bytes.size() != nvram_->size(slot)) { |
| std::string errstr = StringPrintf("Write(%" PRIu32 ") size mismatch: " |
| "%zu != %zu", slot, bytes.size(), |
| nvram_->size(slot)); |
| return DBus::ErrorMessage(call, kNvramError, errstr.c_str()); |
| } |
| if (!nvram_->Write(slot, bytes)) |
| return DBus::ErrorMessage(call, kNvramError, "Write() failed"); |
| return WriteMakeReply(call); |
| } |
| |
| DBus::Message Tpmd::Read(const DBus::CallMessage& call, const uint32_t& slot) { |
| Bytes data; |
| if (!nvram_->Read(slot, &data)) |
| return DBus::ErrorMessage(call, kNvramError, "Read() failed"); |
| return ReadMakeReply(call, data); |
| } |
| |
| DBus::Message Tpmd::IsDefined(const DBus::CallMessage& call, |
| const uint32_t& slot) { |
| return IsDefinedMakeReply(call, nvram_->is_defined(slot)); |
| } |
| |
| DBus::Message Tpmd::IsLocked(const DBus::CallMessage& call, |
| const uint32_t& slot) { |
| return IsLockedMakeReply(call, nvram_->is_locked(slot)); |
| } |
| |
| DBus::Message Tpmd::Size(const DBus::CallMessage& call, const uint32_t& slot) { |
| return SizeMakeReply(call, nvram_->size(slot)); |
| } |
| |
| } // namespace tpmd |