156 lines
5.2 KiB
C++
156 lines
5.2 KiB
C++
//
|
|
// Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
// source code may only be used and distributed under the Widevine
|
|
// License Agreement.
|
|
//
|
|
|
|
// This is an implementation of the opk_transport_interface for the
|
|
// linux trusted OS simulator port of OPK. It uses the
|
|
// posix_services.h implementation of semaphores and shared memory
|
|
// which is based on the POSIX shared memory and semaphore libraries.
|
|
|
|
#include "odk_message.h"
|
|
#include "posix_resources.h"
|
|
#include "tos_transport_interface.h"
|
|
|
|
/*******************************************************************
|
|
* See "tos_transport_interface.h" for documentation of each of the
|
|
* TOS_ interface functions below.
|
|
*******************************************************************/
|
|
|
|
using namespace posix;
|
|
|
|
// message request/response payload data
|
|
static RequestResponseBlock* shared_memory_ = nullptr;
|
|
|
|
// mailbox containing the size of the payload
|
|
static MailboxBlock* mailbox_memory_ = nullptr;
|
|
|
|
// post when a request message is ready
|
|
static RequestSemaphore* request_semaphore_ = nullptr;
|
|
|
|
// post when a response message is ready
|
|
static ResponseSemaphore* response_semaphore_ = nullptr;
|
|
|
|
static void ReleaseResources() {
|
|
if (shared_memory_) {
|
|
delete shared_memory_;
|
|
shared_memory_ = nullptr;
|
|
}
|
|
if (mailbox_memory_) {
|
|
delete mailbox_memory_;
|
|
mailbox_memory_ = nullptr;
|
|
}
|
|
if (request_semaphore_) {
|
|
delete request_semaphore_;
|
|
request_semaphore_ = nullptr;
|
|
}
|
|
if (response_semaphore_) {
|
|
delete response_semaphore_;
|
|
response_semaphore_ = nullptr;
|
|
}
|
|
}
|
|
|
|
bool TOS_Transport_Initialize(void) {
|
|
if (!(shared_memory_ = new RequestResponseBlock()) ||
|
|
!(shared_memory_->Allocate(OPK_TRANSPORT_MESSAGE_SIZE))) {
|
|
ReleaseResources();
|
|
return false;
|
|
}
|
|
if (!(mailbox_memory_ = new MailboxBlock()) ||
|
|
!(mailbox_memory_->Allocate(sizeof(uint32_t)))) {
|
|
ReleaseResources();
|
|
return false;
|
|
}
|
|
if (!(request_semaphore_ = new RequestSemaphore())) {
|
|
ReleaseResources();
|
|
return false;
|
|
}
|
|
if (!(response_semaphore_ = new ResponseSemaphore())) {
|
|
ReleaseResources();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TOS_Transport_Terminate(void) { ReleaseResources(); }
|
|
|
|
ODK_Message TOS_Transport_GetRequest() {
|
|
if (!shared_memory_) {
|
|
return ODK_Message_Create(nullptr, 0);
|
|
} else {
|
|
return ODK_Message_Create(shared_memory_->GetAddress(),
|
|
shared_memory_->GetSize());
|
|
}
|
|
}
|
|
|
|
ODK_Message TOS_Transport_GetResponse() {
|
|
/* Use the same shared memory block for request & response */
|
|
return TOS_Transport_GetRequest();
|
|
}
|
|
|
|
void TOS_Transport_ReleaseMessage(ODK_Message* message) {
|
|
// resources are static, nothing to do here
|
|
}
|
|
|
|
// Get the size of the message from the mailbox and return it
|
|
static uint32_t PeekSize(void) {
|
|
uint8_t* mailbox = mailbox_memory_->GetAddress();
|
|
uint32_t message_size = (uint32_t)mailbox[0] | (uint32_t)mailbox[1] << 8 |
|
|
(uint32_t)mailbox[2] << 16 |
|
|
(uint32_t)mailbox[3] << 24;
|
|
return message_size;
|
|
}
|
|
|
|
// Put the size of the message into the mailbox
|
|
static void PokeSize(uint32_t size) {
|
|
uint8_t* mailbox = mailbox_memory_->GetAddress();
|
|
mailbox[0] = (uint8_t)(size);
|
|
mailbox[1] = (uint8_t)(size >> 8);
|
|
mailbox[2] = (uint8_t)(size >> 16);
|
|
mailbox[3] = (uint8_t)(size >> 24);
|
|
}
|
|
|
|
// The request has been packed into the shared memory, all we need to
|
|
// do is poke the message size in the mailbox and post on the request
|
|
// semaphore, then wait for the response semaphore. The response will
|
|
// be in the shared memory by then, so return a response message
|
|
// constructed from the shared memory with the size in the mailbox.
|
|
|
|
OPK_TransportStatus TOS_Transport_SendMessage(ODK_Message* request,
|
|
ODK_Message* response) {
|
|
PokeSize(static_cast<uint32_t>(ODK_Message_GetSize(request)));
|
|
request_semaphore_->post();
|
|
response_semaphore_->wait();
|
|
*response = ODK_Message_Create(shared_memory_->GetAddress(),
|
|
shared_memory_->GetSize());
|
|
ODK_Message_SetSize(response, PeekSize());
|
|
return OPK_TRANSPORT_STATUS_OK;
|
|
}
|
|
|
|
/********************************************************************
|
|
* These are TOS functions only used by the tee_simulator, they are
|
|
* not an implementation of functions in the TOS transport interface.
|
|
********************************************************************/
|
|
|
|
// Wait for the request until signaled. Then the request payload will
|
|
// be in the shared memory and the size in the mailbox. Create a
|
|
// request message from the payload data and return it.
|
|
|
|
OPK_TransportStatus TOS_Transport_ReceiveRequest(ODK_Message* request) {
|
|
request_semaphore_->wait();
|
|
*request = ODK_Message_Create(shared_memory_->GetAddress(),
|
|
shared_memory_->GetSize());
|
|
ODK_Message_SetSize(request, PeekSize());
|
|
return OPK_TRANSPORT_STATUS_OK;
|
|
}
|
|
|
|
// The response has been packed into the shared memory. Put the message
|
|
// size in the mailbox then post on the response semaphore to send it.
|
|
|
|
OPK_TransportStatus TOS_Transport_SendResponse(ODK_Message* response) {
|
|
PokeSize(static_cast<uint32_t>(ODK_Message_GetSize(response)));
|
|
response_semaphore_->post();
|
|
return OPK_TRANSPORT_STATUS_OK;
|
|
}
|