[Cryptech-Commits] [sw/stm32] 02/03: Reconstruct the hashsig hash tree(s) on device restart.

git at cryptech.is git at cryptech.is
Fri Apr 20 01:06:38 UTC 2018


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch hashsig
in repository sw/stm32.

commit 0f55f31aaa35357b87e7ff817e2683ba1a277193
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Thu Apr 19 16:30:22 2018 -0400

    Reconstruct the hashsig hash tree(s) on device restart.
    
    This can take long enough (several minutes for h=10) that we do it in a
    background task, which is then converted to an RPC dispatch task.
    
    Also add a very limited form of free(), to free the topmost allocation in
    the sdram "heap". I don't want to deal with real heap management, but I do
    want to be able to recover memory upon deleting a hashsig key, if it's
    easy to do so.
---
 projects/hsm/hsm.c | 74 +++++++++++++++++++++++++++++++++++++++++++-----------
 spiflash_n25q128.c |  2 +-
 task.c             | 22 ++++++++++++++--
 task.h             |  1 +
 4 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c
index d971f14..c9d8d28 100644
--- a/projects/hsm/hsm.c
+++ b/projects/hsm/hsm.c
@@ -341,36 +341,73 @@ 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"
+#include "hashsig.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();
 
-    static uint8_t *sdram_heap = &_esdram1;
+    /* 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;
+
+/* 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;
+}
 
+/* 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)
@@ -430,8 +467,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. */
@@ -453,4 +496,7 @@ int main(void)
 
     /* Start the tasker */
     task_yield();
+
+    /*NOTREACHED*/
+    return 0;
 }
diff --git a/spiflash_n25q128.c b/spiflash_n25q128.c
index 5e10185..df53f19 100644
--- a/spiflash_n25q128.c
+++ b/spiflash_n25q128.c
@@ -197,7 +197,7 @@ HAL_StatusTypeDef n25q128_write_page(struct spiflash_ctx *ctx, uint32_t page_off
 }
 
 
-static int n25q128_erase_something(struct spiflash_ctx *ctx, uint8_t command, uint32_t byte_offset)
+static HAL_StatusTypeDef n25q128_erase_something(struct spiflash_ctx *ctx, uint8_t command, uint32_t byte_offset)
 {
     // check offset
     if (byte_offset >= N25Q128_NUM_BYTES) return HAL_ERROR;
diff --git a/task.c b/task.c
index 36e8580..34daa24 100644
--- a/task.c
+++ b/task.c
@@ -131,6 +131,24 @@ tcb_t *task_add(char *name, funcp_t func, void *cookie, void *stack, size_t stac
     return t;
 }
 
+/* Reinitalize the current task.
+ * NOTE: This will destroy any state in the running task.
+ * DO NOT CALL THIS UNLESS YOU ARE REALLY SURE THAT'S WHAT YOU WANT TO DO.
+ */
+void task_mod(char *name, funcp_t func, void *cookie)
+{
+    tcb_t *t = cur_task;
+    t->name = name;
+    t->func = func;
+    t->cookie = cookie;
+    t->state = TASK_INIT;
+    t->stack_ptr = t->stack_base + t->stack_len;
+    for (uint32_t *p = (uint32_t *)t->stack_base; p < (uint32_t *)t->stack_ptr; ++p)
+        *p = STACK_GUARD_WORD;
+    __set_MSP((uint32_t)cur_task->stack_ptr);
+    task_yield();
+}
+
 /* Set the idle hook function pointer.
  *
  * This function is called repeatedly when the system is idle (there are
@@ -232,11 +250,11 @@ void task_yield(void)
     /* If there are no other runnable tasks (and cur_task is runnable),
      * we don't need to context-switch.
      */
-    if (next == cur_task)
+    if (next == cur_task && cur_task->state != TASK_INIT)
         return;
 
     /* Save current context, if there is one. */
-    if (cur_task != NULL) {
+    if (cur_task != NULL && cur_task->state != TASK_INIT) {
         __asm("push {r0-r12, lr}");
         cur_task->stack_ptr = (void *)__get_MSP();
 
diff --git a/task.h b/task.h
index 47d62d6..a71f2e4 100644
--- a/task.h
+++ b/task.h
@@ -51,6 +51,7 @@ typedef struct { unsigned locked; } task_mutex_t;
 typedef void (*funcp_t)(void);
 
 extern tcb_t *task_add(char *name, funcp_t func, void *cookie, void *stack, size_t stack_len);
+extern void task_mod(char *name, funcp_t func, void *cookie);
 
 extern void task_set_idle_hook(funcp_t func);
 



More information about the Commits mailing list