From dd882e357ea36c7ed28511d81b41680623ae216b Mon Sep 17 00:00:00 2001 From: isiora Date: Fri, 11 May 2018 09:56:36 +0000 Subject: Refactory of the proxy stubs code. Added the IOBlks proxystub. Included reliance edge test. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12020 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- .../RT-SAMA5D2-XPLAINED-SEC/proxies/tscommon.h | 60 +++-- .../RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.c | 174 +++++++++++++++ .../RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.h | 68 ++++++ .../RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.c | 240 ++++++++++++++++++++ .../RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.h | 102 +++++++++ .../RT-SAMA5D2-XPLAINED-SEC/proxies/tssockets.h | 74 ++++++ .../RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.c | 248 ++------------------- .../RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.h | 7 +- 8 files changed, 729 insertions(+), 244 deletions(-) create mode 100644 demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.c create mode 100644 demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.h create mode 100644 demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.c create mode 100644 demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.h create mode 100644 demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockets.h (limited to 'demos') diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tscommon.h b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tscommon.h index 3a2698451..bc1c3f5f8 100644 --- a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tscommon.h +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tscommon.h @@ -38,16 +38,43 @@ #define SKEL_REQ_PUTRES 3 #define SKEL_REQ_READY 4 -#define STUB_OP_SOCKET 0 -#define STUB_OP_CLOSE 1 -#define STUB_OP_CONNECT 2 -#define STUB_OP_RECV 3 -#define STUB_OP_SEND 4 -#define STUB_OP_SELECT 5 -#define STUB_OP_BIND 6 -#define STUB_OP_LISTEN 7 +/* Sockets stub defines.*/ +#define SOCK_OP_SOCKET 0 +#define SOCK_OP_CLOSE 1 +#define SOCK_OP_CONNECT 2 +#define SOCK_OP_RECV 3 +#define SOCK_OP_SEND 4 +#define SOCK_OP_SELECT 5 +#define SOCK_OP_BIND 6 +#define SOCK_OP_LISTEN 7 -#define EVT_F_SOCK_NEW_OP 1 +/* Socket new op event.*/ +#define EVT_F_SOCK_NEW_OP 1 + +/* Sockets stub service name.*/ +#define SOCKS_SVC_NAME "TsSocksStubService" + +/* IOBlocks stub defines.*/ +#define IOBLKS_OP_OPEN 0 +#define IOBLKS_OP_CLOSE 1 +#define IOBLKS_OP_READ 2 +#define IOBLKS_OP_WRITE 3 +#define IOBLKS_OP_FLUSH 4 + +/* IOBlock new op event.*/ +#define EVT_F_IOBLK_NEW_OP 2 + +/* IOBlock stub service name.*/ +#define IOBLKS_SVC_NAME "TsIOBlksStubService" + +/* Sector size.*/ +#define IOBLKS_SECT_SIZE 512U + +/* Remote Partition size, in sectors.*/ +#define IOBLKS_PART_SIZE 96256U + +/* Remote partition offset, in sectors.*/ +#define IOBLKS_PART_OFFS 952320U /*===========================================================================*/ /* Module pre-compile time settings. */ @@ -63,13 +90,16 @@ /*===========================================================================*/ /* Module data structures and types. */ /*===========================================================================*/ +typedef struct skel_ctx skel_ctx_t; + typedef struct skel_req { - uint32_t req; /* getop, cpyprms, putres */ - uint32_t stub_op; - uint32_t stub_op_code; - uint32_t stub_op_result; - uint32_t stub_op_p_sz[METHOD_MAX_PARAMS]; - uint32_t stub_op_p[METHOD_MAX_PARAMS]; + uint32_t req; /* getop, cpyprms, putres */ + uint32_t stub_op; + uint32_t stub_op_code; + uint32_t stub_op_result; + uint32_t stub_op_p_sz[METHOD_MAX_PARAMS]; + uint32_t stub_op_p[METHOD_MAX_PARAMS]; + skel_ctx_t *scp; /* the skeleton context this req come from.*/ } skel_req_t; /*===========================================================================*/ diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.c b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.c new file mode 100644 index 000000000..d7ec50c11 --- /dev/null +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.c @@ -0,0 +1,174 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + 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. +*/ + +/** + * @file tsioblksstub.c + * @brief IOBlks stub for trusted services implementing the + * Reliance Edge api. + * + */ + +#include "ch.h" +#include "chobjfifos.h" +#include "chtssi.h" +#include "tsproxystubs.h" +#include "tsioblksstub.h" +#include +#include +#include +#include + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ +static stub_ctx_t stub_ctx; +const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] = { + { + 512, /* ulSectorSize.*/ + IOBLKS_PART_SIZE, /* ullSectorCount.*/ + 0U, /* ullSectorOffset.*/ + false, /* fAtomicSectorWrite.*/ + 1024U, /* ulInodeCount.*/ + 2U, /* bBlockIoRetries.*/ + "" + } +}; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief The IOBlks stub service. + */ +THD_WORKING_AREA(waTsIOBlksStubsService, 1024); +THD_FUNCTION(TsIOBlksStubsService, tsstatep) { + stub_ctx.event_flag = EVT_F_IOBLK_NEW_OP; + TsStubService((ts_state_t *)tsstatep, &stub_ctx); +} + +/** + * @name The IOBlks api, in the Reliance Edge fashion. + * @{ + */ + +/** + * @brief Open the block device. + */ +REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode) { + (void)mode; + + if (bVolNum != 0) + return -RED_EINVAL; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = IOBLKS_OP_OPEN; + op->op_p[0].dir = OP_PRMDIR_NONE; + op->op_p[0].val = (uint32_t)bVolNum; + op->op_p[1].dir = OP_PRMDIR_NONE; + op->op_p[1].val = (uint32_t)mode; + return (REDSTATUS)callRemote(op); +} + +/** + * @brief Close the block device. + */ +REDSTATUS RedOsBDevClose(uint8_t bVolNum) { + if (bVolNum != 0) + return -RED_EINVAL; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = IOBLKS_OP_CLOSE; + op->op_p[0].dir = OP_PRMDIR_NONE; + op->op_p[0].val = (uint32_t)bVolNum; + return (REDSTATUS)callRemote(op); +} + +/** + * @brief Read from the block device. + */ +REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer) { + if ((bVolNum != 0) || + (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) || + ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) || + (pBuffer == NULL)) + return -RED_EINVAL; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = IOBLKS_OP_READ; + op->op_p[0].dir = OP_PRMDIR_NONE; + op->op_p[0].val = (uint32_t)bVolNum; + op->op_p[1].dir = OP_PRMDIR_NONE; + op->op_p[1].val = (uint32_t)ullSectorStart; + op->op_p[2].dir = OP_PRMDIR_NONE; + op->op_p[2].val = (uint32_t)ulSectorCount; + op->op_p[3].dir = OP_PRMDIR_OUT; + op->op_p[3].val = (uint32_t)pBuffer; + op->op_p[3].size = (uint32_t)(ulSectorCount * IOBLKS_SECT_SIZE); + return (int)callRemote(op); +} + +/** + * @brief Write to the block device. + */ +REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer) { + if ((bVolNum != 0) || + (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) || + ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) || + (pBuffer == NULL)) + return -RED_EINVAL; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = IOBLKS_OP_WRITE; + op->op_p[0].dir = OP_PRMDIR_NONE; + op->op_p[0].val = (uint32_t)bVolNum; + op->op_p[1].dir = OP_PRMDIR_NONE; + op->op_p[1].val = (uint32_t)ullSectorStart; + op->op_p[2].dir = OP_PRMDIR_NONE; + op->op_p[2].val = (uint32_t)ulSectorCount; + op->op_p[3].dir = OP_PRMDIR_IN; + op->op_p[3].val = (uint32_t)pBuffer; + op->op_p[3].size = (uint32_t)(ulSectorCount * IOBLKS_SECT_SIZE); + return (int)callRemote(op); +} + +/** + * @brief Flush the block device. + */ +REDSTATUS RedOsBDevFlush(uint8_t bVolNum) { + if (bVolNum != 0) + return -RED_EINVAL; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = IOBLKS_OP_FLUSH; + op->op_p[0].dir = OP_PRMDIR_NONE; + op->op_p[0].val = (uint32_t)bVolNum; + return (REDSTATUS)callRemote(op); +} + +/** @} */ + diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.h b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.h new file mode 100644 index 000000000..17aeb3212 --- /dev/null +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsioblksstub.h @@ -0,0 +1,68 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file tsioblksstub.h + * @brief IOBlocks stub module macros and structures. + * + */ +#ifndef TSIOBLKSSTUB_H +#define TSIOBLKSSTUB_H + +#include "ch.h" +#include "ccportab.h" + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + THD_FUNCTION(TsIOBlksStubsService, tsstatep); + extern THD_WORKING_AREA(waTsIOBlksStubsService, 1024); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* TSIOBLKSSTUB_H */ diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.c b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.c new file mode 100644 index 000000000..67ff5dab4 --- /dev/null +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.c @@ -0,0 +1,240 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + + 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. +*/ + +/** + * @file tssockstub.c + * @brief Sockets stub for trusted services. + * + */ + +#include "ch.h" +#include "chobjfifos.h" +#include "chtssi.h" +#include "tsproxystubs.h" +#include +#include + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ +static eventflags_t tsSkelIsReadyMask = 0; + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ +static bool isOpValid(stub_ctx_t *scp, stub_op_t *op) +{ + if ((op < &(scp->ops[0])) || (op >= &(scp->ops[STUB_MAX_OPS]))) + return FALSE; + if (((char *)op - (char *)&(scp->ops[0])) % sizeof scp->ops[0]) + return FALSE; + return TRUE; +} + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Implement an a call to a NSEC function. + * @details It activates the channel between the stubs service and + * the skels daemon running in the nsec world. + * To do it, it uses an event to signal the corresponding skel + * daemon that a new op request is ready to be executed. + * Behind the scenes, the skel daemon will then gets the op, calling + * the stub service via smc. The daemon executes it and then calls + * the stub service again to post the result and to wake up the + * calling thread of this function. + * + * @param[in] op the 'remote' method description. + * + * @return the return value of 'remote' method. + */ +uint32_t callRemote(stub_op_t *op) { + uint32_t r; + + chSysLock(); + chFifoSendObjectI(&op->scp->ops_fifo, op); + chEvtBroadcastFlagsI(&tsEventSource, op->scp->event_flag); + chThdSuspendS(&op->op_wthdp); + op->op_state = FREE; + chSysUnlock(); + r = op->op_code; + chFifoReturnObject(&op->scp->ops_fifo, op); + return r; +} + +stub_op_t *getNewOp(stub_ctx_t *scp) { + stub_op_t *op = chFifoTakeObjectTimeout(&scp->ops_fifo, TIME_INFINITE); + memset(op, 0, sizeof *op); + op->op_state = CALLING; + op->scp = scp; + return op; +} + +/** + * @brief The stubs service. + * @details And this is where the magic happens. + */ +void TsStubService(ts_state_t *svcp, stub_ctx_t *scp) { + skel_req_t *skrp; + stub_op_t *op; + msg_t r; + int i; + + chFifoObjectInit(&scp->ops_fifo, sizeof (stub_op_t), STUB_MAX_OPS, + sizeof (uint8_t), scp->ops, scp->ops_msgs); + for (;/* ever */;) { + + /* Wait a service request.*/ + (void)tssiWaitRequest(svcp); + skrp = (skel_req_t *)TS_GET_DATA(svcp); + r = SMC_SVC_OK; + + /* Process the request.*/ + if (TS_GET_DATALEN(svcp) != sizeof (skel_req_t)) { + TS_SET_STATUS(svcp, SMC_SVC_INVALID); + continue; + } + + switch (skrp->req) { + case SKEL_REQ_READY: + tsSkelIsReadyMask |= (eventflags_t)skrp->stub_op; + break; + + case SKEL_REQ_GETOP: + + /* The nsec skeleton calls us to get a new op ready to be executed.*/ + if (chFifoReceiveObjectTimeout(&scp->ops_fifo, (void **)&op, + TIME_IMMEDIATE) == MSG_TIMEOUT) { + + /* no op ready to be executed.*/ + r = SMC_SVC_NHND; + break; + } + skrp->stub_op = (uint32_t)op; + skrp->stub_op_code = op->op_code; + + /* Pass all the 'by value' arguments from stub to skel.*/ + for (i = 0; i < METHOD_MAX_PARAMS; ++i) { + if (op->op_p[i].dir == OP_PRMDIR_NONE) + skrp->stub_op_p[i] = op->op_p[i].val; + } + op->op_state = PENDING; + break; + + case SKEL_REQ_CPYPRMS: + + /* The nsec skel calls us to get a copy of the 'in' parameters of + the specified op. + An 'in' parameter is an indirect argument, that is an argument + the value of which is a pointer to a memory buffer, that + must be copied in a non secure memory buffer. + It represents data to be consumed by the callee.*/ + op = (stub_op_t *)skrp->stub_op; + if (!isOpValid(scp, op) || op->op_state != PENDING || + op->op_code != skrp->stub_op_code) { + r = SMC_SVC_INVALID; + break; + } + + /* Copy all 'in' parameters. + For each parameter check that the destination memory area + is in the non secure memory arena.*/ + for (i = 0; i < METHOD_MAX_PARAMS; ++i) { + if ((op->op_p[i].dir & OP_PRMDIR_IN) == 0) + continue; + if (!tsIsAddrSpaceValid((void *)skrp->stub_op_p[i], op->op_p[i].size)) { + r = SMC_SVC_INVALID; + break; + } + memcpy((void *)skrp->stub_op_p[i], (void *)op->op_p[i].val, + op->op_p[i].size); + } + break; + + case SKEL_REQ_PUTRES: + + /* The nsec skel calls us to put a copy of the 'out' parameters of + the specified op. + An 'out' parameter is an indirect argument, that is an argument + the value of which is a pointer to a memory buffer, that + must be copied in a secure memory buffer. + It represents data produced by the callee.*/ + op = (stub_op_t *)skrp->stub_op; + if (!isOpValid(scp, op) || op->op_state != PENDING || + op->op_code != skrp->stub_op_code) { + r = SMC_SVC_INVALID; + break; + } + + /* Copy all 'out' parameters. + For each parameter check that the source memory area + is in the non secure memory arena, and that the size returned + fits in the caller buffer size.*/ + for (i = 0; i < METHOD_MAX_PARAMS; ++i) { + if ((op->op_p[i].dir & OP_PRMDIR_OUT) == 0) + continue; + if (!tsIsAddrSpaceValid((void *)skrp->stub_op_p[i], skrp->stub_op_p_sz[i]) + || (skrp->stub_op_p_sz[i] > op->op_p[i].size)) { + r = SMC_SVC_INVALID; + break; + } + memcpy((void *)op->op_p[i].val, (void *)skrp->stub_op_p[i], + skrp->stub_op_p_sz[i]); + } + if (r != SMC_SVC_OK) + break; + + /* Set the return value of the 'remote' callee method, + and wake up the caller.*/ + op->op_code = skrp->stub_op_result; + chThdResume(&op->op_wthdp, MSG_OK); + break; + + default: + r = SMC_SVC_INVALID; + break; + } + + /* Set the response.*/ + TS_SET_STATUS(svcp, r); + } +} + +/** + * @brief Is the skeletons daemon ready to operate? + * @details It is used at the startup to synchronize the + * stub service with the skeleton daemon. + */ +void tsWaitStubSkelReady(eventflags_t mask) { + while ((tsSkelIsReadyMask & mask) != mask) { + chThdSleepMilliseconds(100); + } +} + diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.h b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.h new file mode 100644 index 000000000..5ecd0d90d --- /dev/null +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tsproxystubs.h @@ -0,0 +1,102 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file tsproxystubs.h + * @brief Proxy stubs module macros and structures. + * + */ + +#ifndef TSPROXYSTUBS_H +#define TSPROXYSTUBS_H + +#include "ch.h" +#include "ccportab.h" +#include "tscommon.h" + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ +#define METHOD_MAX_PARAMS 6 +#define STUB_MAX_OPS 32 + +#define OP_PRMDIR_NONE 0 +#define OP_PRMDIR_IN 1 +#define OP_PRMDIR_OUT 2 + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +typedef enum {FREE=0, CALLING, PENDING} op_state_t; +typedef struct stub_ctx stub_ctx_t; + +typedef struct stub_param { + uint32_t dir; + uint32_t val; + uint32_t size; +} stub_parm_t; + +typedef struct stub_op { + uint32_t op_code; /* the stub method op code.*/ + op_state_t op_state; /* calling, pending, free.*/ + stub_parm_t op_p[METHOD_MAX_PARAMS]; + thread_reference_t op_wthdp; /* TS internal client thread (the caller).*/ + stub_ctx_t *scp; /* the stub ctx this stub_op relates to.*/ +} stub_op_t; + +typedef struct stub_ctx { + eventflags_t event_flag; + objects_fifo_t ops_fifo; + msg_t ops_msgs[STUB_MAX_OPS]; + stub_op_t ops[STUB_MAX_OPS]; +} stub_ctx_t; + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void tsWaitStubSkelReady(eventflags_t mask); + void TsStubService(ts_state_t *svcp, stub_ctx_t *scp); + uint32_t callRemote(stub_op_t *op); + stub_op_t *getNewOp(stub_ctx_t *scp); +#ifdef __cplusplus +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* TSPROXYSTUBS_H */ diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockets.h b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockets.h new file mode 100644 index 000000000..7d8ecb59e --- /dev/null +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockets.h @@ -0,0 +1,74 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file tssockets.h + */ + +#ifndef TSSOCKETS_H +#define TSSOCKETS_H + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ +#define socket ts_socket +#define connect ts_connect +#define send ts_send +#define recv ts_recv +#define select ts_select +#define close ts_close +#define bind ts_bind +#define listen ts_listen +#define write ts_write +#define read ts_read +#define getaddrinfo ts_getaddrinfo +#define freeaddrinfo ts_freeaddrinfo + +#define fd_set ts_fd_set +#define timeval ts_timeval + +#define FD_ZERO TS_FD_ZERO +#define FD_SET TS_FD_SET +#define FD_CLR TS_FD_CLR +#define FD_ISSET TS_FD_ISSET +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +#endif /* TSSOCKETS_H */ diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.c b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.c index 00dcd2626..9c800a3c5 100644 --- a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.c +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.c @@ -23,6 +23,7 @@ #include "ch.h" #include "chobjfifos.h" #include "chtssi.h" +#include "tsproxystubs.h" #include "tssockstub.h" #include #include @@ -31,13 +32,6 @@ /* Module local definitions. */ /*===========================================================================*/ -#define METHOD_MAX_PARAMS 6 -#define STUB_MAX_OPS 32 - -#define OP_PRMDIR_NONE 0 -#define OP_PRMDIR_IN 1 -#define OP_PRMDIR_OUT 2 - /*===========================================================================*/ /* Module exported variables. */ /*===========================================================================*/ @@ -45,231 +39,35 @@ /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ -typedef struct stub_op stub_op_t; -typedef enum {FREE=0, CALLING, PENDING} op_state_t; - -typedef struct stub_param { - uint32_t dir; - uint32_t val; - uint32_t size; -} stub_parm_t; - -typedef struct stub_op { - uint32_t op_code; /* e.g. connect, recv, sendv, close, etc.*/ - op_state_t op_state; /* calling, pending, free.*/ - stub_parm_t op_p[METHOD_MAX_PARAMS]; - thread_reference_t op_wthdp; /* TS internal client thread (the caller).*/ -} stub_op_t; /*===========================================================================*/ /* Module local variables. */ /*===========================================================================*/ - -static objects_fifo_t ops_fifo; -static msg_t ops_msgs[STUB_MAX_OPS]; -static struct stub_op ops[STUB_MAX_OPS] = {0}; -static bool tsSkelIsReady = false; +static stub_ctx_t stub_ctx; /*===========================================================================*/ /* Module local functions. */ /*===========================================================================*/ -static bool isOpValid(stub_op_t *op) -{ - if ((op < &ops[0]) || (op >= &ops[STUB_MAX_OPS])) - return FALSE; - if (((char *)op - (char *)&ops[0]) % sizeof ops[0]) - return FALSE; - return TRUE; -} - -/** - * @brief Implement an a call to a NSEC function. - * @details It activates the channel between the stubs service and - * the skels daemon running in the nsec world. - * To do it, it uses an event to signal the skels - * daemon that a new op request is ready to be executed. - * Behind the scenes, the skels daemon will then gets the op, calling - * the stubs service via smc. The daemon executes it and then calls - * the stubs service again to post the result and to wake up the - * calling thread of this function. - * - * @param[in] op the 'remote' method description. - * - * @return the return value of 'remote' method. - */ -static uint32_t callRemote(stub_op_t *op) { - uint32_t r; - - chSysLock(); - chFifoSendObjectI(&ops_fifo, op); - chEvtBroadcastFlagsI(&tsEventSource, EVT_F_SOCK_NEW_OP); - chThdSuspendS(&op->op_wthdp); - chSysUnlock(); - r = op->op_code; - chFifoReturnObject(&ops_fifo, op); - return r; -} - -static stub_op_t *getNewOp(void) { - stub_op_t *op = chFifoTakeObjectTimeout(&ops_fifo, TIME_INFINITE); - memset(op, 0, sizeof *op); - op->op_state = CALLING; - return op; -} - /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ /** - * @brief The stubs service. - * @details And this is where the magic happens. + * @brief The sockets stub service. */ -THD_WORKING_AREA(waTsStubsService, 1024); -THD_FUNCTION(TsStubsService, tsstate) { - ts_state_t *svcp = tsstate; - skel_req_t *skrp; - stub_op_t *op; - msg_t r; - int i; - - chFifoObjectInit(&ops_fifo, sizeof (stub_op_t), STUB_MAX_OPS, - sizeof (uint8_t), ops, ops_msgs); - for (;/* ever */;) { - - /* Wait a service request.*/ - (void)tssiWaitRequest(svcp); - skrp = (skel_req_t *)TS_GET_DATA(svcp); - r = SMC_SVC_OK; - - /* Process the request.*/ - if (TS_GET_DATALEN(svcp) != sizeof (skel_req_t)) { - TS_SET_STATUS(svcp, SMC_SVC_INVALID); - continue; - } - - switch (skrp->req) { - case SKEL_REQ_READY: - tsSkelIsReady = true; - break; - - case SKEL_REQ_GETOP: - - /* The nsec skeleton calls us to get a new op ready to be executed.*/ - if (chFifoReceiveObjectTimeout(&ops_fifo, (void **)&op, TIME_IMMEDIATE) == - MSG_TIMEOUT) { - - /* no op ready to be executed.*/ - r = SMC_SVC_NHND; - break; - } - skrp->stub_op = (uint32_t)op; - skrp->stub_op_code = op->op_code; - - /* Pass all the 'by value' arguments from stub to skel.*/ - for (i = 0; i < METHOD_MAX_PARAMS; ++i) { - if (op->op_p[i].dir == OP_PRMDIR_NONE) - skrp->stub_op_p[i] = op->op_p[i].val; - } - op->op_state = PENDING; - break; - - case SKEL_REQ_CPYPRMS: - - /* The nsec skel calls us to get a copy of the 'in' parameters of - the specified op. - An 'in' parameter is an indirect argument, that is an argument - the value of which is a pointer to a memory buffer, that - must be copied in a non secure memory buffer. - It represents data to be consumed by the callee.*/ - op = (stub_op_t *)skrp->stub_op; - if (!isOpValid(op) || op->op_state != PENDING || - op->op_code != skrp->stub_op_code) { - r = SMC_SVC_INVALID; - break; - } - - /* Copy all 'in' parameters. - For each parameter check that the destination memory area - is in the non secure memory arena.*/ - for (i = 0; i < METHOD_MAX_PARAMS; ++i) { - if ((op->op_p[i].dir & OP_PRMDIR_IN) == 0) - continue; - if (!tsIsAddrSpaceValid((void *)skrp->stub_op_p[i], op->op_p[i].size)) { - r = SMC_SVC_INVALID; - break; - } - memcpy((void *)skrp->stub_op_p[i], (void *)op->op_p[i].val, - op->op_p[i].size); - } - break; - - case SKEL_REQ_PUTRES: - - /* The nsec skel calls us to put a copy of the 'out' parameters of - the specified op. - An 'out' parameter is an indirect argument, that is an argument - the value of which is a pointer to a memory buffer, that - must be copied in a secure memory buffer. - It represents data produced by the callee.*/ - op = (stub_op_t *)skrp->stub_op; - if (!isOpValid(op) || op->op_state != PENDING || - op->op_code != skrp->stub_op_code) { - r = SMC_SVC_INVALID; - break; - } - - /* Copy all 'out' parameters. - For each parameter check that the source memory area - is in the non secure memory arena, and that the size returned - fits in the caller buffer size.*/ - for (i = 0; i < METHOD_MAX_PARAMS; ++i) { - if ((op->op_p[i].dir & OP_PRMDIR_OUT) == 0) - continue; - if (!tsIsAddrSpaceValid((void *)skrp->stub_op_p[i], skrp->stub_op_p_sz[i]) - || (skrp->stub_op_p_sz[i] > op->op_p[i].size)) { - r = SMC_SVC_INVALID; - break; - } - memcpy((void *)op->op_p[i].val, (void *)skrp->stub_op_p[i], - skrp->stub_op_p_sz[i]); - } - if (r != SMC_SVC_OK) - break; - - /* Set the return value of the 'remote' callee method, - and wake up the caller.*/ - op->op_code = skrp->stub_op_result; - chThdResume(&op->op_wthdp, MSG_OK); - break; - - default: - r = SMC_SVC_INVALID; - break; - } - - /* Set the response.*/ - TS_SET_STATUS(svcp, r); - } -} -/** - * @brief Is the skeletons daemon ready to operate? - * @details It is used at the startup to synchronize the - * stub service with the skeleton daemon. - */ -void tsWaitStubSkelReady(void) { - while (!tsSkelIsReady) { - chThdSleepMilliseconds(100); - } +THD_WORKING_AREA(waTsSocksStubsService, 1024); +THD_FUNCTION(TsSocksStubsService, tsstatep) { + stub_ctx.event_flag = EVT_F_SOCK_NEW_OP; + TsStubService((ts_state_t *)tsstatep, &stub_ctx); } /** * @brief The sockets API. */ int socket(int domain, int type, int protocol) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_SOCKET; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_SOCKET; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)domain; op->op_p[1].dir = OP_PRMDIR_NONE; @@ -280,8 +78,8 @@ int socket(int domain, int type, int protocol) { } int connect(int s, const struct sockaddr *name, socklen_t namelen) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_CONNECT; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_CONNECT; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; op->op_p[1].dir = OP_PRMDIR_IN; @@ -293,16 +91,16 @@ int connect(int s, const struct sockaddr *name, socklen_t namelen) { } int close(int s) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_CLOSE; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_CLOSE; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; return (int)callRemote(op); } int recv(int s, void *mem, size_t len, int flags) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_RECV; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_RECV; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; op->op_p[1].dir = OP_PRMDIR_OUT; @@ -316,8 +114,8 @@ int recv(int s, void *mem, size_t len, int flags) { } int send(int s, const void *dataptr, size_t size, int flags) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_SEND; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_SEND; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; op->op_p[1].dir = OP_PRMDIR_IN; @@ -332,8 +130,8 @@ int send(int s, const void *dataptr, size_t size, int flags) { int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_SELECT; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_SELECT; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)maxfdp1; op->op_p[1].dir = OP_PRMDIR_IN|OP_PRMDIR_OUT; @@ -352,8 +150,8 @@ int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, } int bind(int s, const struct sockaddr *name, socklen_t namelen) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_BIND; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_BIND; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; op->op_p[1].dir = OP_PRMDIR_IN; @@ -365,8 +163,8 @@ int bind(int s, const struct sockaddr *name, socklen_t namelen) { } int listen(int s, int backlog) { - stub_op_t *op = getNewOp(); - op->op_code = STUB_OP_LISTEN; + stub_op_t *op = getNewOp(&stub_ctx); + op->op_code = SOCK_OP_LISTEN; op->op_p[0].dir = OP_PRMDIR_NONE; op->op_p[0].val = (uint32_t)s; op->op_p[1].dir = OP_PRMDIR_NONE; diff --git a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.h b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.h index 937caa29a..e91edf42e 100644 --- a/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.h +++ b/demos/ATSAMA5D2/RT-SAMA5D2-XPLAINED-SEC/proxies/tssockstub.h @@ -28,7 +28,7 @@ #include "ch.h" #include "ccportab.h" -#include "tscommon.h" + /*===========================================================================*/ /* Module constants. */ /*===========================================================================*/ @@ -376,9 +376,8 @@ extern "C" { int listen(int s, int backlog); in_addr_t inet_addr(const char *cp); int inet_aton(const char *cp, struct in_addr *addr); - void tsWaitStubSkelReady(void); - THD_FUNCTION(TsStubsService, tsstate); - extern THD_WORKING_AREA(waTsStubsService, 1024); + THD_FUNCTION(TsSocksStubsService, tsstatep); + extern THD_WORKING_AREA(waTsSocksStubsService, 1024); #ifdef __cplusplus } #endif -- cgit v1.2.3