blob: c794353d92f3b009e4e3ca6d5e0af5118a4eb5cb [file] [log] [blame]
// Copyright 2015 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 <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <brillo/streams/file_stream.h>
extern "C" {
#include <tpm2/_TPM_Init_fp.h>
#include <tpm2/ExecCommand_fp.h>
#include <tpm2/GetCommandCodeString_fp.h>
#include <tpm2/Platform.h>
#include <tpm2/tpm_generated.h>
}
int main() {
// Initialize TPM.
_plat__Signal_PowerOn();
_TPM_Init();
_plat__SetNvAvail();
brillo::ErrorPtr error;
// Create pipes.
mkfifo("/dev/tpm-req", O_CREAT|O_RDWR);
mkfifo("/dev/tpm-resp", O_CREAT|O_RDWR);
brillo::StreamPtr request_stream = brillo::FileStream::Open(
base::FilePath("/dev/tpm-req"),
brillo::Stream::AccessMode::READ_WRITE,
brillo::FileStream::Disposition::CREATE_ALWAYS,
&error);
if (error.get()) {
PLOG(ERROR) << "TPM simulator: Error opening /dev/tpm-req: "
<< error->GetMessage();
return -1;
}
brillo::StreamPtr response_stream = brillo::FileStream::Open(
base::FilePath("/dev/tpm-resp"),
brillo::Stream::AccessMode::READ_WRITE,
brillo::FileStream::Disposition::CREATE_ALWAYS,
&error);
if (error.get()) {
PLOG(ERROR) << "TPM simulator: Error opening /dev/tpm-resp: "
<< error->GetMessage();
return -1;
}
while (true) {
unsigned char request[MAX_COMMAND_SIZE];
unsigned int request_size;
// Read request header.
request_stream->ReadAllBlocking(request, 10, &error);
if (error.get()) {
PLOG(ERROR) << "TPM simulator: Error receiving request header: "
<< error->GetMessage();
return -1;
}
unsigned char *header = request;
INT32 header_size = 10;
TPMI_ST_COMMAND_TAG tag;
UINT32 command_size;
TPM_CC command_code;
// Unmarshal request header to get request size and command code.
TPM_RC rc = TPMI_ST_COMMAND_TAG_Unmarshal(&tag, &header, &header_size);
CHECK_EQ(rc, TPM_RC_SUCCESS);
rc = UINT32_Unmarshal(&command_size, &header, &header_size);
CHECK_EQ(rc, TPM_RC_SUCCESS);
rc = TPM_CC_Unmarshal(&command_code, &header, &header_size);
CHECK_EQ(rc, TPM_RC_SUCCESS);
request_size = command_size;
// Read request body.
if (request_size > 10) {
request_stream->ReadAllBlocking(request+10, request_size-10, &error);
if (error.get()) {
PLOG(ERROR) << "TPM simulator: Error receiving request body: "
<< error->GetMessage();
return -1;
}
}
// Execute command.
LOG(INFO) << "TPM simulator: Executing "
<< GetCommandCodeString(command_code);
unsigned int response_size;
unsigned char *response;
ExecuteCommand(request_size, request, &response_size, &response);
// Write response.
response_stream->WriteAllBlocking(response, response_size, &error);
if (error.get()) {
PLOG(ERROR) << "TPM simulator: Error writing response: "
<< error->GetMessage();
return -1;
}
}
}