[Cryptech-Commits] [sw/libhal] 06/08: Further keystore cleanup and consolidation.

git at cryptech.is git at cryptech.is
Sun May 28 22:51:55 UTC 2017


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

sra at hactrn.net pushed a commit to branch ks9
in repository sw/libhal.

commit f59533ee9807832ea5ca7dd5492592c8991a9f34
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sun May 28 12:11:31 2017 -0400

    Further keystore cleanup and consolidation.
    
    Still not yet expected to compile, much less run, but getting closer.
---
 Makefile                 |   4 +-
 hal_internal.h           |  20 +-----
 ks.c                     |  26 ++++---
 ks.h                     |   7 +-
 ks_flash.c => ks_token.c | 181 ++++++++++++++++++++++++++---------------------
 ks_volatile.c            | 143 +++++++++++++++++++++----------------
 6 files changed, 210 insertions(+), 171 deletions(-)

diff --git a/Makefile b/Makefile
index e688837..f3a5979 100644
--- a/Makefile
+++ b/Makefile
@@ -137,7 +137,7 @@ endif
 # volatile keystore is always present, to support things like PKCS #11
 # "session" objects.
 
-KS_OBJ = ks.o ks_index.o ks_attribute.o ks_volatile.o ks_flash.o mkm.o
+KS_OBJ = ks.o ks_index.o ks_attribute.o ks_volatile.o ks_token.o mkm.o
 
 # RPC_MODE = none | server | client-simple | client-mixed
 #   none:		Build without RPC client, use cores directly.
@@ -268,7 +268,7 @@ asn1.o rsa.o ecdsa.o:				asn1_internal.h
 ecdsa.o:					ecdsa_curves.h
 novena-eim.o hal_io_eim.o:			novena-eim.h
 slip.o rpc_client_serial.o rpc_server_serial.o:	slip_internal.h
-ks_flash.o:					last_gasp_pin_internal.h
+ks_token.o:					last_gasp_pin_internal.h
 
 last_gasp_pin_internal.h:
 	./utils/last_gasp_default_pin >$@
diff --git a/hal_internal.h b/hal_internal.h
index 89dfbbb..667c5a4 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -479,24 +479,8 @@ typedef struct {
 
 typedef struct hal_ks hal_ks_t;
 
-#error Minor re-think needed on keystore init
-
-// I like current hal_ks_*_init() setup method, but how does anything
-// get a handle on the keystore?  Make the keystores global variables?
-// Right now they're hidden in larger, driver-specific structures, but
-// it would be easy enough to break them out.  Have already forgotten
-// how the old API handled this, except that it involved an init
-// method via the driver.  Init is going to be special in any case,
-// since we can't dispatch through a driver pointer in the keystore
-// object, so either we expose the keystore and the driver or we
-// expose the keystore and the init function.  The latter may be
-// simpler.
-//
-// Another variation would be to keep the current nesting, add global
-// pointer variables for the keystores, and have the init functions
-// set the pointers.  Only real advantage there is that it would give
-// us an easy test for whether the keystore had been initialized...but
-// we already have several of those, not clear what value another adds.
+extern hal_ks_t * const hal_ks_token;
+extern hal_ks_t * const hal_ks_volatile;
 
 /*
  * RPC lowest-level send and receive routines. These are blocking, and
diff --git a/ks.c b/ks.c
index f0c71cc..3d1ae61 100644
--- a/ks.c
+++ b/ks.c
@@ -221,24 +221,31 @@ static inline void *gnaw(uint8_t **mem, size_t *len, const size_t size)
 
 #warning Call hal_ks_alloc_common() and hal_ks_init_common() while holding hal_ks_lock(); !
 
-hal_error_t hal_ks_alloc_common(hal_ks_t *ks, const unsigned ks_blocks, const unsigned cache_blocks)
+hal_error_t hal_ks_alloc_common(hal_ks_t *ks,
+                                const unsigned ks_blocks,
+                                const unsigned cache_blocks,
+                                void **extra,
+                                const size_t extra_len)
 {
   /*
-   * We allocate a single big chunk of memory rather than three
-   * smaller chunks to make it atomic.  We need all three, so this way
-   * either all succeed or all fail.
+   * We allocate a single big chunk of memory to make it atomic.  We
+   * need all three of our blocks, so this way either all succeed or
+   * all fail; we allow our caller to piggyback its own memory needs
+   * (if any) on ours for the same reason.
    */
 
   size_t len = (sizeof(*ks->index) * ks_blocks +
                 sizeof(*ks->names) * ks_blocks +
-                sizeof(*ks->cache) * cache_blocks);
+                sizeof(*ks->cache) * cache_blocks +
+                extra_len);
 
   uint8_t *mem = hal_allocate_static_memory(len);
 
   if (mem == NULL)
     return HAL_ERROR_ALLOCATION_FAILURE;
 
-  memset(ks,  0, sizeof(*ks));
+  memset(((uint8_t *) ks) + sizeof(hal_ks_driver_t), 0,
+         sizeof(hal_ks_t) - sizeof(hal_ks_driver_t));
   memset(mem, 0, len);
 
   ks->index = gnaw(&mem, &len, sizeof(*ks->index) * ks_blocks);
@@ -248,10 +255,13 @@ hal_error_t hal_ks_alloc_common(hal_ks_t *ks, const unsigned ks_blocks, const un
   ks->size       = ks_blocks;
   ks->cache_size = cache_blocks;
 
+  if (extra != NULL)
+    *extra = mem;
+
   return HAL_OK;
 }
 
-hal_error_t hal_ks_init_common(hal_ks_t *ks, const hal_ks_driver_t * const driver)
+hal_error_t hal_ks_init_common(hal_ks_t *ks)
 {
   if (ks->index == NULL || ks->names == NULL || ks->cache == NULL)
     return HAL_ERROR_IMPOSSIBLE;
@@ -447,8 +457,6 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks, const hal_ks_driver_t * const drive
    * And we're finally done.
    */
 
-  ks->driver = driver;
-
   return HAL_OK;
 }
 
diff --git a/ks.h b/ks.h
index b24f3c0..29965cc 100644
--- a/ks.h
+++ b/ks.h
@@ -186,8 +186,10 @@ typedef struct {
  * themselves are stored, that's up to the keystore driver.
  */
 
+typedef struct hal_ks_driver hal_ks_driver_t;
+
 struct hal_ks {
-  const hal_ks_driver_t *driver;
+  const hal_ks_driver_t *driver;/* Must be first */
   unsigned size;                /* Blocks in keystore */
   unsigned used;                /* How many blocks are in use */
   uint16_t *index;              /* Index/freelist array */
@@ -209,10 +211,9 @@ struct hal_ks {
  * function pointers and a set of static inline wrapper functions.
  */
 
-typedef struct hal_ks_driver hal_ks_driver_t;
-
 #define KS_DRIVER_END_LIST
 #define KS_DRIVER_METHODS                                                                               \
+  KS_DRIVER_METHOD(init,        hal_ks_t *ks, const int alloc)                                          \
   KS_DRIVER_METHOD(read,        hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)            \
   KS_DRIVER_METHOD(write,       hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)            \
   KS_DRIVER_METHOD(deprecate,   hal_ks_t *ks, const unsigned blockno)                                   \
diff --git a/ks_flash.c b/ks_token.c
similarity index 73%
rename from ks_flash.c
rename to ks_token.c
index e5a83ea..cc25ca5 100644
--- a/ks_flash.c
+++ b/ks_token.c
@@ -1,5 +1,5 @@
 /*
- * ks_flash.c
+ * ks_token.c
  * ----------
  * Keystore implementation in flash memory.
  *
@@ -56,18 +56,29 @@
 #include "stm-keystore.h"
 #undef HAL_OK
 
-#ifndef KS_FLASH_CACHE_SIZE
-#define KS_FLASH_CACHE_SIZE 4
+#ifndef KS_TOKEN_CACHE_SIZE
+#define KS_TOKEN_CACHE_SIZE 4
 #endif
 
 #define NUM_FLASH_BLOCKS        KEYSTORE_NUM_SUBSECTORS
 
-static struct db {
+/*
+ * Keystore database.
+ */
+
+typedef struct {
   hal_ks_t              ks;                  /* Must be first (C "subclassing") */
   hal_ks_pin_t          wheel_pin;
   hal_ks_pin_t          so_pin;
   hal_ks_pin_t          user_pin;
-} db;
+} ks_token_db_t;
+
+/*
+ * This is a bit silly, but it's safe enough, and it lets us avoid a
+ * nasty mess of forward references.
+ */
+
+#define db      ((ks_token_db_t * const) hal_ks_token)
 
 /*
  * PIN block gets the all-zeros UUID, which will never be returned by
@@ -76,12 +87,11 @@ static struct db {
 
 const static hal_uuid_t pin_uuid = {{0}};
 
-
 /*
  * Calculate offset of the block in the flash address space.
  */
 
-static inline uint32_t block_offset(const unsigned blockno)
+static inline uint32_t ks_token_offset(const unsigned blockno)
 {
   return blockno * KEYSTORE_SUBSECTOR_SIZE;
 }
@@ -93,9 +103,9 @@ static inline uint32_t block_offset(const unsigned blockno)
  * first page before reading the rest of the block.
  */
 
-static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_token_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
 {
-  if (ks != &db.ks || block == NULL || blockno >= NUM_FLASH_BLOCKS || sizeof(*block) != KEYSTORE_SUBSECTOR_SIZE)
+  if (ks != hal_ks_token || block == NULL || blockno >= NUM_FLASH_BLOCKS || sizeof(*block) != KEYSTORE_SUBSECTOR_SIZE)
     return HAL_ERROR_IMPOSSIBLE;
 
   /* Sigh, magic numeric return codes */
@@ -105,19 +115,19 @@ static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *b
     return HAL_ERROR_KEYSTORE_ACCESS;
 
   switch (block_get_type(block)) {
-  case BLOCK_TYPE_ERASED:
-  case BLOCK_TYPE_ZEROED:
+  case HAL_KS_BLOCK_TYPE_ERASED:
+  case HAL_KS_BLOCK_TYPE_ZEROED:
     return HAL_OK;
-  case BLOCK_TYPE_KEY:
-  case BLOCK_TYPE_PIN:
+  case HAL_KS_BLOCK_TYPE_KEY:
+  case HAL_KS_BLOCK_TYPE_PIN:
     break;
   default:
     return HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE;
   }
 
   switch (block_get_status(block)) {
-  case BLOCK_STATUS_LIVE:
-  case BLOCK_STATUS_TOMBSTONE:
+  case HAL_KS_BLOCK_STATUS_LIVE:
+  case HAL_KS_BLOCK_STATUS_TOMBSTONE:
     break;
   default:
     return HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE;
@@ -141,20 +151,20 @@ static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *b
  * need to update the CRC for this, we just modify the first page.
  */
 
-static hal_error_t block_deprecate(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_deprecate(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || blockno >= NUM_FLASH_BLOCKS)
+  if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
 
   uint8_t page[KEYSTORE_PAGE_SIZE];
   flash_block_header_t *header = (void *) page;
-  uint32_t offset = block_offset(blockno);
+  uint32_t offset = ks_token_offset(blockno);
 
   /* Sigh, magic numeric return codes */
   if (keystore_read_data(offset, page, sizeof(page)) != 1)
     return HAL_ERROR_KEYSTORE_ACCESS;
 
-  header->block_status = BLOCK_STATUS_TOMBSTONE;
+  header->block_status = HAL_KS_BLOCK_STATUS_TOMBSTONE;
 
   /* Sigh, magic numeric return codes */
   if (keystore_write_data(offset, page, sizeof(page)) != 1)
@@ -167,9 +177,9 @@ static hal_error_t block_deprecate(hal_k_t *ks, const unsigned blockno)
  * Zero (not erase) a flash block.  Just need to zero the first page.
  */
 
-static hal_error_t block_zero(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_zero(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || blockno >= NUM_FLASH_BLOCKS)
+  if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
 
   uint8_t page[KEYSTORE_PAGE_SIZE] = {0};
@@ -182,12 +192,12 @@ static hal_error_t block_zero(hal_k_t *ks, const unsigned blockno)
 }
 
 /*
- * Erase a flash block.  Also see block_erase_maybe(), below.
+ * Erase a flash block.  Also see ks_token_erase_maybe(), below.
  */
 
-static hal_error_t block_erase(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_erase(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || blockno >= NUM_FLASH_BLOCKS)
+  if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
 
   /* Sigh, magic numeric return codes */
@@ -207,14 +217,14 @@ static hal_error_t block_erase(hal_k_t *ks, const unsigned blockno)
  * leak information about, eg, key length, so we do constant time.
  */
 
-static hal_error_t block_erase_maybe(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_erase_maybe(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || blockno >= NUM_FLASH_BLOCKS)
+  if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
 
   uint8_t mask = 0xFF;
 
-  for (uint32_t a = block_offset(blockno); a < block_offset(blockno + 1); a += KEYSTORE_PAGE_SIZE) {
+  for (uint32_t a = ks_token_offset(blockno); a < ks_token_offset(blockno + 1); a += KEYSTORE_PAGE_SIZE) {
     uint8_t page[KEYSTORE_PAGE_SIZE];
     if (keystore_read_data(a, page, sizeof(page)) != 1)
       return HAL_ERROR_KEYSTORE_ACCESS;
@@ -222,26 +232,26 @@ static hal_error_t block_erase_maybe(hal_k_t *ks, const unsigned blockno)
       mask &= page[i];
   }
 
-  return mask == 0xFF ? HAL_OK : block_erase(blockno);
+  return mask == 0xFF ? HAL_OK : ks_token_erase(blockno);
 }
 
 /*
  * Write a flash block, calculating CRC when appropriate.
  */
 
-static hal_error_t block_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_token_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
 {
-  if (ks != &db.ks || block == NULL || blockno >= NUM_FLASH_BLOCKS || sizeof(*block) != KEYSTORE_SUBSECTOR_SIZE)
+  if (ks != hal_ks_token || block == NULL || blockno >= NUM_FLASH_BLOCKS || sizeof(*block) != KEYSTORE_SUBSECTOR_SIZE)
     return HAL_ERROR_IMPOSSIBLE;
 
-  hal_error_t err = block_erase_maybe(blockno);
+  hal_error_t err = ks_token_erase_maybe(blockno);
 
   if (err != HAL_OK)
     return err;
 
   switch (block_get_type(block)) {
-  case BLOCK_TYPE_KEY:
-  case BLOCK_TYPE_PIN:
+  case HAL_KS_BLOCK_TYPE_KEY:
+  case HAL_KS_BLOCK_TYPE_PIN:
     block->header.crc = calculate_block_crc(block);
     break;
   default:
@@ -259,7 +269,7 @@ static hal_error_t block_write(hal_k_t *ks, const unsigned blockno, ks_block_t *
  * The token keystore doesn't implement per-session objects, so these are no-ops.
  */
 
-static hal_error_t block_set_owner(hal_ks_t *ks,
+static hal_error_t ks_token_set_owner(hal_ks_t *ks,
                                    const unsigned blockno,
                                    const hal_client_handle_t client,
                                    const hal_session_handle_t session)
@@ -267,7 +277,7 @@ static hal_error_t block_set_owner(hal_ks_t *ks,
   return HAL_OK;
 }
 
-static hal_error_t block_test_owner(hal_ks_t *ks, const
+static hal_error_t ks_token_test_owner(hal_ks_t *ks, const
                                     unsigned blockno,
                                     const hal_client_handle_t client,
                                     const hal_session_handle_t session)
@@ -285,43 +295,35 @@ static hal_error_t fetch_pin_block(unsigned *b, ks_block_t **block);
  * Initialize keystore.
  */
 
-static const hal_ks_driver_t hal_ks_token_driver[1] = {{
-  .read               	= block_read,
-  .write                = block_write,
-  .deprecate		= block_deprecate,
-  .zero                 = block_zero,
-  .erase                = block_erase,
-  .erase_maybe		= block_erase_maybe,
-  .set_owner            = block_set_owner,
-  .test_owner           = block_test_owner
-}};
-
-hal_error_t hal_ks_token_init(const int alloc)
+static hal_error_t ks_token_init(hal_ks_t *ks, const int alloc)
 {
+  if (ks != hal_ks_token)
+    return HAL_ERROR_IMPOSSIBLE;
+
   hal_error_t err = HAL_OK;
 
   hal_ks_lock();
 
-  if (alloc && (err = hal_ks_alloc_common(&db.ks, NUM_FLASH_BLOCKS, KS_FLASH_CACHE_SIZE)) != HAL_OK)
+  if (alloc && (err = hal_ks_alloc_common(ks, NUM_FLASH_BLOCKS, KS_TOKEN_CACHE_SIZE, NULL, 0)) != HAL_OK)
     goto done;
 
-  if ((err = hal_ks_init_common(ks, hal_ks_token_driver)) != HAL_OK)
+  if ((err = hal_ks_init_common(ks)) != HAL_OK)
     goto done;
 
   /*
    * Fetch or create the PIN block.
    */
 
-  memset(&db.wheel_pin, 0, sizeof(db.wheel_pin));
-  memset(&db.so_pin,    0, sizeof(db.so_pin));
-  memset(&db.user_pin,  0, sizeof(db.user_pin));
+  memset(&db->wheel_pin, 0, sizeof(db->wheel_pin));
+  memset(&db->so_pin,    0, sizeof(db->so_pin));
+  memset(&db->user_pin,  0, sizeof(db->user_pin));
 
   err = fetch_pin_block(NULL, &block);
 
   if (err == HAL_OK) {
-    db.wheel_pin = block->pin.wheel_pin;
-    db.so_pin    = block->pin.so_pin;
-    db.user_pin  = block->pin.user_pin;
+    db->wheel_pin = block->pin.wheel_pin;
+    db->so_pin    = block->pin.so_pin;
+    db->user_pin  = block->pin.user_pin;
   }
 
   else if (err != HAL_ERROR_KEY_NOT_FOUND)
@@ -340,19 +342,19 @@ hal_error_t hal_ks_token_init(const int alloc)
 
     memset(block, 0xFF, sizeof(*block));
 
-    block->header.block_type   = BLOCK_TYPE_PIN;
-    block->header.block_status = BLOCK_STATUS_LIVE;
+    block->header.block_type   = HAL_KS_BLOCK_TYPE_PIN;
+    block->header.block_status = HAL_KS_BLOCK_STATUS_LIVE;
 
-    block->pin.wheel_pin = db.wheel_pin = hal_last_gasp_pin;
-    block->pin.so_pin    = db.so_pin;
-    block->pin.user_pin  = db.user_pin;
+    block->pin.wheel_pin = db->wheel_pin = hal_last_gasp_pin;
+    block->pin.so_pin    = db->so_pin;
+    block->pin.user_pin  = db->user_pin;
 
-    if ((err = hal_ks_index_add(&db.ksi, &pin_uuid, &b, NULL)) != HAL_OK)
+    if ((err = hal_ks_index_add(ks, &pin_uuid, &b, NULL)) != HAL_OK)
       goto done;
 
     cache_mark_used(block, b);
 
-    err = block_write(b, block);
+    err = ks_token_write(b, block);
 
     cache_release(block);
 
@@ -368,6 +370,27 @@ hal_error_t hal_ks_token_init(const int alloc)
 }
 
 /*
+ * Dispatch vector and keystore definition, now that we've defined all
+ * the driver functions.
+ */
+
+static const hal_ks_driver_t ks_token_driver = {
+  .init                 = ks_token_init,
+  .read               	= ks_token_read,
+  .write                = ks_token_write,
+  .deprecate		= ks_token_deprecate,
+  .zero                 = ks_token_zero,
+  .erase                = ks_token_erase,
+  .erase_maybe		= ks_token_erase_maybe,
+  .set_owner            = ks_token_set_owner,
+  .test_owner           = ks_token_test_owner
+};
+
+static ks_token_db_t _db = { .ks.driver = &ks_token_driver };
+
+hal_ks_t * const hal_ks_token = &_db.ks;
+
+/*
  * The remaining functions aren't really part of the keystore API per se,
  * but they all involve non-key data which we keep in the keystore
  * because it's the flash we've got.
@@ -390,14 +413,14 @@ void hal_ks_init_read_only_pins_only(void)
   hal_ks_lock();
 
   for (b = 0; b < NUM_FLASH_BLOCKS; b++) {
-    if (block_read(b, block) != HAL_OK || block_get_type(block) != BLOCK_TYPE_PIN)
+    if (block_read(b, block) != HAL_OK || ks_token_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
       continue;
     best_seen = b;
-    if (block_get_status(block) == BLOCK_STATUS_LIVE)
+    if (block_get_status(block) == HAL_KS_BLOCK_STATUS_LIVE)
       break;
   }
 
-  if (b != best_seen && best_seen != ~0 && block_read(best_seen, block) != HAL_OK)
+  if (b != best_seen && best_seen != ~0 && ks_token_read(best_seen, block) != HAL_OK)
     best_seen = ~0;
 
   if (best_seen == ~0) {
@@ -405,9 +428,9 @@ void hal_ks_init_read_only_pins_only(void)
     block->pin.wheel_pin = hal_last_gasp_pin;
   }
 
-  db.wheel_pin = block->pin.wheel_pin;
-  db.so_pin    = block->pin.so_pin;
-  db.user_pin  = block->pin.user_pin;
+  db->wheel_pin = block->pin.wheel_pin;
+  db->so_pin    = block->pin.so_pin;
+  db->user_pin  = block->pin.user_pin;
 
   hal_ks_unlock();
 }
@@ -427,9 +450,9 @@ hal_error_t hal_get_pin(const hal_user_t user,
   hal_ks_lock();
 
   switch (user) {
-  case HAL_USER_WHEEL:  *pin = &db.wheel_pin;  break;
-  case HAL_USER_SO:     *pin = &db.so_pin;     break;
-  case HAL_USER_NORMAL: *pin = &db.user_pin;   break;
+  case HAL_USER_WHEEL:  *pin = &db->wheel_pin;  break;
+  case HAL_USER_SO:     *pin = &db->so_pin;     break;
+  case HAL_USER_NORMAL: *pin = &db->user_pin;   break;
   default:               err = HAL_ERROR_BAD_ARGUMENTS;
   }
 
@@ -455,13 +478,13 @@ static hal_error_t fetch_pin_block(unsigned *b, ks_block_t **block)
   if (b == NULL)
     b = &b_;
 
-  if ((err = hal_ks_index_find(&db.ksi, &pin_uuid, b, &hint))   != HAL_OK ||
-      (err = block_read_cached(*b, block))                      != HAL_OK)
+  if ((err = hal_ks_index_find(hal_ks_token, &pin_uuid, b, &hint)) != HAL_OK ||
+      (err = ks_token_read_cached(*b, block))                      != HAL_OK)
     return err;
 
   cache_mark_used(*block, *b);
 
-  if (block_get_type(*block) != BLOCK_TYPE_PIN)
+  if (block_get_type(*block) != HAL_KS_BLOCK_TYPE_PIN)
     return HAL_ERROR_IMPOSSIBLE;
 
   return HAL_OK;
@@ -478,14 +501,14 @@ static hal_error_t update_pin_block(const unsigned b,
                                     ks_block_t *block,
                                     const flash_pin_block_t * const new_data)
 {
-  if (block == NULL || new_data == NULL || block_get_type(block) != BLOCK_TYPE_PIN)
+  if (block == NULL || new_data == NULL || ks_token_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
     return HAL_ERROR_IMPOSSIBLE;
 
   int hint = 0;
 
   block->pin = *new_data;
 
-  return block_update(b, block, &pin_uuid, &hint);
+  return ks_token_update(b, block, &pin_uuid, &hint);
 }
 
 /*
@@ -511,9 +534,9 @@ hal_error_t hal_set_pin(const hal_user_t user,
   hal_ks_pin_t *dp, *bp;
 
   switch (user) {
-  case HAL_USER_WHEEL:  bp = &new_data.wheel_pin; dp = &db.wheel_pin; break;
-  case HAL_USER_SO:     bp = &new_data.so_pin;    dp = &db.so_pin;    break;
-  case HAL_USER_NORMAL: bp = &new_data.user_pin;  dp = &db.user_pin;  break;
+  case HAL_USER_WHEEL:  bp = &new_data.wheel_pin; dp = &db->wheel_pin; break;
+  case HAL_USER_SO:     bp = &new_data.so_pin;    dp = &db->so_pin;    break;
+  case HAL_USER_NORMAL: bp = &new_data.user_pin;  dp = &db->user_pin;  break;
   default:              err = HAL_ERROR_BAD_ARGUMENTS;  goto done;
   }
 
diff --git a/ks_volatile.c b/ks_volatile.c
index e9a0ef4..7e1a5f2 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -51,27 +51,38 @@
 #define KS_VOLATILE_CACHE_SIZE 4
 #endif
 
+/*
+ * Keystore database.
+ */
+
 typedef struct {
   hal_client_handle_t   client;
   hal_session_handle_t  session;
   hal_ks_block_t	block;
-} volatile_key_t;
+} ks_volatile_key_t;
 
-static struct db {
+typedef struct {
   hal_ks_t ks;              /* Must be first */
-  volatile_key_t *keys;
-} db;
+  ks_volatile_key_t *keys;
+} ks_volatile_db_t;
+
+/*
+ * This is a bit silly, but it's safe enough, and it lets us avoid a
+ * nasty mess of forward references.
+ */
+
+#define db      ((ks_volatile_db_t * const) hal_ks_volatile)
 
 /*
  * Read a block.  CRC probably not necessary for RAM.
  */
 
-static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_volatile_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
 {
-  if (ks != &db.ks || db.keys == NULL || block == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || block == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  memcpy(block, &db.keys[blockno].block, sizeof(*block));
+  memcpy(block, &db->keys[blockno].block, sizeof(*block));
 
   return HAL_OK;
 }
@@ -80,12 +91,12 @@ static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *b
  * Convert a live block into a tombstone.
  */
 
-static hal_error_t block_deprecate(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_deprecate(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || db.keys == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  db.keys[blockno].block.header->block_status = BLOCK_STATUS_TOMBSTONE;
+  db->keys[blockno].block.header->block_status = BLOCK_STATUS_TOMBSTONE;
 
   return HAL_OK;
 }
@@ -94,14 +105,14 @@ static hal_error_t block_deprecate(hal_k_t *ks, const unsigned blockno)
  * Zero (not erase) a flash block.
  */
 
-static hal_error_t block_zero(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_zero(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || db.keys == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  memset(db.keys[blockno].block, 0x00, sizeof(db.keys[blockno].block));
-  db.keys[blockno].client.handle = HAL_HANDLE_NONE;
-  db.keys[blockno].session.handle = HAL_HANDLE_NONE;
+  memset(db->keys[blockno].block, 0x00, sizeof(db->keys[blockno].block));
+  db->keys[blockno].client.handle = HAL_HANDLE_NONE;
+  db->keys[blockno].session.handle = HAL_HANDLE_NONE;
 
   return HAL_OK;
 }
@@ -110,14 +121,14 @@ static hal_error_t block_zero(hal_k_t *ks, const unsigned blockno)
  * Erase a flash block.
  */
 
-static hal_error_t block_erase(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_erase(hal_k_t *ks, const unsigned blockno)
 {
-  if (ks != &db.ks || db.keys == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  memset(db.keys[blockno].block, 0xFF, sizeof(db.keys[blockno].block));
-  db.keys[blockno].client.handle = HAL_HANDLE_NONE;
-  db.keys[blockno].session.handle = HAL_HANDLE_NONE;
+  memset(db->keys[blockno].block, 0xFF, sizeof(db->keys[blockno].block));
+  db->keys[blockno].client.handle = HAL_HANDLE_NONE;
+  db->keys[blockno].session.handle = HAL_HANDLE_NONE;
 
   return HAL_OK;
 }
@@ -126,12 +137,12 @@ static hal_error_t block_erase(hal_k_t *ks, const unsigned blockno)
  * Write a flash block.  CRC probably not necessary for RAM.
  */
 
-static hal_error_t block_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_volatile_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
 {
-  if (ks != &db.ks || db.keys == NULL || block == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || block == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  memcpy(&db.keys[blockno].block, block, sizeof(*block));
+  memcpy(&db->keys[blockno].block, block, sizeof(*block));
 
   return HAL_OK;
 }
@@ -140,16 +151,16 @@ static hal_error_t block_write(hal_k_t *ks, const unsigned blockno, ks_block_t *
  * Set key ownership.
  */
 
-static hal_error_t block_set_owner(hal_ks_t *ks,
-                                   const unsigned blockno,
-                                   const hal_client_handle_t client,
-                                   const hal_session_handle_t session)
+static hal_error_t ks_volatile_set_owner(hal_ks_t *ks,
+                                         const unsigned blockno,
+                                         const hal_client_handle_t client,
+                                         const hal_session_handle_t session)
 {
-  if (ks != &db.ks || db.keys == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  db.keys[blockno].client = client;
-  db.keys[blockno].session = session;
+  db->keys[blockno].client = client;
+  db->keys[blockno].session = session;
 
   return HAL_OK;
 }
@@ -158,16 +169,16 @@ static hal_error_t block_set_owner(hal_ks_t *ks,
  * Test key ownership.
  */
 
-static hal_error_t block_test_owner(hal_ks_t *ks, const
-                                    unsigned blockno,
-                                    const hal_client_handle_t client,
-                                    const hal_session_handle_t session)
+static hal_error_t ks_volatile_test_owner(hal_ks_t *ks, const
+                                          unsigned blockno,
+                                          const hal_client_handle_t client,
+                                          const hal_session_handle_t session)
 {
-  if (ks != &db.ks || db.keys == NULL || blockno >= ks->size)
+  if (ks != hal_ks_volatile || db->keys == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
 
-  if (db.keys[blockno].client.handle  == client.handle &&
-      db.keys[blockno].session.handle == session.handle)
+  if (db->keys[blockno].client.handle  == client.handle &&
+      db->keys[blockno].session.handle == session.handle)
     return HAL_OK;
   else
     return HAL_ERROR_KEY_NOT_FOUND;
@@ -177,37 +188,28 @@ static hal_error_t block_test_owner(hal_ks_t *ks, const
  * Initialize keystore.
  */
 
-static const hal_ks_driver_t hal_ks_volatile_driver[1] = {{
-  .read               	= block_read,
-  .write                = block_write,
-  .deprecate		= block_deprecate,
-  .zero                 = block_zero,
-  .erase                = block_erase,
-  .erase_maybe		= block_erase, /* sic */
-  .set_owner            = block_set_owner,
-  .test_owner           = block_test_owner
-}};
-
- hal_error_t hal_ks_volatile_init(const int alloc)
+static hal_error_t ks_volatile_init(hal_ks_t *ks, const int alloc)
 {
+  if (ks != hal_ks_volatile)
+    return HAL_ERROR_IMPOSSIBLE;
+
   hal_error_t err = HAL_OK;
+  void *mem = NULL;
 
   hal_ks_lock();
 
+  if (alloc) {
+    if ((err = hal_ks_alloc_common(ks, STATIC_KS_VOLATILE_SLOTS, KS_VOLATILE_CACHE_SIZE,
+                                   &mem, sizeof(*db->keys) * STATIC_KS_VOLATILE_SLOTS)) != HAL_OK)
+      goto done;
+    db->keys = mem;
+  }
 
-  if (alloc && (err = hal_ks_alloc_common(&db.ks, STATIC_KS_VOLATILE_SLOTS, KS_VOLATILE_CACHE_SIZE)) != HAL_OK)
-    goto done;
-
-  if ((err = hal_ks_init_common(&db.ks, hal_ks_volatile_driver)) != HAL_OK)
-    goto done;
-
-  if (alloc && (db.keys = hal_allocate_static_memory(sizeof(*db.keys) * db.ks.size)) == NULL) {
-    err = HAL_ERROR_ALLOCATION_FAILURE;
+  if ((err = hal_ks_init_common(ks)) != HAL_OK)
     goto done;
-  }
 
-  for (unsigned b = 0; b < db.ks.size; i++)
-    if ((err = block_erase(&db.ks, b)) != HAL_OK)
+  for (unsigned b = 0; b < db->ks.size; i++)
+    if ((err = block_erase(ks, b)) != HAL_OK)
       goto done;
 
   err = HAL_OK;
@@ -218,6 +220,27 @@ static const hal_ks_driver_t hal_ks_volatile_driver[1] = {{
 }
 
 /*
+ * Dispatch vector and keystore definition, now that we've defined all
+ * the driver functions.
+ */
+
+static const hal_ks_driver_t hal_ks_volatile_driver = {
+  .init                 = ks_volatile_init,
+  .read               	= ks_volatile_read,
+  .write                = ks_volatile_write,
+  .deprecate		= ks_volatile_deprecate,
+  .zero                 = ks_volatile_zero,
+  .erase                = ks_volatile_erase,
+  .erase_maybe		= ks_volatile_erase, /* sic */
+  .set_owner            = ks_volatile_set_owner,
+  .test_owner           = ks_volatile_test_owner
+};
+
+static ks_volatile_db_t _db = { .ks.driver = &ks_volatile_driver };
+
+hal_ks_t * const hal_ks_volatile = &_db.ks;
+
+/*
  * Local variables:
  * indent-tabs-mode: nil
  * End:



More information about the Commits mailing list