Files
oemcrypto/oemcrypto/opk/ports/linux/common/tos_transport.cpp
Fred Gylys-Colwell ef3ad135c9 Add new test files for OEMCrypto v17.2
The previous commit did not include some new files.
2023-09-07 13:45:38 -07:00

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;
}