97 lines
2.9 KiB
C++
97 lines
2.9 KiB
C++
//
|
|
// Copyright (C) 2014 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 "trunks/tpm_handle.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#include <base/callback.h>
|
|
#include <base/logging.h>
|
|
#include <base/posix/eintr_wrapper.h>
|
|
|
|
namespace {
|
|
|
|
const char kTpmDevice[] = "/dev/tpm0";
|
|
const uint32_t kTpmBufferSize = 4096;
|
|
const int kInvalidFileDescriptor = -1;
|
|
|
|
} // namespace
|
|
|
|
namespace trunks {
|
|
|
|
TpmHandle::TpmHandle() : fd_(kInvalidFileDescriptor) {}
|
|
|
|
TpmHandle::~TpmHandle() {
|
|
int result = IGNORE_EINTR(close(fd_));
|
|
if (result == -1) {
|
|
PLOG(ERROR) << "TPM: couldn't close " << kTpmDevice;
|
|
}
|
|
LOG(INFO) << "TPM: " << kTpmDevice << " closed successfully";
|
|
}
|
|
|
|
bool TpmHandle::Init() {
|
|
if (fd_ != kInvalidFileDescriptor) {
|
|
VLOG(1) << "Tpm already initialized.";
|
|
return true;
|
|
}
|
|
fd_ = HANDLE_EINTR(open(kTpmDevice, O_RDWR));
|
|
if (fd_ == kInvalidFileDescriptor) {
|
|
PLOG(ERROR) << "TPM: Error opening tpm0 file descriptor at " << kTpmDevice;
|
|
return false;
|
|
}
|
|
LOG(INFO) << "TPM: " << kTpmDevice << " opened successfully";
|
|
return true;
|
|
}
|
|
|
|
void TpmHandle::SendCommand(const std::string& command,
|
|
const ResponseCallback& callback) {
|
|
callback.Run(SendCommandAndWait(command));
|
|
}
|
|
|
|
std::string TpmHandle::SendCommandAndWait(const std::string& command) {
|
|
std::string response;
|
|
TPM_RC result = SendCommandInternal(command, &response);
|
|
if (result != TPM_RC_SUCCESS) {
|
|
response = CreateErrorResponse(result);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
TPM_RC TpmHandle::SendCommandInternal(const std::string& command,
|
|
std::string* response) {
|
|
CHECK_NE(fd_, kInvalidFileDescriptor);
|
|
int result = HANDLE_EINTR(write(fd_, command.data(), command.length()));
|
|
if (result < 0) {
|
|
PLOG(ERROR) << "TPM: Error writing to TPM handle.";
|
|
return TRUNKS_RC_WRITE_ERROR;
|
|
}
|
|
if (static_cast<size_t>(result) != command.length()) {
|
|
LOG(ERROR) << "TPM: Error writing to TPM handle: " << result << " vs "
|
|
<< command.length();
|
|
return TRUNKS_RC_WRITE_ERROR;
|
|
}
|
|
char response_buf[kTpmBufferSize];
|
|
result = HANDLE_EINTR(read(fd_, response_buf, kTpmBufferSize));
|
|
if (result < 0) {
|
|
PLOG(ERROR) << "TPM: Error reading from TPM handle.";
|
|
return TRUNKS_RC_READ_ERROR;
|
|
}
|
|
response->assign(response_buf, static_cast<size_t>(result));
|
|
return TPM_RC_SUCCESS;
|
|
}
|
|
|
|
} // namespace trunks
|