From 5a0c56d9b4d7076ddf8ed762c22519290de3f998 Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Thu, 9 Jun 2016 11:47:00 -0400 Subject: Rename main.c to hsm.c for consistency and a slightly simpler Makefile. --- projects/hsm/Makefile | 13 ++- projects/hsm/hsm.c | 226 ++++++++++++++++++++++++++++++++++++++++++++++++++ projects/hsm/main.c | 226 -------------------------------------------------- 3 files changed, 232 insertions(+), 233 deletions(-) create mode 100644 projects/hsm/hsm.c delete mode 100644 projects/hsm/main.c diff --git a/projects/hsm/Makefile b/projects/hsm/Makefile index f5546d8..d8fd1f9 100644 --- a/projects/hsm/Makefile +++ b/projects/hsm/Makefile @@ -1,8 +1,7 @@ PROJ = hsm -SRCS = main.c - -OBJS = $(SRCS:.c=.o) +# objs in addition to $(PROJ).o +OBJS = CFLAGS += -I $(LIBHAL_DIR) @@ -10,10 +9,10 @@ LIBS += $(LIBHAL_DIR)/libhal.a $(LIBTFM_DIR)/libtfm.a all: $(PROJ:=.elf) -$(PROJ).elf: $(OBJS) $(BOARD_OBJS) $(LIBS) - $(CC) $(CFLAGS) $^ -o $@ -T$(LDSCRIPT) -g -Wl,-Map=$(PROJ).map - $(OBJCOPY) -O binary $(PROJ).elf $(PROJ).bin - $(SIZE) $(PROJ).elf +%.elf: %.o $(BOARD_OBJS) $(OBJS) $(LIBS) + $(CC) $(CFLAGS) $^ -o $@ -T$(LDSCRIPT) -g -Wl,-Map=$*.map + $(OBJCOPY) -O binary $*.elf $*.bin + $(SIZE) $*.elf clean: rm -f *.o diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c new file mode 100644 index 0000000..79c567b --- /dev/null +++ b/projects/hsm/hsm.c @@ -0,0 +1,226 @@ +/* + * rpc_server.c + * ------------ + * Remote procedure call server-side private API implementation. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is the main RPC server moddule. It creates a new thread to deal + * with each request, to prevent a long-running request (e.g. RSA keygen) + * from blocking independent requests from other clients. This has a + * number of consequences. We can't do a blocking receive in the main + * thread, because that prevents the dispatch thread from transmitting the + * response (because they both want to lock the UART - see + * stm32f4xx_hal_uart.c). So we have to do a non-blocking receive with a + * callback routine. But we can't create a thread from the callback + * routine, because it's in the context of an ISR, so we raise a semaphore + * for the main thread to create the dispatch thread. + */ + +#include + +#include "cmsis_os.h" + +#include "stm-init.h" +#include "stm-led.h" +#include "stm-fmc.h" +#include "stm-uart.h" + +/* stm32f4xx_hal_def.h and hal.h both define HAL_OK as an enum value */ +#define HAL_OK HAL_OKAY + +#include "hal.h" +#include "hal_internal.h" +#include "slip_internal.h" +#include "xdr_internal.h" + +/* RPC buffers. For each active RPC, there will be two - input and output. + */ + +#ifndef NUM_RPC_BUFFER +/* An arbitrary number, but we don't expect to have more than 8 concurrent + * RPC requests. + */ +#define NUM_RPC_BUFFER 16 +#endif + +#ifndef MAX_PKT_SIZE +/* Another arbitrary number, more or less driven by the 4096-bit RSA + * keygen test. + */ +#define MAX_PKT_SIZE 4096 +#endif + +/* The thread entry point takes a single void* argument, so we bundle the + * packet buffer and length arguments together. + */ +typedef struct { + size_t len; + uint8_t buf[MAX_PKT_SIZE]; +} rpc_buffer_t; + +osPoolDef(rpc_buffer_pool, NUM_RPC_BUFFER, rpc_buffer_t); +osPoolId rpc_buffer_pool; + +static rpc_buffer_t *rpc_buffer_alloc(void) +{ + return (rpc_buffer_t *)osPoolCAlloc(rpc_buffer_pool); +} + +/* A mutex to arbitrate concurrent UART transmits, from RPC responses. + */ +osMutexId uart_mutex; +osMutexDef(uart_mutex); + +/* Thread entry point for the RPC request handler. + */ +static void dispatch_thread(void const *args) +{ + rpc_buffer_t *ibuf = (rpc_buffer_t *)args; + rpc_buffer_t *obuf = rpc_buffer_alloc(); + if (obuf == NULL) { + uint8_t buf[8]; + uint8_t * bufptr = &buf[4]; + const uint8_t * const limit = buf + sizeof(buf); + memcpy(buf, ibuf->buf, 4); + hal_xdr_encode_int(&bufptr, limit, HAL_ERROR_ALLOCATION_FAILURE); + osMutexWait(uart_mutex, osWaitForever); + hal_rpc_sendto(ibuf->buf, sizeof(buf), NULL); + osMutexRelease(uart_mutex); + osPoolFree(rpc_buffer_pool, ibuf); + Error_Handler(); + } + /* copy client ID from request to response */ + memcpy(obuf->buf, ibuf->buf, 4); + obuf->len = sizeof(obuf->buf) - 4; + hal_rpc_server_dispatch(ibuf->buf + 4, ibuf->len - 4, obuf->buf + 4, &obuf->len); + osPoolFree(rpc_buffer_pool, ibuf); + osMutexWait(uart_mutex, osWaitForever); + hal_error_t ret = hal_rpc_sendto(obuf->buf, obuf->len + 4, NULL); + osMutexRelease(uart_mutex); + osPoolFree(rpc_buffer_pool, obuf); + if (ret != HAL_OK) + Error_Handler(); +} +osThreadDef(dispatch_thread, osPriorityNormal, DEFAULT_STACK_SIZE); + +/* Semaphore to inform the main thread that there's a new RPC request. + */ +osSemaphoreId rpc_sem; +osSemaphoreDef(rpc_sem); + +static uint8_t c; /* current character received from UART */ +static rpc_buffer_t *ibuf; /* current RPC input buffer */ + +/* Callback for HAL_UART_Receive_IT(). + */ +void HAL_UART2_RxCpltCallback(UART_HandleTypeDef *huart) +{ + int complete; + hal_slip_recv_char(ibuf->buf, &ibuf->len, sizeof(ibuf->buf), &complete); + if (complete) + osSemaphoreRelease(rpc_sem); + + HAL_UART_Receive_IT(huart, &c, 1); +} + +hal_error_t hal_serial_send_char(uint8_t c) +{ + return (uart_send_char(c) == 0) ? HAL_OK : HAL_ERROR_RPC_TRANSPORT; +} + +hal_error_t hal_serial_recv_char(uint8_t *cp) +{ + /* return the character from HAL_UART_Receive_IT */ + *cp = c; + return HAL_OK; +} + +/* The main thread. After the system setup, it waits for the RPC-request + * semaphore from HAL_UART_RxCpltCallback, and spawns a dispatch thread. + */ +int main() +{ + stm_init(); + +#ifdef TARGET_CRYPTECH_DEV_BRIDGE + /* Wait six seconds to not upset the Novena at boot. */ + led_on(LED_BLUE); + for (int i = 0; i < 12; i++) { + osDelay(500); + led_toggle(LED_BLUE); + } + led_off(LED_BLUE); +#endif + led_on(LED_GREEN); + /* Prepare FMC interface. */ + fmc_init(); + + /* Haaaack. probe_cores() calls malloc(), which works from the main + * thread, but not from a spawned thread. It would be better to + * rewrite it to use static memory, but for now, just force it to + * probe early. + */ + hal_core_iterate(NULL); + + rpc_buffer_pool = osPoolCreate(osPool(rpc_buffer_pool)); + uart_mutex = osMutexCreate(osMutex(uart_mutex)); + rpc_sem = osSemaphoreCreate(osSemaphore(rpc_sem), 0); + +#ifdef TARGET_CRYPTECH_ALPHA + /* Launch other threads: + * - admin thread on USART1 + * - csprng warm-up thread? + */ +#endif + + if (hal_rpc_server_init() != HAL_OK) + Error_Handler(); + + ibuf = rpc_buffer_alloc(); + if (ibuf == NULL) + /* Something is badly wrong. */ + Error_Handler(); + + /* Start the non-blocking receive */ + HAL_UART_Receive_IT(&huart_user, &c, 1); + + while (1) { + osSemaphoreWait(rpc_sem, osWaitForever); + if (osThreadCreate(osThread(dispatch_thread), (void *)ibuf) == NULL) + Error_Handler(); + while ((ibuf = rpc_buffer_alloc()) == NULL); + /* XXX There's a potential race condition, where another request + * could write into the old ibuf, or into the null pointer if + * we're out of ibufs. + */ + } +} diff --git a/projects/hsm/main.c b/projects/hsm/main.c deleted file mode 100644 index 79c567b..0000000 --- a/projects/hsm/main.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * rpc_server.c - * ------------ - * Remote procedure call server-side private API implementation. - * - * Copyright (c) 2016, NORDUnet A/S All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of the NORDUnet nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This is the main RPC server moddule. It creates a new thread to deal - * with each request, to prevent a long-running request (e.g. RSA keygen) - * from blocking independent requests from other clients. This has a - * number of consequences. We can't do a blocking receive in the main - * thread, because that prevents the dispatch thread from transmitting the - * response (because they both want to lock the UART - see - * stm32f4xx_hal_uart.c). So we have to do a non-blocking receive with a - * callback routine. But we can't create a thread from the callback - * routine, because it's in the context of an ISR, so we raise a semaphore - * for the main thread to create the dispatch thread. - */ - -#include - -#include "cmsis_os.h" - -#include "stm-init.h" -#include "stm-led.h" -#include "stm-fmc.h" -#include "stm-uart.h" - -/* stm32f4xx_hal_def.h and hal.h both define HAL_OK as an enum value */ -#define HAL_OK HAL_OKAY - -#include "hal.h" -#include "hal_internal.h" -#include "slip_internal.h" -#include "xdr_internal.h" - -/* RPC buffers. For each active RPC, there will be two - input and output. - */ - -#ifndef NUM_RPC_BUFFER -/* An arbitrary number, but we don't expect to have more than 8 concurrent - * RPC requests. - */ -#define NUM_RPC_BUFFER 16 -#endif - -#ifndef MAX_PKT_SIZE -/* Another arbitrary number, more or less driven by the 4096-bit RSA - * keygen test. - */ -#define MAX_PKT_SIZE 4096 -#endif - -/* The thread entry point takes a single void* argument, so we bundle the - * packet buffer and length arguments together. - */ -typedef struct { - size_t len; - uint8_t buf[MAX_PKT_SIZE]; -} rpc_buffer_t; - -osPoolDef(rpc_buffer_pool, NUM_RPC_BUFFER, rpc_buffer_t); -osPoolId rpc_buffer_pool; - -static rpc_buffer_t *rpc_buffer_alloc(void) -{ - return (rpc_buffer_t *)osPoolCAlloc(rpc_buffer_pool); -} - -/* A mutex to arbitrate concurrent UART transmits, from RPC responses. - */ -osMutexId uart_mutex; -osMutexDef(uart_mutex); - -/* Thread entry point for the RPC request handler. - */ -static void dispatch_thread(void const *args) -{ - rpc_buffer_t *ibuf = (rpc_buffer_t *)args; - rpc_buffer_t *obuf = rpc_buffer_alloc(); - if (obuf == NULL) { - uint8_t buf[8]; - uint8_t * bufptr = &buf[4]; - const uint8_t * const limit = buf + sizeof(buf); - memcpy(buf, ibuf->buf, 4); - hal_xdr_encode_int(&bufptr, limit, HAL_ERROR_ALLOCATION_FAILURE); - osMutexWait(uart_mutex, osWaitForever); - hal_rpc_sendto(ibuf->buf, sizeof(buf), NULL); - osMutexRelease(uart_mutex); - osPoolFree(rpc_buffer_pool, ibuf); - Error_Handler(); - } - /* copy client ID from request to response */ - memcpy(obuf->buf, ibuf->buf, 4); - obuf->len = sizeof(obuf->buf) - 4; - hal_rpc_server_dispatch(ibuf->buf + 4, ibuf->len - 4, obuf->buf + 4, &obuf->len); - osPoolFree(rpc_buffer_pool, ibuf); - osMutexWait(uart_mutex, osWaitForever); - hal_error_t ret = hal_rpc_sendto(obuf->buf, obuf->len + 4, NULL); - osMutexRelease(uart_mutex); - osPoolFree(rpc_buffer_pool, obuf); - if (ret != HAL_OK) - Error_Handler(); -} -osThreadDef(dispatch_thread, osPriorityNormal, DEFAULT_STACK_SIZE); - -/* Semaphore to inform the main thread that there's a new RPC request. - */ -osSemaphoreId rpc_sem; -osSemaphoreDef(rpc_sem); - -static uint8_t c; /* current character received from UART */ -static rpc_buffer_t *ibuf; /* current RPC input buffer */ - -/* Callback for HAL_UART_Receive_IT(). - */ -void HAL_UART2_RxCpltCallback(UART_HandleTypeDef *huart) -{ - int complete; - hal_slip_recv_char(ibuf->buf, &ibuf->len, sizeof(ibuf->buf), &complete); - if (complete) - osSemaphoreRelease(rpc_sem); - - HAL_UART_Receive_IT(huart, &c, 1); -} - -hal_error_t hal_serial_send_char(uint8_t c) -{ - return (uart_send_char(c) == 0) ? HAL_OK : HAL_ERROR_RPC_TRANSPORT; -} - -hal_error_t hal_serial_recv_char(uint8_t *cp) -{ - /* return the character from HAL_UART_Receive_IT */ - *cp = c; - return HAL_OK; -} - -/* The main thread. After the system setup, it waits for the RPC-request - * semaphore from HAL_UART_RxCpltCallback, and spawns a dispatch thread. - */ -int main() -{ - stm_init(); - -#ifdef TARGET_CRYPTECH_DEV_BRIDGE - /* Wait six seconds to not upset the Novena at boot. */ - led_on(LED_BLUE); - for (int i = 0; i < 12; i++) { - osDelay(500); - led_toggle(LED_BLUE); - } - led_off(LED_BLUE); -#endif - led_on(LED_GREEN); - /* Prepare FMC interface. */ - fmc_init(); - - /* Haaaack. probe_cores() calls malloc(), which works from the main - * thread, but not from a spawned thread. It would be better to - * rewrite it to use static memory, but for now, just force it to - * probe early. - */ - hal_core_iterate(NULL); - - rpc_buffer_pool = osPoolCreate(osPool(rpc_buffer_pool)); - uart_mutex = osMutexCreate(osMutex(uart_mutex)); - rpc_sem = osSemaphoreCreate(osSemaphore(rpc_sem), 0); - -#ifdef TARGET_CRYPTECH_ALPHA - /* Launch other threads: - * - admin thread on USART1 - * - csprng warm-up thread? - */ -#endif - - if (hal_rpc_server_init() != HAL_OK) - Error_Handler(); - - ibuf = rpc_buffer_alloc(); - if (ibuf == NULL) - /* Something is badly wrong. */ - Error_Handler(); - - /* Start the non-blocking receive */ - HAL_UART_Receive_IT(&huart_user, &c, 1); - - while (1) { - osSemaphoreWait(rpc_sem, osWaitForever); - if (osThreadCreate(osThread(dispatch_thread), (void *)ibuf) == NULL) - Error_Handler(); - while ((ibuf = rpc_buffer_alloc()) == NULL); - /* XXX There's a potential race condition, where another request - * could write into the old ibuf, or into the null pointer if - * we're out of ibufs. - */ - } -} -- cgit v1.2.3