diff options
Diffstat (limited to 'projects')
-rw-r--r-- | projects/cli-test/cli-test.c | 6 | ||||
-rw-r--r-- | projects/hsm/Makefile | 1 | ||||
-rw-r--r-- | projects/hsm/hsm.c | 107 | ||||
-rw-r--r-- | projects/hsm/mgmt-keystore.c | 51 | ||||
-rw-r--r-- | projects/hsm/mgmt-masterkey.c | 90 | ||||
-rw-r--r-- | projects/hsm/mgmt-task.c | 6 | ||||
-rw-r--r-- | projects/libhal-test/main.c | 1 |
7 files changed, 205 insertions, 57 deletions
diff --git a/projects/cli-test/cli-test.c b/projects/cli-test/cli-test.c index 82946fa..c0fe57e 100644 --- a/projects/cli-test/cli-test.c +++ b/projects/cli-test/cli-test.c @@ -88,3 +88,9 @@ void *hal_allocate_static_memory(const size_t size) { return NULL; } + +int hal_free_static_memory(const void * const ptr) +{ + return 0; +} + diff --git a/projects/hsm/Makefile b/projects/hsm/Makefile index 3430e14..37c552d 100644 --- a/projects/hsm/Makefile +++ b/projects/hsm/Makefile @@ -25,7 +25,6 @@ LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 LDFLAGS += -Wl,--gc-sections ifdef DO_PROFILING -OBJS += $(TOPLEVEL)/memfunc.o LDFLAGS += --specs=rdimon.specs -lc -lrdimon endif diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c index 64529f6..52157c9 100644 --- a/projects/hsm/hsm.c +++ b/projects/hsm/hsm.c @@ -86,27 +86,19 @@ static uint8_t busy_stack[BUSY_STACK_SIZE]; * 4096-byte block of an FPGA or bootloader image upload. */ #ifndef CLI_STACK_SIZE -#define CLI_STACK_SIZE 8*1024 -#endif -static uint8_t cli_stack[CLI_STACK_SIZE]; - -#ifndef MAX_PKT_SIZE -/* An arbitrary number, more or less driven by the 4096-bit RSA - * keygen test. - */ -#define MAX_PKT_SIZE 4096 +#define CLI_STACK_SIZE 16*1024 #endif /* RPC buffers. For each active request, there will be two - input and output. */ typedef struct rpc_buffer_s { size_t len; - uint8_t buf[MAX_PKT_SIZE]; + uint8_t buf[HAL_RPC_MAX_PKT_SIZE]; struct rpc_buffer_s *next; /* for ibuf queue linking */ } rpc_buffer_t; /* RPC input (requst) buffers */ -static rpc_buffer_t ibufs[NUM_RPC_TASK]; +static rpc_buffer_t *ibufs; /* ibuf queue structure */ typedef struct { @@ -348,36 +340,83 @@ static void busy_task(void) } } -/* Allocate memory from SDRAM1. There is only malloc, no free, so we don't - * worry about fragmentation. */ -static uint8_t *sdram_malloc(size_t size) +#include "stm-fpgacfg.h" + +static void hashsig_restart_task(void) { - /* end of variables declared with __attribute__((section(".sdram1"))) */ - extern uint8_t _esdram1 __asm ("_esdram1"); - /* end of SDRAM1 section */ - extern uint8_t __end_sdram1 __asm ("__end_sdram1"); + /* wait for the fpga to configure itself on cold-boot */ + while (fpgacfg_check_done() != CMSIS_HAL_OK) + task_yield(); + + /* reinitialize the hashsig key structures after a device restart */ + hal_hashsig_ks_init(); + + /* done, convert this task to an RPC handler */ + task_mod((char *)task_get_cookie(NULL), dispatch_task, NULL); +} + +/* end of variables declared with __attribute__((section(".sdram1"))) */ +extern uint8_t _esdram1 __asm ("_esdram1"); +/* end of SDRAM1 section */ +extern uint8_t __end_sdram1 __asm ("__end_sdram1"); +static uint8_t *sdram_heap = &_esdram1; - static uint8_t *sdram_heap = &_esdram1; +/* Allocate memory from SDRAM1. */ +static uint8_t *sdram_malloc(size_t size) +{ uint8_t *p = sdram_heap; #define pad(n) (((n) + 3) & ~3) size = pad(size); - if (p + size > &__end_sdram1) + if (p + size + sizeof(uint32_t) > &__end_sdram1) return NULL; - sdram_heap += size; + *(uint32_t *)p = (uint32_t)size; + p += sizeof(uint32_t); + + sdram_heap += size + sizeof(uint32_t); return p; } -/* Implement static memory allocation for libhal over sdram_malloc(). - * Once again, there's only alloc, not free. */ +/* A very limited form of free(), which only frees memory if it's at the + * top of the heap. + */ +static hal_error_t sdram_free(uint8_t *ptr) +{ + uint8_t *p = ptr - sizeof(uint32_t); + uint32_t size = *(uint32_t *)p; + if (ptr + size == sdram_heap) { + sdram_heap = p; + return LIBHAL_OK; + } + else + return HAL_ERROR_FORBIDDEN; +} +hal_error_t sdram_stats(size_t *used, size_t *available) +{ + if (used == NULL || available == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + *used = sdram_heap - &_esdram1; + *available = &__end_sdram1 - sdram_heap; + + return LIBHAL_OK; +} + +/* Implement static memory allocation for libhal over sdram_malloc(). + */ void *hal_allocate_static_memory(const size_t size) { return sdram_malloc(size); } +hal_error_t hal_free_static_memory(const void * const ptr) +{ + return sdram_free((uint8_t *)ptr); +} + /* Critical section start/end - temporarily disable interrupts. */ void hal_critical_section_start(void) @@ -431,9 +470,13 @@ int main(void) Error_Handler(); /* Initialize the ibuf queues. */ + ibufs = (rpc_buffer_t *)sdram_malloc(NUM_RPC_TASK * sizeof(rpc_buffer_t)); + if (ibufs == NULL) + Error_Handler(); + memset(ibufs, 0, NUM_RPC_TASK * sizeof(rpc_buffer_t)); memset(&ibuf_waiting, 0, sizeof(ibuf_waiting)); memset(&ibuf_ready, 0, sizeof(ibuf_ready)); - for (size_t i = 0; i < sizeof(ibufs)/sizeof(ibufs[0]); ++i) + for (size_t i = 0; i < NUM_RPC_TASK; ++i) ibuf_put(&ibuf_waiting, &ibufs[i]); /* Create the rpc dispatch worker tasks. */ @@ -443,8 +486,14 @@ int main(void) void *stack = (void *)sdram_malloc(TASK_STACK_SIZE); if (stack == NULL) Error_Handler(); - if (task_add(label[i], dispatch_task, &ibufs[i], stack, TASK_STACK_SIZE) == NULL) - Error_Handler(); + if (i == NUM_RPC_TASK - 1) { + if (task_add("hashsig_restart", hashsig_restart_task, label[i], stack, TASK_STACK_SIZE) == NULL) + Error_Handler(); + } + else { + if (task_add(label[i], dispatch_task, NULL, stack, TASK_STACK_SIZE) == NULL) + Error_Handler(); + } } /* Create the busy task. */ @@ -461,9 +510,13 @@ int main(void) */ /* Create the CLI task. */ - if (task_add("cli", (funcp_t)cli_main, NULL, cli_stack, sizeof(cli_stack)) == NULL) + void *cli_stack = (void *)sdram_malloc(CLI_STACK_SIZE); + if (task_add("cli", (funcp_t)cli_main, NULL, cli_stack, CLI_STACK_SIZE) == NULL) Error_Handler(); /* Start the tasker */ task_yield(); + + /*NOTREACHED*/ + return 0; } diff --git a/projects/hsm/mgmt-keystore.c b/projects/hsm/mgmt-keystore.c index b79a5fe..9eb42da 100644 --- a/projects/hsm/mgmt-keystore.c +++ b/projects/hsm/mgmt-keystore.c @@ -50,6 +50,7 @@ #include <stdlib.h> #include <string.h> +#include <strings.h> #include <ctype.h> @@ -180,6 +181,8 @@ static int cmd_keystore_delete_key(struct cli_def *cli, const char *command, cha return CLI_OK; } +#include "ks.h" + static int show_keys(struct cli_def *cli, const char *title) { const hal_client_handle_t client = { -1 }; @@ -198,6 +201,16 @@ static int show_keys(struct cli_def *cli, const char *title) cli_print(cli, title); + size_t avail; + if ((status = hal_ks_available(hal_ks_token, &avail)) == HAL_OK) + cli_print(cli, "Token keystore: %d available", avail); + else + cli_print(cli, "Error reading token keystore: %s", hal_error_string(status)); + if ((status = hal_ks_available(hal_ks_volatile, &avail)) == HAL_OK) + cli_print(cli, "Volatile keystore: %d available", avail); + else + cli_print(cli, "Error reading volatile keystore: %s", hal_error_string(status)); + while (!done) { if ((status = hal_rpc_pkey_match(client, session, HAL_KEY_TYPE_NONE, HAL_CURVE_NONE, @@ -248,6 +261,10 @@ static int show_keys(struct cli_def *cli, const char *title) case HAL_KEY_TYPE_RSA_PUBLIC: type_name = "RSA public"; break; case HAL_KEY_TYPE_EC_PRIVATE: type_name = "EC private"; break; case HAL_KEY_TYPE_EC_PUBLIC: type_name = "EC public"; break; + case HAL_KEY_TYPE_HASHSIG_PRIVATE: type_name = "hashsig private"; break; + case HAL_KEY_TYPE_HASHSIG_PUBLIC: type_name = "hashsig public"; break; + case HAL_KEY_TYPE_HASHSIG_LMS: type_name = "hashsig lms"; break; + case HAL_KEY_TYPE_HASHSIG_LMOTS: type_name = "hashsig lmots"; break; } const char *curve_name = "unknown"; @@ -304,13 +321,34 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar { hal_error_t err; HAL_StatusTypeDef status; + int preserve_PINs = 0; command = command; - if (argc != 1 || strcmp(argv[0], "YesIAmSure") != 0) { - cli_print(cli, "Syntax: keystore erase YesIAmSure"); + if (argc < 1 || argc > 2 || strcmp(argv[0], "YesIAmSure") != 0) { + usage: + cli_print(cli, "Syntax: keystore erase YesIAmSure [preservePINs]"); return CLI_ERROR; } + if (argc == 2) { + if (strcasecmp(argv[1], "preservePINs") != 0) + goto usage; + else + preserve_PINs = 1; + } + + hal_user_t users[3] = { HAL_USER_NORMAL, HAL_USER_SO, HAL_USER_WHEEL }; + hal_ks_pin_t pins[3]; + if (preserve_PINs) { + for (size_t i = 0; i < 3; ++i) { + const hal_ks_pin_t *pin; + if (hal_get_pin(users[i], &pin) != HAL_OK) { + cli_print(cli, "Failed to get the PINs"); + return CLI_ERROR; + } + memcpy(&pins[i], pin, sizeof(*pin)); + } + } cli_print(cli, "OK, erasing keystore, this will take about 45 seconds..."); if ((status = keystore_erase_bulk()) != CMSIS_HAL_OK) { @@ -328,6 +366,15 @@ static int cmd_keystore_erase(struct cli_def *cli, const char *command, char *ar return CLI_ERROR; } + if (preserve_PINs) { + for (size_t i = 0; i < 3; ++i) { + if (hal_set_pin(users[i], &pins[i]) != HAL_OK) { + cli_print(cli, "Failed to restore the PINs"); + return CLI_ERROR; + } + } + } + cli_print(cli, "Keystore erased"); return CLI_OK; } diff --git a/projects/hsm/mgmt-masterkey.c b/projects/hsm/mgmt-masterkey.c index 765cb10..e63e0e0 100644 --- a/projects/hsm/mgmt-masterkey.c +++ b/projects/hsm/mgmt-masterkey.c @@ -60,24 +60,6 @@ static char * _status2str(const hal_error_t status) } } -static int _parse_hex_groups(uint8_t *buf, size_t len, char *argv[], int argc) -{ - int i; - uint32_t *dst = (uint32_t *) buf; - uint32_t *end = (uint32_t *) buf + len - 1; - char *err_ptr = NULL; - - if (! argc) return 0; - - for (i = 0; i < argc; i++) { - if (dst >= end) return -1; - *dst++ = strtoul(argv[i], &err_ptr, 16); - if (*err_ptr) return -2; - } - - return 1; -} - static int cmd_masterkey_status(struct cli_def *cli, const char *command, char *argv[], int argc) { hal_error_t status; @@ -97,12 +79,54 @@ static int cmd_masterkey_status(struct cli_def *cli, const char *command, char * return CLI_OK; } +static int str_to_hex_digit(char c) +{ + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + c = c - 'A' + 10; + else + return -1; + + return c; +} + +static inline char hex_to_str_digit(const uint8_t c) +{ + return (c < 10) ? ((char)c + '0') : ((char)c + 'A' - 10); +} + +static char *hexdump_kek(const uint8_t * const kek) +{ + /* This is only for dumping masterkey values, so has no length checks. + * Do not use it for anything else. + * + * For convenience of possibly hand-copying and hand-retyping, the key + * is divided into 8 4-byte (8-character) groups. + */ + + static char buf[2 * KEK_LENGTH + 8]; + char *dst = buf; + + for (size_t i = 0; i < KEK_LENGTH; ++i) { + uint8_t b = kek[i]; + *dst++ = hex_to_str_digit(b >> 4); + *dst++ = hex_to_str_digit(b & 0xf); + if ((i & 3) == 3) + *dst++ = ' '; + } + buf[sizeof(buf) - 1] = '\0'; + + return buf; +} + static int _masterkey_set(struct cli_def *cli, char *argv[], int argc, char *label, hal_error_t (*writer)(const uint8_t * const, const size_t)) { uint8_t buf[KEK_LENGTH] = {0}; hal_error_t err; - int i; if (argc == 0) { /* fill master key with yummy randomness */ @@ -110,20 +134,32 @@ static int _masterkey_set(struct cli_def *cli, char *argv[], int argc, cli_print(cli, "Error getting random key: %s", hal_error_string(err)); return CLI_ERROR; } - cli_print(cli, "Random key:\n"); - uart_send_hexdump(buf, 0, sizeof(buf) - 1); - cli_print(cli, "\n"); + cli_print(cli, "Random key:\n%s", hexdump_kek(buf)); } else { - if ((i = _parse_hex_groups(&buf[0], sizeof(buf), argv, argc)) != 1) { - cli_print(cli, "Failed parsing master key, expected up to 8 groups of 32-bit hex chars (%i)", i); + /* input is 32 hex bytes, arranged however the user wants */ + size_t len = 0; + for (int i = 0; i < argc; ++i) { + for (char *cp = argv[i]; *cp != '\0'; ) { + int c; + if ((c = str_to_hex_digit(*cp++)) < 0) + goto errout; + buf[len] = c << 4; + if ((c = str_to_hex_digit(*cp++)) < 0) + goto errout; + buf[len] |= c & 0xf; + if (++len > KEK_LENGTH) + goto errout; + } + } + if (len < KEK_LENGTH) { + errout: + cli_print(cli, "Failed parsing master key, expected exactly %d hex bytes", KEK_LENGTH); return CLI_ERROR; } - cli_print(cli, "Parsed key:\n"); - uart_send_hexdump(buf, 0, sizeof(buf) - 1); - cli_print(cli, "\n"); + cli_print(cli, "Parsed key:\n%s", hexdump_kek(buf)); } if ((err = writer(buf, sizeof(buf))) == LIBHAL_OK) { diff --git a/projects/hsm/mgmt-task.c b/projects/hsm/mgmt-task.c index c2a3d3f..180c6d9 100644 --- a/projects/hsm/mgmt-task.c +++ b/projects/hsm/mgmt-task.c @@ -74,6 +74,12 @@ static int cmd_task_show(struct cli_def *cli, const char *command, char *argv[], cli_print(cli, " "); cli_print(cli, "UART receive queue maximum length: %u", uart_rx_max); + size_t used, available; + extern void sdram_stats(size_t *used, size_t *available); + sdram_stats(&used, &available); + cli_print(cli, " "); + cli_print(cli, "SDRAM used: %u, available: %u", used, available); + return CLI_OK; } diff --git a/projects/libhal-test/main.c b/projects/libhal-test/main.c index fff8c38..c0d9330 100644 --- a/projects/libhal-test/main.c +++ b/projects/libhal-test/main.c @@ -43,6 +43,7 @@ extern void __main(void); int main(void) { stm_init(); + HAL_Delay(500); led_on(LED_GREEN); __main(); |