[Cryptech-Commits] [sw/libhal] 07/08: Almost compiles.

git at cryptech.is git at cryptech.is
Sun May 28 22:51:56 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 2caa6c72640877abc5f3572c4d926a23ff672ab1
Author: Rob Austein <sra at hactrn.net>
AuthorDate: Sun May 28 16:11:25 2017 -0400

    Almost compiles.
    
    Need to refactor init sequence slightly (again), this time to humor
    the bootloader, which has its own special read-only view of the PIN
    block in the token keystore.
---
 cryptech/libhal.py |   5 +-
 hal.h              |   2 +-
 hal_internal.h     |  44 +++++++++++-
 ks.c               | 141 ++++++++++++++++++------------------
 ks.h               | 205 +++++++++++++++++++++++++++++++++++++++--------------
 ks_index.c         |   2 +-
 ks_token.c         | 107 ++++++++++++++--------------
 ks_volatile.c      |  30 ++++----
 rpc_pkey.c         | 118 ++++++------------------------
 rpc_server.c       |  10 ++-
 10 files changed, 359 insertions(+), 305 deletions(-)

diff --git a/cryptech/libhal.py b/cryptech/libhal.py
index 0c6b3f6..39fa826 100644
--- a/cryptech/libhal.py
+++ b/cryptech/libhal.py
@@ -117,10 +117,7 @@ HALError.define(HAL_ERROR_KEYSTORE_LOST_DATA        = "Keystore appears to have
 HALError.define(HAL_ERROR_BAD_ATTRIBUTE_LENGTH      = "Bad attribute length")
 HALError.define(HAL_ERROR_ATTRIBUTE_NOT_FOUND       = "Attribute not found")
 HALError.define(HAL_ERROR_NO_KEY_INDEX_SLOTS        = "No key index slots available")
-HALError.define(HAL_ERROR_KSI_INDEX_UUID_MISORDERED = "Key index UUID misordered")
-HALError.define(HAL_ERROR_KSI_INDEX_CHUNK_ORPHANED  = "Key index chunk orphaned")
-HALError.define(HAL_ERROR_KSI_INDEX_CHUNK_MISSING   = "Key index chunk missing")
-HALError.define(HAL_ERROR_KSI_INDEX_CHUNK_OVERLAPS  = "Key index chunk overlaps")
+HALError.define(HAL_ERROR_KS_INDEX_UUID_MISORDERED  = "Key index UUID misordered")
 HALError.define(HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE = "Wrong block type in keystore")
 HALError.define(HAL_ERROR_RPC_PROTOCOL_ERROR        = "RPC protocol error")
 HALError.define(HAL_ERROR_NOT_IMPLEMENTED           = "Not implemented")
diff --git a/hal.h b/hal.h
index a3ea1dd..47ebe25 100644
--- a/hal.h
+++ b/hal.h
@@ -157,7 +157,7 @@
   DEFINE_HAL_ERROR(HAL_ERROR_BAD_ATTRIBUTE_LENGTH,      "Bad attribute length")                         \
   DEFINE_HAL_ERROR(HAL_ERROR_ATTRIBUTE_NOT_FOUND,       "Attribute not found")                          \
   DEFINE_HAL_ERROR(HAL_ERROR_NO_KEY_INDEX_SLOTS,        "No key index slots available")                 \
-  DEFINE_HAL_ERROR(HAL_ERROR_KSI_INDEX_UUID_MISORDERED, "Key index UUID misordered")                    \
+  DEFINE_HAL_ERROR(HAL_ERROR_KS_INDEX_UUID_MISORDERED,  "Key index UUID misordered")                    \
   DEFINE_HAL_ERROR(HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE, "Wrong block type in keystore")                 \
   DEFINE_HAL_ERROR(HAL_ERROR_RPC_PROTOCOL_ERROR,        "RPC protocol error")                           \
   DEFINE_HAL_ERROR(HAL_ERROR_NOT_IMPLEMENTED,           "Not implemented")                              \
diff --git a/hal_internal.h b/hal_internal.h
index 667c5a4..e998ae3 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -397,8 +397,6 @@ extern hal_error_t hal_get_pin(const hal_user_t user,
 extern hal_error_t hal_set_pin(const hal_user_t user,
                                const hal_ks_pin_t * const pin);
 
-extern void hal_ks_init_read_only_pins_only(void);
-
 /*
  * Master key memory (MKM) and key-encryption-key (KEK).
  *
@@ -482,6 +480,48 @@ typedef struct hal_ks hal_ks_t;
 extern hal_ks_t * const hal_ks_token;
 extern hal_ks_t * const hal_ks_volatile;
 
+extern hal_error_t hal_ks_init(hal_ks_t *ks,
+                               const int alloc);
+
+extern void hal_ks_init_read_only_pins_only(void);
+
+extern hal_error_t hal_ks_store(hal_ks_t *ks,
+                                hal_pkey_slot_t *slot,
+                                const uint8_t * const der, const size_t der_len);
+
+extern hal_error_t hal_ks_fetch(hal_ks_t *ks,
+                                hal_pkey_slot_t *slot,
+                                uint8_t *der, size_t *der_len, const size_t der_max);
+
+extern hal_error_t hal_ks_delete(hal_ks_t *ks,
+                                 hal_pkey_slot_t *slot);
+
+extern hal_error_t hal_ks_match(hal_ks_t *ks,
+                                const hal_client_handle_t client,
+                                const hal_session_handle_t session,
+                                const hal_key_type_t type,
+                                const hal_curve_name_t curve,
+                                const hal_key_flags_t mask,
+                                const hal_key_flags_t flags,
+                                const hal_pkey_attribute_t *attributes,
+                                const unsigned attributes_len,
+                                hal_uuid_t *result,
+                                unsigned *result_len,
+                                const unsigned result_max,
+                                const hal_uuid_t * const previous_uuid);
+
+extern hal_error_t hal_ks_set_attributes(hal_ks_t *ks,
+                                         hal_pkey_slot_t *slot,
+                                         const hal_pkey_attribute_t *attributes,
+                                         const unsigned attributes_len);
+
+extern hal_error_t hal_ks_get_attributes(hal_ks_t *ks,
+                                         hal_pkey_slot_t *slot,
+                                         hal_pkey_attribute_t *attributes,
+                                         const unsigned attributes_len,
+                                         uint8_t *attributes_buffer,
+                                         const size_t attributes_buffer_len);
+
 /*
  * RPC lowest-level send and receive routines. These are blocking, and
  * transport-specific (sockets, USB).
diff --git a/ks.c b/ks.c
index 3d1ae61..a0a4de7 100644
--- a/ks.c
+++ b/ks.c
@@ -40,18 +40,11 @@
 #include "ks.h"
 
 /*
- * Type safe casts.
+ * PIN block gets the all-zeros UUID, which will never be returned by
+ * the UUID generation code (by definition -- it's not a version 4 UUID).
  */
 
-static inline ks_block_type_t block_get_type(const ks_block_t * const block)
-{
-  return block == NULL ? HAL_KS_BLOCK_TYPE_UNKNOWN : (ks_block_type_t) block->header.block_type;
-}
-
-static inline ks_block_status_t block_get_status(const ks_block_t * const block)
-{
-  return block == NULL ? HAL_KS_BLOCK_STATUS_UNKNOWN : (ks_block_status_t) block->header.block_status;
-}
+const hal_uuid_t hal_ks_pin_uuid = {{0}};
 
 /*
  * Pick unused or least-recently-used slot in our in-memory cache.
@@ -61,7 +54,7 @@ static inline ks_block_status_t block_get_status(const ks_block_t * const block)
  * result, leave the lru values alone and the right thing will happen.
  */
 
-static inline hal_ks_block_t *cache_pick_lru(hal_ks_t *ks)
+hal_ks_block_t *hal_ks_cache_pick_lru(hal_ks_t *ks)
 {
   uint32_t best_delta = 0;
   int      best_index = 0;
@@ -87,7 +80,7 @@ static inline hal_ks_block_t *cache_pick_lru(hal_ks_t *ks)
  * Find a block in our in-memory cache; return block or NULL if not present.
  */
 
-static inline hal_ks_block_t *cache_find_block(const hal_ks_t * const ks, const unsigned blockno)
+hal_ks_block_t *hal_ks_cache_find_block(const hal_ks_t * const ks, const unsigned blockno)
 {
   for (int i = 0; i < ks->cache_size; i++)
     if (ks->cache[i].blockno == blockno)
@@ -99,7 +92,7 @@ static inline hal_ks_block_t *cache_find_block(const hal_ks_t * const ks, const
  * Mark a block in our in-memory cache as being in current use.
  */
 
-static inline void cache_mark_used(hal_ks_t *ks, const hal_ks_block_t * const block, const unsigned blockno)
+void hal_ks_cache_mark_used(hal_ks_t *ks, const hal_ks_block_t * const block, const unsigned blockno)
 {
   for (int i = 0; i < ks->cache_size; i++) {
     if (&ks->cache[i].block == block) {
@@ -114,10 +107,10 @@ static inline void cache_mark_used(hal_ks_t *ks, const hal_ks_block_t * const bl
  * Release a block from the in-memory cache.
  */
 
-static inline void cache_release(hal_ks_t *ks, const hal_ks_block_t * const block)
+void hal_ks_cache_release(hal_ks_t *ks, const hal_ks_block_t * const block)
 {
   if (block != NULL)
-    cache_mark_used(block, ~0);
+    hal_ks_cache_mark_used(ks, block, ~0);
 }
 
 /*
@@ -128,7 +121,7 @@ static inline void cache_release(hal_ks_t *ks, const hal_ks_block_t * const bloc
  * shouldn't be included in the CRC.
  */
 
-static hal_crc32_t calculate_block_crc(const hal_ks_block_t * const block)
+hal_crc32_t hal_ks_block_calculate_crc(const hal_ks_block_t * const block)
 {
   hal_crc32_t crc = hal_crc32_init();
 
@@ -151,15 +144,15 @@ static hal_crc32_t calculate_block_crc(const hal_ks_block_t * const block)
  * perform a hal_ks_match() operation.
  */
 
-static hal_error_t block_read_cached(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t **block)
+hal_error_t hal_ks_block_read_cached(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t **block)
 {
   if (block == NULL)
     return HAL_ERROR_IMPOSSIBLE;
 
-  if ((*block = cache_find_block(ks, blockno)) != NULL)
+  if ((*block = hal_ks_cache_find_block(ks, blockno)) != NULL)
     return HAL_OK;
 
-  if ((*block = cache_pick_lru(ks)) == NULL)
+  if ((*block = hal_ks_cache_pick_lru(ks)) == NULL)
     return HAL_ERROR_IMPOSSIBLE;
 
   return hal_ks_block_read(ks, blockno, *block);
@@ -169,11 +162,11 @@ static hal_error_t block_read_cached(hal_ks_t *ks, const unsigned blockno, hal_k
  * Update one block, including zombie jamboree.
  */
 
-static hal_error_t block_update(hal_ks_t *ks,
-                                const unsigned b1,
-                                hal_ks_block_t *block,
-                                const hal_uuid_t * const uuid,
-                                int *hint)
+hal_error_t hal_ks_block_update(hal_ks_t *ks,
+                         const unsigned b1,
+                         hal_ks_block_t *block,
+                         const hal_uuid_t * const uuid,
+                         int *hint)
 {
   if (block == NULL)
     return HAL_ERROR_IMPOSSIBLE;
@@ -181,7 +174,7 @@ static hal_error_t block_update(hal_ks_t *ks,
   if (ks->used == ks->size)
     return HAL_ERROR_NO_KEY_INDEX_SLOTS;
 
-  cache_release(block);
+  hal_ks_cache_release(ks, block);
 
   hal_error_t err;
   unsigned b2;
@@ -192,7 +185,7 @@ static hal_error_t block_update(hal_ks_t *ks,
       (err = hal_ks_block_zero(ks, b1))                 != HAL_OK)
     return err;
 
-  cache_mark_used(ks, block, b2);
+  hal_ks_cache_mark_used(ks, block, b2);
 
   /*
    * Erase the first block in the free list. In case of restart, this
@@ -209,6 +202,14 @@ static hal_error_t block_update(hal_ks_t *ks,
  * recover from unclean shutdown.
  */
 
+hal_error_t hal_ks_init(hal_ks_t *ks, const int alloc)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->init == NULL          ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->init(ks, alloc);
+}
+
 static inline void *gnaw(uint8_t **mem, size_t *len, const size_t size)
 {
   if (mem == NULL || *mem == NULL || len == NULL || size > *len)
@@ -219,8 +220,6 @@ static inline void *gnaw(uint8_t **mem, size_t *len, const size_t size)
   return ret;
 }
 
-#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,
@@ -279,7 +278,7 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
 
   hal_ks_block_type_t   block_types[ks->size];
   hal_ks_block_status_t block_status[ks->size];
-  hal_ks_block_t *block = cache_pick_lru(ks);
+  hal_ks_block_t *block = hal_ks_cache_pick_lru(ks);
   int first_erased = -1;
   hal_error_t err;
   uint16_t n = 0;
@@ -299,28 +298,28 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
     err = hal_ks_block_read(ks, i, block);
 
     if (err == HAL_ERROR_KEYSTORE_BAD_CRC || err == HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE)
-      block_types[i] = BLOCK_TYPE_UNKNOWN;
+      block_types[i] = HAL_KS_BLOCK_TYPE_UNKNOWN;
 
     else if (err == HAL_OK)
-      block_types[i] = block_get_type(block);
+      block_types[i] = hal_ks_block_get_type(block);
 
     else
       return err;
 
     switch (block_types[i]) {
-    case BLOCK_TYPE_KEY:
-    case BLOCK_TYPE_PIN:
-      block_status[i] = block_get_status(block);
+    case HAL_KS_BLOCK_TYPE_KEY:
+    case HAL_KS_BLOCK_TYPE_PIN:
+      block_status[i] = hal_ks_block_get_status(block);
       break;
     default:
-      block_status[i] = BLOCK_STATUS_UNKNOWN;
+      block_status[i] = HAL_KS_BLOCK_STATUS_UNKNOWN;
     }
 
     /*
      * First erased block we see is head of the free list.
      */
 
-    if (block_types[i] == BLOCK_TYPE_ERASED && first_erased < 0)
+    if (block_types[i] == HAL_KS_BLOCK_TYPE_ERASED && first_erased < 0)
       first_erased = i;
 
     /*
@@ -332,8 +331,8 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
     const hal_uuid_t *uuid = NULL;
 
     switch (block_types[i]) {
-    case BLOCK_TYPE_KEY:        uuid = &block->key.name;        break;
-    case BLOCK_TYPE_PIN:        uuid = &pin_uuid;               break;
+    case HAL_KS_BLOCK_TYPE_KEY: uuid = &block->key.name;        break;
+    case HAL_KS_BLOCK_TYPE_PIN: uuid = &hal_ks_pin_uuid;        break;
     default:                    /* Keep GCC happy */            break;
     }
 
@@ -359,22 +358,22 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
 
   if (n < ks->size)
     for (int i = 0; i < ks->size; i++)
-      if (block_types[i] == BLOCK_TYPE_ERASED)
+      if (block_types[i] == HAL_KS_BLOCK_TYPE_ERASED)
         ks->index[n++] = i;
 
   if (n < ks->size)
     for (int i = first_erased; i < ks->size; i++)
-      if (block_types[i] == BLOCK_TYPE_ZEROED)
+      if (block_types[i] == HAL_KS_BLOCK_TYPE_ZEROED)
         ks->index[n++] = i;
 
   if (n < ks->size)
     for (int i = 0; i < first_erased; i++)
-      if (block_types[i] == BLOCK_TYPE_ZEROED)
+      if (block_types[i] == HAL_KS_BLOCK_TYPE_ZEROED)
         ks->index[n++] = i;
 
   if (n < ks->size)
     for (int i = 0; i < ks->size; i++)
-      if (block_types[i] == BLOCK_TYPE_UNKNOWN)
+      if (block_types[i] == HAL_KS_BLOCK_TYPE_UNKNOWN)
         ks->index[n++] = i;
 
   if (ks->used > ks->size)
@@ -396,7 +395,7 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
 
   for (unsigned b_tomb = 0; b_tomb < ks->size; b_tomb++) {
 
-    if (block_status[b_tomb] != BLOCK_STATUS_TOMBSTONE)
+    if (block_status[b_tomb] != HAL_KS_BLOCK_STATUS_TOMBSTONE)
       continue;
 
     hal_uuid_t name = ks->names[b_tomb];
@@ -419,8 +418,8 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
     const int matches_prev = where - 1 >= 0       && !hal_uuid_cmp(&name, &ks->names[ks->index[where - 1]]);
 
     if ((matches_prev && matches_next) ||
-        (matches_prev && block_status[ks->index[b_tomb - 1]] != BLOCK_STATUS_LIVE) ||
-        (matches_next && block_status[ks->index[b_tomb + 1]] != BLOCK_STATUS_LIVE))
+        (matches_prev && block_status[ks->index[b_tomb - 1]] != HAL_KS_BLOCK_STATUS_LIVE) ||
+        (matches_next && block_status[ks->index[b_tomb + 1]] != HAL_KS_BLOCK_STATUS_LIVE))
       return HAL_ERROR_IMPOSSIBLE;
 
     if (matches_prev || matches_next)  {
@@ -432,17 +431,17 @@ hal_error_t hal_ks_init_common(hal_ks_t *ks)
       unsigned b_live;
       if ((err = hal_ks_block_read(ks, b_tomb, block)) != HAL_OK)
         return err;
-      block->header.block_status = BLOCK_STATUS_LIVE;
+      block->header.block_status = HAL_KS_BLOCK_STATUS_LIVE;
       if ((err = hal_ks_index_replace(ks, &name, &b_live, &where)) != HAL_OK ||
           (err = hal_ks_block_write(ks, b_live, block))            != HAL_OK)
         return err;
-      block_status[b_live] = BLOCK_STATUS_LIVE;
+      block_status[b_live] = HAL_KS_BLOCK_STATUS_LIVE;
     }
 
     if ((err = hal_ks_block_zero(ks, b_tomb)) != HAL_OK)
       return err;
-    block_types[ b_tomb] = BLOCK_TYPE_ZEROED;
-    block_status[b_tomb] = BLOCK_STATUS_UNKNOWN;
+    block_types[ b_tomb] = HAL_KS_BLOCK_TYPE_ZEROED;
+    block_status[b_tomb] = HAL_KS_BLOCK_STATUS_UNKNOWN;
   }
 
   /*
@@ -494,7 +493,7 @@ static inline int acceptable_key_type(const hal_key_type_t type)
  * avoid revising this yet again.
  */
 
-static inline hal_error_t key_visible(const hal_ks_t * const ks,
+static inline hal_error_t key_visible(hal_ks_t * const ks,
                                       const hal_client_handle_t client,
                                       const hal_session_handle_t session,
                                       const unsigned blockno)
@@ -507,7 +506,7 @@ static inline hal_error_t key_visible(const hal_ks_t * const ks,
 
   hal_error_t err;
 
-  if ((err = hal_ks_block_test_owner(ks, client, session)) != HAL_OK)
+  if ((err = hal_ks_block_test_owner(ks, blockno, client, session)) != HAL_OK)
     return err;
 
   err = hal_rpc_is_logged_in(client, HAL_USER_WHEEL);
@@ -527,14 +526,14 @@ hal_error_t hal_ks_store(hal_ks_t *ks,
 
   hal_error_t err = HAL_OK;
   hal_ks_block_t *block;
-  flash_key_block_t *k;
+  hal_ks_key_block_t *k;
   uint8_t kek[KEK_LENGTH];
   size_t kek_len;
   unsigned b;
 
   hal_ks_lock();
 
-  if ((block = cache_pick_lru(ks)) == NULL) {
+  if ((block = hal_ks_cache_pick_lru(ks)) == NULL) {
     err = HAL_ERROR_IMPOSSIBLE;
     goto done;
   }
@@ -544,18 +543,18 @@ hal_error_t hal_ks_store(hal_ks_t *ks,
   if ((err = hal_ks_index_add(ks, &slot->name, &b, &slot->hint)) != HAL_OK)
     goto done;
 
-  cache_mark_used(ks, block, b);
+  hal_ks_cache_mark_used(ks, block, b);
 
   memset(block, 0xFF, sizeof(*block));
 
-  block->header.block_type   = BLOCK_TYPE_KEY;
-  block->header.block_status = BLOCK_STATUS_LIVE;
+  block->header.block_type   = HAL_KS_BLOCK_TYPE_KEY;
+  block->header.block_status = HAL_KS_BLOCK_STATUS_LIVE;
 
   k->name    = slot->name;
   k->type    = slot->type;
   k->curve   = slot->curve;
   k->flags   = slot->flags;
-  k->der_len = SIZEOF_FLASH_KEY_BLOCK_DER;
+  k->der_len = SIZEOF_KS_KEY_BLOCK_DER;
   k->attributes_len = 0;
 
   if (ks->used < ks->size)
@@ -579,7 +578,7 @@ hal_error_t hal_ks_store(hal_ks_t *ks,
     goto done;
 
   memset(block, 0, sizeof(*block));
-  cache_release(ks, block);
+  hal_ks_cache_release(ks, block);
   (void) hal_ks_index_delete(ks, &slot->name, NULL, &slot->hint);
 
  done:
@@ -605,14 +604,14 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks,
       (err = hal_ks_block_read_cached(ks, b, &block))                       != HAL_OK)
     goto done;
 
-  if (block_get_type(block) != BLOCK_TYPE_KEY) {
+  if (hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_KEY) {
     err = HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE; /* HAL_ERROR_KEY_NOT_FOUND */
     goto done;
   }
 
-  cache_mark_used(ks, block, b);
+  hal_ks_cache_mark_used(ks, block, b);
 
-  flash_key_block_t *k = &block->key;
+  hal_ks_key_block_t *k = &block->key;
 
   slot->type  = k->type;
   slot->curve = k->curve;
@@ -658,7 +657,7 @@ hal_error_t hal_ks_delete(hal_ks_t *ks,
       (err = key_visible(ks, slot->client_handle, slot->session_handle, b)) != HAL_OK)
     goto done;
 
-  cache_release(ks, cache_find_block(ks, b));
+  hal_ks_cache_release(ks, hal_ks_cache_find_block(ks, b));
 
   if ((err = hal_ks_block_zero(ks, b)) != HAL_OK)
     goto done;
@@ -678,11 +677,11 @@ static inline hal_error_t locate_attributes(hal_ks_block_t *block,
     return HAL_ERROR_IMPOSSIBLE;
 
 
-  if (block_get_type(block) != BLOCK_TYPE_KEY)
+  if (hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_KEY)
     return HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE;
   *attrs_len = &block->key.attributes_len;
   *bytes = block->key.der + block->key.der_len;
-  *bytes_len = SIZEOF_FLASH_KEY_BLOCK_DER - block->key.der_len;
+  *bytes_len = SIZEOF_KS_KEY_BLOCK_DER - block->key.der_len;
 
   return HAL_OK;
 }
@@ -802,11 +801,11 @@ hal_error_t hal_ks_set_attributes(hal_ks_t *ks,
 
   {
     if ((err = hal_ks_index_find(ks, &slot->name, &b, &slot->hint))             != HAL_OK ||
-        (err = key_visibile(ks, slot->client_handle, slot->session_handle, b))  != HAL_OK ||
+        (err = key_visible(ks, slot->client_handle, slot->session_handle, b))   != HAL_OK ||
         (err = hal_ks_block_read_cached(ks, b, &block))                         != HAL_OK)
       goto done;
 
-    cache_mark_used(ks, block, b);
+    hal_ks_cache_mark_used(ks, block, b);
 
     uint8_t *bytes = NULL;
     size_t bytes_len = 0;
@@ -832,9 +831,9 @@ hal_error_t hal_ks_set_attributes(hal_ks_t *ks,
                                       attributes[i].length);
 
     if (err == HAL_OK)
-      err = block_update(ks, b, block, &slot->name, &slot->hint);
+      err = hal_ks_block_update(ks, b, block, &slot->name, &slot->hint);
     else
-      cache_release(ks, block);
+      hal_ks_cache_release(ks, block);
   }
 
  done:
@@ -868,11 +867,11 @@ hal_error_t hal_ks_get_attributes(hal_ks_t *ks,
 
   {
     if ((err = hal_ks_index_find(ks, &slot->name, &b, &slot->hint))             != HAL_OK ||
-        (err = key_visibile(ks, slot->client_handle, slot->session_handle, b))  != HAL_OK ||
-        (err = hal_ks_block_read_cached(ks, b, &block))				!= HAL_OK)
+        (err = key_visible(ks, slot->client_handle, slot->session_handle, b))   != HAL_OK ||
+        (err = hal_ks_block_read_cached(ks, b, &block))                         != HAL_OK)
       goto done;
 
-    cache_mark_used(ks, block, b);
+    hal_ks_cache_mark_used(ks, block, b);
 
     uint8_t *bytes = NULL;
     size_t bytes_len = 0;
diff --git a/ks.h b/ks.h
index 29965cc..6db0bd7 100644
--- a/ks.h
+++ b/ks.h
@@ -46,10 +46,17 @@
  */
 
 #ifndef HAL_KS_BLOCK_SIZE
-#define HAL_KS_BLOCK_SIZE       (KEYSTORE_SUBSECTOR_SIZE * 1)
+#define HAL_KS_BLOCK_SIZE       (4096)
 #endif
 
 /*
+ * PIN block gets the all-zeros UUID, which will never be returned by
+ * the UUID generation code (by definition -- it's not a version 4 UUID).
+ */
+
+const hal_uuid_t hal_ks_pin_uuid;
+
+/*
  * Known block states.
  *
  * C does not guarantee any particular representation for enums, so
@@ -94,7 +101,7 @@ typedef struct {
  */
 
 typedef struct {
-  hal_ks_block_header_t	header;
+  hal_ks_block_header_t header;
   hal_uuid_t            name;
   hal_key_type_t        type;
   hal_curve_name_t      curve;
@@ -102,10 +109,10 @@ typedef struct {
   size_t                der_len;
   unsigned              attributes_len;
   uint8_t               der[];  /* Must be last field -- C99 "flexible array member" */
-} hal_ks_blockkey_block_t;
+} hal_ks_key_block_t;
 
-#define SIZEOF_KS_BLOCKKEY_BLOCK_DER \
-  (HAL_KS_BLOCK_SIZE - offsetof(hal_ks_blockkey_block_t, der))
+#define SIZEOF_KS_KEY_BLOCK_DER \
+  (HAL_KS_BLOCK_SIZE - offsetof(hal_ks_key_block_t, der))
 
 /*
  * PIN block.  Also includes space for backing up the KEK when
@@ -113,7 +120,7 @@ typedef struct {
  */
 
 typedef struct {
-  hal_ks_block_header_t	header;
+  hal_ks_block_header_t header;
   hal_ks_pin_t          wheel_pin;
   hal_ks_pin_t          so_pin;
   hal_ks_pin_t          user_pin;
@@ -121,7 +128,7 @@ typedef struct {
   uint32_t              kek_set;
   uint8_t               kek[KEK_LENGTH];
 #endif
-} hal_ks_blockpin_block_t;
+} hal_ks_pin_block_t;
 
 #define FLASH_KEK_SET   0x33333333
 
@@ -130,10 +137,10 @@ typedef struct {
  */
 
 typedef union {
-  uint8_t		    bytes[HAL_KS_BLOCK_SIZE];
+  uint8_t                   bytes[HAL_KS_BLOCK_SIZE];
   hal_ks_block_header_t     header;
-  hal_ks_blockkey_block_t   key;
-  hal_ks_blockpin_block_t   pin;
+  hal_ks_key_block_t   key;
+  hal_ks_pin_block_t   pin;
 } hal_ks_block_t;
 
 /*
@@ -143,7 +150,7 @@ typedef union {
 typedef struct {
   unsigned              blockno;
   unsigned              lru;
-  hal_ks_block_t	block;
+  hal_ks_block_t        block;
 } hal_ks_cache_block_t;
 
 /*
@@ -201,50 +208,112 @@ struct hal_ks {
 };
 
 /*
- * Keystore driver.  This is just a dispatch vector for low-level
- * keystore operations, and the code is very repetitive.  We opt for
- * expressing this in a terse form via C macros over expressing it
- * as huge chunks of repetitive code: both are difficult to read, but
- * the terse form has the advantage of fitting in a single screen.
- * The KS_DRIVER_METHODS macro is the protein, the rest is just the
- * machinery to expand the method definitions into a struct of typed
- * function pointers and a set of static inline wrapper functions.
+ * Keystore driver.
  */
 
-#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)                                   \
-  KS_DRIVER_METHOD(zero,        hal_ks_t *ks, const unsigned blockno)                                   \
-  KS_DRIVER_METHOD(erase,       hal_ks_t *ks, const unsigned blockno)                                   \
-  KS_DRIVER_METHOD(erase_maybe, hal_ks_t *ks, const unsigned blockno)                                   \
-  KS_DRIVER_METHOD(set_owner,   hal_ks_t *ks, const unsigned blockno,                                   \
-                                const hal_client_handle_t client, const hal_session_handle_t session)   \
-  KS_DRIVER_METHOD(test_owner,  hal_ks_t *ks, const unsigned blockno,                                   \
-                                const hal_client_handle_t client, const hal_session_handle_t session)   \
-  KS_DRIVER_END_LIST
-
-#define KS_DRIVER_METHOD(_name_, ...)   hal_error_t (*_name_)(__VA_ARGS__);
-struct hal_ks_driver { KS_DRIVER_METHODS };
-#undef  KS_DRIVER_METHOD
-
-#define KS_DRIVER_METHOD(_name_, ...)                                   \
-  static inline hal_error_t hal_ks_block_##_name_(__VA_ARGS__)		\
-  {									\
-    return                                                              \
-      ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :	\
-      ks->driver->_name_ == NULL        ? HAL_ERROR_NOT_IMPLEMENTED :	\
-      ks->driver->_name_(__VA_ARGS__);					\
-  }
-KS_DRIVER_METHODS
-#undef  KS_DRIVER_METHOD
-
-#undef  KS_DRIVER_METHODS
-#undef  KS_DRIVER_END_LIST
+struct hal_ks_driver {
+  hal_error_t (*init)        (hal_ks_t *ks, const int alloc);
+  hal_error_t (*read)        (hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block);
+  hal_error_t (*write)       (hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block);
+  hal_error_t (*deprecate)   (hal_ks_t *ks, const unsigned blockno);
+  hal_error_t (*zero)        (hal_ks_t *ks, const unsigned blockno);
+  hal_error_t (*erase)       (hal_ks_t *ks, const unsigned blockno);
+  hal_error_t (*erase_maybe) (hal_ks_t *ks, const unsigned blockno);
+  hal_error_t (*set_owner)   (hal_ks_t *ks, const unsigned blockno,
+                              const hal_client_handle_t client, const hal_session_handle_t session);
+  hal_error_t (*test_owner)  (hal_ks_t *ks, const unsigned blockno,
+                              const hal_client_handle_t client, const hal_session_handle_t session);
+};
 
-#endif /* _KS_H_ */
+/*
+ * Wrappers around keystore driver methods.
+ *
+ * hal_ks_init() is missing here because we expose it to the rest of libhal.
+ */
+
+static inline hal_error_t hal_ks_block_read(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->read == NULL          ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->read(ks, blockno, block);
+}
+
+static inline hal_error_t hal_ks_block_write(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->write == NULL         ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->write(ks, blockno, block);
+}
+
+static inline hal_error_t hal_ks_block_deprecate(hal_ks_t *ks, const unsigned blockno)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->deprecate == NULL     ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->deprecate(ks, blockno);
+}
+
+static inline hal_error_t hal_ks_block_zero(hal_ks_t *ks, const unsigned blockno)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->zero == NULL          ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->zero(ks, blockno);
+}
+
+static inline hal_error_t hal_ks_block_erase(hal_ks_t *ks, const unsigned blockno)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->erase == NULL         ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->erase(ks, blockno);
+}
+
+static inline hal_error_t hal_ks_block_erase_maybe(hal_ks_t *ks, const unsigned blockno)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->erase_maybe == NULL   ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->erase_maybe(ks, blockno);
+}
+
+static inline hal_error_t hal_ks_block_set_owner(hal_ks_t *ks, const unsigned blockno,
+                                                 const hal_client_handle_t  client,
+                                                 const hal_session_handle_t session)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->set_owner == NULL     ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->set_owner(ks, blockno, client, session);
+}
+
+static inline hal_error_t hal_ks_block_test_owner(hal_ks_t *ks, const unsigned blockno,
+                                                  const hal_client_handle_t  client,
+                                                  const hal_session_handle_t session)
+{
+  return
+    ks == NULL || ks->driver == NULL  ? HAL_ERROR_BAD_ARGUMENTS   :
+    ks->driver->test_owner == NULL    ? HAL_ERROR_NOT_IMPLEMENTED :
+    ks->driver->test_owner(ks, blockno, client, session);
+}
+
+/*
+ * Type safe casts.
+ */
+
+static inline hal_ks_block_type_t hal_ks_block_get_type(const hal_ks_block_t * const block)
+{
+  return block == NULL ? HAL_KS_BLOCK_TYPE_UNKNOWN :
+    (hal_ks_block_type_t) block->header.block_type;
+}
+
+static inline hal_ks_block_status_t hal_ks_block_get_status(const hal_ks_block_t * const block)
+{
+  return block == NULL ? HAL_KS_BLOCK_STATUS_UNKNOWN :
+    (hal_ks_block_status_t) block->header.block_status;
+}
 
 /*
  * Keystore utilities.  Some or all of these may end up static within ks.c.
@@ -252,10 +321,13 @@ KS_DRIVER_METHODS
 
 extern hal_error_t hal_ks_alloc_common(hal_ks_t *ks,
                                        const unsigned ks_blocks,
-                                       const unsigned cache_blocks);
+                                       const unsigned cache_blocks,
+                                       void **extra,
+                                       const size_t extra_len);
 
-extern hal_error_t hal_ks_init_common(hal_ks_t *ks,
-                                      const hal_ks_driver_t * const driver);
+extern hal_error_t hal_ks_init_common(hal_ks_t *ks);
+
+extern hal_crc32_t hal_ks_block_calculate_crc(const hal_ks_block_t * const block);
 
 extern hal_error_t hal_ks_index_heapsort(hal_ks_t *ks);
 
@@ -304,6 +376,29 @@ extern hal_error_t hal_ks_attribute_insert(uint8_t *bytes, const size_t bytes_le
                                            const uint8_t * const value,
                                            const size_t value_len);
 
+extern hal_ks_block_t *hal_ks_cache_pick_lru(hal_ks_t *ks);
+
+extern hal_ks_block_t *hal_ks_cache_find_block(const hal_ks_t * const ks,
+                                        const unsigned blockno);
+
+extern void hal_ks_cache_mark_used(hal_ks_t *ks,
+                            const hal_ks_block_t * const block,
+                            const unsigned blockno);
+
+extern void hal_ks_cache_release(hal_ks_t *ks,
+                          const hal_ks_block_t * const block);
+
+extern hal_error_t hal_ks_block_read_cached(hal_ks_t *ks,
+                                            const unsigned blockno,
+                                            hal_ks_block_t **block);
+
+extern hal_error_t hal_ks_block_update(hal_ks_t *ks,
+                                       const unsigned b1,
+                                       hal_ks_block_t *block,
+                                       const hal_uuid_t * const uuid,
+                                       int *hint);
+
+#endif /* _KS_H_ */
 
 /*
  * Local variables:
diff --git a/ks_index.c b/ks_index.c
index ed22cfb..644aecf 100644
--- a/ks_index.c
+++ b/ks_index.c
@@ -114,7 +114,7 @@ static inline hal_error_t ks_heapsift(hal_ks_t *ks, int parent, const int end)
   }
 }
 
-hal_ks_error_t hal_ks_index_heapsort(hal_ks_t *ks)
+hal_error_t hal_ks_index_heapsort(hal_ks_t *ks)
 {
   if (ks == NULL || ks->index == NULL || ks->names == NULL)
     return HAL_ERROR_IMPOSSIBLE;
diff --git a/ks_token.c b/ks_token.c
index cc25ca5..c2ebee2 100644
--- a/ks_token.c
+++ b/ks_token.c
@@ -62,6 +62,10 @@
 
 #define NUM_FLASH_BLOCKS        KEYSTORE_NUM_SUBSECTORS
 
+#if HAL_KS_BLOCK_SIZE % KEYSTORE_SUBSECTOR_SIZE != 0
+#error Keystore block size is not a multiple of flash subsector size
+#endif
+
 /*
  * Keystore database.
  */
@@ -81,13 +85,6 @@ typedef struct {
 #define db      ((ks_token_db_t * const) hal_ks_token)
 
 /*
- * PIN block gets the all-zeros UUID, which will never be returned by
- * the UUID generation code (by definition -- it's not a version 4 UUID).
- */
-
-const static hal_uuid_t pin_uuid = {{0}};
-
-/*
  * Calculate offset of the block in the flash address space.
  */
 
@@ -103,18 +100,18 @@ static inline uint32_t ks_token_offset(const unsigned blockno)
  * first page before reading the rest of the block.
  */
 
-static hal_error_t ks_token_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_token_read(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
 {
   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 */
-  if (keystore_read_data(block_offset(blockno),
+  if (keystore_read_data(ks_token_offset(blockno),
                          block->bytes,
                          KEYSTORE_PAGE_SIZE) != 1)
     return HAL_ERROR_KEYSTORE_ACCESS;
 
-  switch (block_get_type(block)) {
+  switch (hal_ks_block_get_type(block)) {
   case HAL_KS_BLOCK_TYPE_ERASED:
   case HAL_KS_BLOCK_TYPE_ZEROED:
     return HAL_OK;
@@ -125,7 +122,7 @@ static hal_error_t ks_token_read(hal_k_t *ks, const unsigned blockno, ks_block_t
     return HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE;
   }
 
-  switch (block_get_status(block)) {
+  switch (hal_ks_block_get_status(block)) {
   case HAL_KS_BLOCK_STATUS_LIVE:
   case HAL_KS_BLOCK_STATUS_TOMBSTONE:
     break;
@@ -134,12 +131,12 @@ static hal_error_t ks_token_read(hal_k_t *ks, const unsigned blockno, ks_block_t
   }
 
   /* Sigh, magic numeric return codes */
-  if (keystore_read_data(block_offset(blockno) + KEYSTORE_PAGE_SIZE,
+  if (keystore_read_data(ks_token_offset(blockno) + KEYSTORE_PAGE_SIZE,
                          block->bytes + KEYSTORE_PAGE_SIZE,
                          sizeof(*block) - KEYSTORE_PAGE_SIZE) != 1)
     return HAL_ERROR_KEYSTORE_ACCESS;
 
-  if (calculate_block_crc(block) != block->header.crc)
+  if (hal_ks_block_calculate_crc(block) != block->header.crc)
     return HAL_ERROR_KEYSTORE_BAD_CRC;
 
   return HAL_OK;
@@ -151,13 +148,13 @@ static hal_error_t ks_token_read(hal_k_t *ks, const unsigned blockno, ks_block_t
  * need to update the CRC for this, we just modify the first page.
  */
 
-static hal_error_t ks_token_deprecate(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_deprecate(hal_ks_t *ks, const unsigned blockno)
 {
   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;
+  hal_ks_block_header_t *header = (void *) page;
   uint32_t offset = ks_token_offset(blockno);
 
   /* Sigh, magic numeric return codes */
@@ -177,7 +174,7 @@ static hal_error_t ks_token_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 ks_token_zero(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_zero(hal_ks_t *ks, const unsigned blockno)
 {
   if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
@@ -185,7 +182,7 @@ static hal_error_t ks_token_zero(hal_k_t *ks, const unsigned blockno)
   uint8_t page[KEYSTORE_PAGE_SIZE] = {0};
 
   /* Sigh, magic numeric return codes */
-  if (keystore_write_data(block_offset(blockno), page, sizeof(page)) != 1)
+  if (keystore_write_data(ks_token_offset(blockno), page, sizeof(page)) != 1)
     return HAL_ERROR_KEYSTORE_ACCESS;
 
   return HAL_OK;
@@ -195,7 +192,7 @@ static hal_error_t ks_token_zero(hal_k_t *ks, const unsigned blockno)
  * Erase a flash block.  Also see ks_token_erase_maybe(), below.
  */
 
-static hal_error_t ks_token_erase(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_erase(hal_ks_t *ks, const unsigned blockno)
 {
   if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
@@ -217,7 +214,7 @@ static hal_error_t ks_token_erase(hal_k_t *ks, const unsigned blockno)
  * leak information about, eg, key length, so we do constant time.
  */
 
-static hal_error_t ks_token_erase_maybe(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_token_erase_maybe(hal_ks_t *ks, const unsigned blockno)
 {
   if (ks != hal_ks_token || blockno >= NUM_FLASH_BLOCKS)
     return HAL_ERROR_IMPOSSIBLE;
@@ -232,34 +229,34 @@ static hal_error_t ks_token_erase_maybe(hal_k_t *ks, const unsigned blockno)
       mask &= page[i];
   }
 
-  return mask == 0xFF ? HAL_OK : ks_token_erase(blockno);
+  return mask == 0xFF ? HAL_OK : ks_token_erase(ks, blockno);
 }
 
 /*
  * Write a flash block, calculating CRC when appropriate.
  */
 
-static hal_error_t ks_token_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_token_write(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
 {
   if (ks != hal_ks_token || block == NULL || blockno >= NUM_FLASH_BLOCKS || sizeof(*block) != KEYSTORE_SUBSECTOR_SIZE)
     return HAL_ERROR_IMPOSSIBLE;
 
-  hal_error_t err = ks_token_erase_maybe(blockno);
+  hal_error_t err = ks_token_erase_maybe(ks, blockno);
 
   if (err != HAL_OK)
     return err;
 
-  switch (block_get_type(block)) {
+  switch (hal_ks_block_get_type(block)) {
   case HAL_KS_BLOCK_TYPE_KEY:
   case HAL_KS_BLOCK_TYPE_PIN:
-    block->header.crc = calculate_block_crc(block);
+    block->header.crc = hal_ks_block_calculate_crc(block);
     break;
   default:
     break;
   }
 
   /* Sigh, magic numeric return codes */
-  if (keystore_write_data(block_offset(blockno), block->bytes, sizeof(*block)) != 1)
+  if (keystore_write_data(ks_token_offset(blockno), block->bytes, sizeof(*block)) != 1)
     return HAL_ERROR_KEYSTORE_ACCESS;
 
   return HAL_OK;
@@ -289,7 +286,7 @@ static hal_error_t ks_token_test_owner(hal_ks_t *ks, const
  * Forward reference.
  */
 
-static hal_error_t fetch_pin_block(unsigned *b, ks_block_t **block);
+static hal_error_t fetch_pin_block(unsigned *b, hal_ks_block_t **block);
 
 /*
  * Initialize keystore.
@@ -300,6 +297,7 @@ static hal_error_t ks_token_init(hal_ks_t *ks, const int alloc)
   if (ks != hal_ks_token)
     return HAL_ERROR_IMPOSSIBLE;
 
+  hal_ks_block_t *block = NULL;
   hal_error_t err = HAL_OK;
 
   hal_ks_lock();
@@ -349,14 +347,14 @@ static hal_error_t ks_token_init(hal_ks_t *ks, const int alloc)
     block->pin.so_pin    = db->so_pin;
     block->pin.user_pin  = db->user_pin;
 
-    if ((err = hal_ks_index_add(ks, &pin_uuid, &b, NULL)) != HAL_OK)
+    if ((err = hal_ks_index_add(ks, &hal_ks_pin_uuid, &b, NULL)) != HAL_OK)
       goto done;
 
-    cache_mark_used(block, b);
+    hal_ks_cache_mark_used(ks, block, b);
 
-    err = ks_token_write(b, block);
+    err = ks_token_write(ks, b, block);
 
-    cache_release(block);
+    hal_ks_cache_release(ks, block);
 
     if (err != HAL_OK)
       goto done;
@@ -376,12 +374,12 @@ static hal_error_t ks_token_init(hal_ks_t *ks, const int alloc)
 
 static const hal_ks_driver_t ks_token_driver = {
   .init                 = ks_token_init,
-  .read               	= ks_token_read,
+  .read                 = ks_token_read,
   .write                = ks_token_write,
-  .deprecate		= ks_token_deprecate,
+  .deprecate            = ks_token_deprecate,
   .zero                 = ks_token_zero,
   .erase                = ks_token_erase,
-  .erase_maybe		= ks_token_erase_maybe,
+  .erase_maybe          = ks_token_erase_maybe,
   .set_owner            = ks_token_set_owner,
   .test_owner           = ks_token_test_owner
 };
@@ -408,19 +406,21 @@ hal_ks_t * const hal_ks_token = &_db.ks;
 void hal_ks_init_read_only_pins_only(void)
 {
   unsigned b, best_seen = ~0;
-  ks_block_t block[1];
+  hal_ks_block_t block[1];
 
   hal_ks_lock();
 
   for (b = 0; b < NUM_FLASH_BLOCKS; b++) {
-    if (block_read(b, block) != HAL_OK || ks_token_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
+    if (hal_ks_block_read(hal_ks_token, b, block) != HAL_OK ||
+        hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
       continue;
     best_seen = b;
-    if (block_get_status(block) == HAL_KS_BLOCK_STATUS_LIVE)
+    if (hal_ks_block_get_status(block) == HAL_KS_BLOCK_STATUS_LIVE)
       break;
   }
 
-  if (b != best_seen && best_seen != ~0 && ks_token_read(best_seen, block) != HAL_OK)
+  if (b != best_seen && best_seen != ~0 &&
+      hal_ks_block_read(hal_ks_token, best_seen, block) != HAL_OK)
     best_seen = ~0;
 
   if (best_seen == ~0) {
@@ -466,7 +466,7 @@ hal_error_t hal_get_pin(const hal_user_t user,
  * should always sort to first slot in the index.
  */
 
-static hal_error_t fetch_pin_block(unsigned *b, ks_block_t **block)
+static hal_error_t fetch_pin_block(unsigned *b, hal_ks_block_t **block)
 {
   if (block == NULL)
     return HAL_ERROR_IMPOSSIBLE;
@@ -478,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(hal_ks_token, &pin_uuid, b, &hint)) != HAL_OK ||
-      (err = ks_token_read_cached(*b, block))                      != HAL_OK)
+  if ((err = hal_ks_index_find(hal_ks_token, &hal_ks_pin_uuid, b, &hint)) != HAL_OK ||
+      (err = hal_ks_block_read_cached(hal_ks_token, *b, block))           != HAL_OK)
     return err;
 
-  cache_mark_used(*block, *b);
+  hal_ks_cache_mark_used(hal_ks_token, *block, *b);
 
-  if (block_get_type(*block) != HAL_KS_BLOCK_TYPE_PIN)
+  if (hal_ks_block_get_type(*block) != HAL_KS_BLOCK_TYPE_PIN)
     return HAL_ERROR_IMPOSSIBLE;
 
   return HAL_OK;
@@ -498,17 +498,17 @@ static hal_error_t fetch_pin_block(unsigned *b, ks_block_t **block)
  */
 
 static hal_error_t update_pin_block(const unsigned b,
-                                    ks_block_t *block,
-                                    const flash_pin_block_t * const new_data)
+                                    hal_ks_block_t *block,
+                                    const hal_ks_pin_block_t * const new_data)
 {
-  if (block == NULL || new_data == NULL || ks_token_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
+  if (block == NULL || new_data == NULL || hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_PIN)
     return HAL_ERROR_IMPOSSIBLE;
 
   int hint = 0;
 
   block->pin = *new_data;
 
-  return ks_token_update(b, block, &pin_uuid, &hint);
+  return hal_ks_block_update(hal_ks_token, b, block, &hal_ks_pin_uuid, &hint);
 }
 
 /*
@@ -521,7 +521,7 @@ hal_error_t hal_set_pin(const hal_user_t user,
   if (pin == NULL)
     return HAL_ERROR_BAD_ARGUMENTS;
 
-  ks_block_t *block;
+  hal_ks_block_t *block;
   hal_error_t err;
   unsigned b;
 
@@ -530,7 +530,7 @@ hal_error_t hal_set_pin(const hal_user_t user,
   if ((err = fetch_pin_block(&b, &block)) != HAL_OK)
     goto done;
 
-  flash_pin_block_t new_data = block->pin;
+  hal_ks_pin_block_t new_data = block->pin;
   hal_ks_pin_t *dp, *bp;
 
   switch (user) {
@@ -572,7 +572,7 @@ hal_error_t hal_mkm_flash_read_no_lock(uint8_t *buf, const size_t len)
   if (buf != NULL && len != KEK_LENGTH)
     return HAL_ERROR_MASTERKEY_BAD_LENGTH;
 
-  ks_block_t *block;
+  hal_ks_block_t *block;
   hal_error_t err;
   unsigned b;
 
@@ -604,7 +604,7 @@ hal_error_t hal_mkm_flash_write(const uint8_t * const buf, const size_t len)
   if (len != KEK_LENGTH)
     return HAL_ERROR_MASTERKEY_BAD_LENGTH;
 
-  ks_block_t *block;
+  hal_ks_block_t *block;
   hal_error_t err;
   unsigned b;
 
@@ -613,7 +613,7 @@ hal_error_t hal_mkm_flash_write(const uint8_t * const buf, const size_t len)
   if ((err = fetch_pin_block(&b, &block)) != HAL_OK)
     goto done;
 
-  flash_pin_block_t new_data = block->pin;
+  hal_ks_pin_block_t new_data = block->pin;
 
   new_data.kek_set = FLASH_KEK_SET;
   memcpy(new_data.kek, buf, len);
@@ -630,7 +630,7 @@ hal_error_t hal_mkm_flash_erase(const size_t len)
   if (len != KEK_LENGTH)
     return HAL_ERROR_MASTERKEY_BAD_LENGTH;
 
-  ks_block_t *block;
+  hal_ks_block_t *block;
   hal_error_t err;
   unsigned b;
 
@@ -639,7 +639,7 @@ hal_error_t hal_mkm_flash_erase(const size_t len)
   if ((err = fetch_pin_block(&b, &block)) != HAL_OK)
     goto done;
 
-  flash_pin_block_t new_data = block->pin;
+  hal_ks_pin_block_t new_data = block->pin;
 
   new_data.kek_set = FLASH_KEK_SET;
   memset(new_data.kek, 0, len);
@@ -653,7 +653,6 @@ hal_error_t hal_mkm_flash_erase(const size_t len)
 
 #endif /* HAL_MKM_FLASH_BACKUP_KLUDGE */
 
-
 /*
  * Local variables:
  * indent-tabs-mode: nil
diff --git a/ks_volatile.c b/ks_volatile.c
index 7e1a5f2..42d1ba1 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -58,7 +58,7 @@
 typedef struct {
   hal_client_handle_t   client;
   hal_session_handle_t  session;
-  hal_ks_block_t	block;
+  hal_ks_block_t        block;
 } ks_volatile_key_t;
 
 typedef struct {
@@ -77,7 +77,7 @@ typedef struct {
  * Read a block.  CRC probably not necessary for RAM.
  */
 
-static hal_error_t ks_volatile_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_volatile_read(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
 {
   if (ks != hal_ks_volatile || db->keys == NULL || block == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
@@ -91,12 +91,12 @@ static hal_error_t ks_volatile_read(hal_k_t *ks, const unsigned blockno, ks_bloc
  * Convert a live block into a tombstone.
  */
 
-static hal_error_t ks_volatile_deprecate(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_deprecate(hal_ks_t *ks, const unsigned blockno)
 {
   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 = HAL_KS_BLOCK_STATUS_TOMBSTONE;
 
   return HAL_OK;
 }
@@ -105,12 +105,12 @@ static hal_error_t ks_volatile_deprecate(hal_k_t *ks, const unsigned blockno)
  * Zero (not erase) a flash block.
  */
 
-static hal_error_t ks_volatile_zero(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_zero(hal_ks_t *ks, const unsigned blockno)
 {
   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));
+  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;
 
@@ -121,12 +121,12 @@ static hal_error_t ks_volatile_zero(hal_k_t *ks, const unsigned blockno)
  * Erase a flash block.
  */
 
-static hal_error_t ks_volatile_erase(hal_k_t *ks, const unsigned blockno)
+static hal_error_t ks_volatile_erase(hal_ks_t *ks, const unsigned blockno)
 {
   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));
+  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;
 
@@ -137,7 +137,7 @@ static hal_error_t ks_volatile_erase(hal_k_t *ks, const unsigned blockno)
  * Write a flash block.  CRC probably not necessary for RAM.
  */
 
-static hal_error_t ks_volatile_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block)
+static hal_error_t ks_volatile_write(hal_ks_t *ks, const unsigned blockno, hal_ks_block_t *block)
 {
   if (ks != hal_ks_volatile || db->keys == NULL || block == NULL || blockno >= ks->size)
     return HAL_ERROR_IMPOSSIBLE;
@@ -208,8 +208,8 @@ static hal_error_t ks_volatile_init(hal_ks_t *ks, const int alloc)
   if ((err = hal_ks_init_common(ks)) != HAL_OK)
     goto done;
 
-  for (unsigned b = 0; b < db->ks.size; i++)
-    if ((err = block_erase(ks, b)) != HAL_OK)
+  for (unsigned b = 0; b < db->ks.size; b++)
+    if ((err = hal_ks_block_erase(ks, b)) != HAL_OK)
       goto done;
 
   err = HAL_OK;
@@ -224,14 +224,14 @@ static hal_error_t ks_volatile_init(hal_ks_t *ks, const int alloc)
  * the driver functions.
  */
 
-static const hal_ks_driver_t hal_ks_volatile_driver = {
+static const hal_ks_driver_t ks_volatile_driver = {
   .init                 = ks_volatile_init,
-  .read               	= ks_volatile_read,
+  .read                 = ks_volatile_read,
   .write                = ks_volatile_write,
-  .deprecate		= ks_volatile_deprecate,
+  .deprecate            = ks_volatile_deprecate,
   .zero                 = ks_volatile_zero,
   .erase                = ks_volatile_erase,
-  .erase_maybe		= ks_volatile_erase, /* sic */
+  .erase_maybe          = ks_volatile_erase, /* sic */
   .set_owner            = ks_volatile_set_owner,
   .test_owner           = ks_volatile_test_owner
 };
diff --git a/rpc_pkey.c b/rpc_pkey.c
index bdf8a7e..d280c54 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -270,52 +270,25 @@ static hal_error_t pkcs1_5_pad(const uint8_t * const data, const size_t data_len
 }
 
 /*
- * Given key flags, open appropriate keystore driver.
+ * Given key flags, return appropriate keystore.
  */
 
-static inline hal_error_t ks_open_from_flags(hal_ks_t **ks, const hal_key_flags_t flags)
+static inline hal_ks_t *ks_from_flags(const hal_key_flags_t flags)
 {
-  return hal_ks_open((flags & HAL_KEY_FLAG_TOKEN) == 0
-                     ? hal_ks_volatile_driver
-                     : hal_ks_token_driver,
-                     ks);
+  return (flags & HAL_KEY_FLAG_TOKEN) == 0 ? hal_ks_volatile : hal_ks_token;
 }
 
 /*
- * Fetch a key from a driver.
- */
-
-static inline hal_error_t ks_fetch_from_driver(const hal_ks_driver_t * const driver,
-                                               hal_pkey_slot_t *slot,
-                                               uint8_t *der, size_t *der_len, const size_t der_max)
-{
-  hal_ks_t *ks = NULL;
-  hal_error_t err;
-
-  if ((err = hal_ks_open(driver, &ks)) != HAL_OK)
-    return err;
-
-  if ((err = hal_ks_fetch(ks, slot, der, der_len, der_max)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else
-    (void) hal_ks_close(ks);
-
-  return err;
-}
-
-/*
- * Same thing but from key flag in slot object rather than explict driver.
+ * Fetch a key from keystore indicated by key flag in slot object.
  */
 
 static inline hal_error_t ks_fetch_from_flags(hal_pkey_slot_t *slot,
                                               uint8_t *der, size_t *der_len, const size_t der_max)
 {
-  assert(slot != NULL);
+  if (slot == NULL)
+    return HAL_ERROR_IMPOSSIBLE;
 
-  return ks_fetch_from_driver((slot->flags & HAL_KEY_FLAG_TOKEN) == 0
-                              ? hal_ks_volatile_driver
-                              : hal_ks_token_driver,
-                              slot, der, der_len, der_max);
+  return hal_ks_fetch(ks_from_flags(slot->flags), slot, der, der_len, der_max);
 }
 
 
@@ -336,7 +309,6 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
   hal_curve_name_t curve;
   hal_pkey_slot_t *slot;
   hal_key_type_t type;
-  hal_ks_t *ks = NULL;
   hal_error_t err;
 
   if ((err = check_writable(client, flags)) != HAL_OK)
@@ -357,13 +329,7 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
   slot->curve = curve;
   slot->flags = flags;
 
-  if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
-      (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
-
-  if (err != HAL_OK) {
+  if ((err = hal_ks_store(ks_from_flags(flags), slot, der, der_len)) != HAL_OK) {
     slot->type = HAL_KEY_TYPE_NONE;
     return err;
   }
@@ -397,11 +363,11 @@ static hal_error_t pkey_local_open(const hal_client_handle_t client,
   slot->client_handle = client;
   slot->session_handle = session;
 
-  if ((err = ks_fetch_from_driver(hal_ks_token_driver, slot, NULL, NULL, 0)) == HAL_OK)
+  if ((err = hal_ks_fetch(hal_ks_token, slot, NULL, NULL, 0)) == HAL_OK)
     slot->pkey_handle.handle |= HAL_PKEY_HANDLE_TOKEN_FLAG;
 
   else if (err == HAL_ERROR_KEY_NOT_FOUND)
-    err = ks_fetch_from_driver(hal_ks_volatile_driver, slot, NULL, NULL, 0);
+    err = hal_ks_fetch(hal_ks_volatile, slot, NULL, NULL, 0);
 
   if (err != HAL_OK)
     goto fail;
@@ -431,7 +397,6 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
   uint8_t keybuf[hal_rsa_key_t_size];
   hal_rsa_key_t *key = NULL;
   hal_pkey_slot_t *slot;
-  hal_ks_t *ks = NULL;
   hal_error_t err;
 
   if ((err = check_writable(client, flags)) != HAL_OK)
@@ -458,12 +423,8 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
   uint8_t der[hal_rsa_private_key_to_der_len(key)];
   size_t der_len;
 
-  if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
-      (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
-      (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
+  if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
+    err = hal_ks_store(ks_from_flags(flags), slot, der, der_len);
 
   memset(keybuf, 0, sizeof(keybuf));
   memset(der, 0, sizeof(der));
@@ -495,7 +456,6 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
   uint8_t keybuf[hal_ecdsa_key_t_size];
   hal_ecdsa_key_t *key = NULL;
   hal_pkey_slot_t *slot;
-  hal_ks_t *ks = NULL;
   hal_error_t err;
 
   if ((err = check_writable(client, flags)) != HAL_OK)
@@ -521,12 +481,8 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
   uint8_t der[hal_ecdsa_private_key_to_der_len(key)];
   size_t der_len;
 
-  if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
-      (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
-      (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
+  if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
+    err = hal_ks_store(ks_from_flags(flags), slot, der, der_len);
 
   memset(keybuf, 0, sizeof(keybuf));
   memset(der, 0, sizeof(der));
@@ -568,17 +524,12 @@ static hal_error_t pkey_local_delete(const hal_pkey_handle_t pkey)
   if (slot == NULL)
     return HAL_ERROR_KEY_NOT_FOUND;
 
-  hal_ks_t *ks = NULL;
   hal_error_t err;
 
   if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
     return err;
 
-  if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
-      (err = hal_ks_delete(ks, slot)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
+  err = hal_ks_delete(ks_from_flags(slot->flags), slot);
 
   if (err == HAL_OK || err == HAL_ERROR_KEY_NOT_FOUND)
     clear_slot(slot);
@@ -1018,7 +969,7 @@ static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
   return err;
 }
 
-static inline hal_error_t match_one_keystore(const hal_ks_driver_t * const driver,
+static inline hal_error_t match_one_keystore(hal_ks_t *ks,
                                              const hal_client_handle_t client,
                                              const hal_session_handle_t session,
                                              const hal_key_type_t type,
@@ -1032,21 +983,12 @@ static inline hal_error_t match_one_keystore(const hal_ks_driver_t * const drive
                                              const unsigned result_max,
                                              const hal_uuid_t * const previous_uuid)
 {
-  hal_ks_t *ks = NULL;
   hal_error_t err;
   unsigned len;
 
-  if ((err = hal_ks_open(driver, &ks)) != HAL_OK)
-    return err;
-
   if ((err = hal_ks_match(ks, client, session, type, curve,
                           mask, flags, attributes, attributes_len,
-                          *result, &len, result_max, previous_uuid)) != HAL_OK) {
-    (void) hal_ks_close(ks);
-    return err;
-  }
-
-  if ((err = hal_ks_close(ks)) != HAL_OK)
+                          *result, &len, result_max, previous_uuid)) != HAL_OK)
     return err;
 
   *result     += len;
@@ -1097,7 +1039,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client,
 
   case MATCH_STATE_TOKEN:
     if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) != 0) &&
-        (err = match_one_keystore(hal_ks_token_driver, client, session, type, curve,
+        (err = match_one_keystore(hal_ks_token, client, session, type, curve,
                                   mask, flags, attributes, attributes_len,
                                   &result, result_len, result_max - *result_len, prev)) != HAL_OK)
       return err;
@@ -1108,7 +1050,7 @@ static hal_error_t pkey_local_match(const hal_client_handle_t client,
 
   case MATCH_STATE_VOLATILE:
     if (((mask & HAL_KEY_FLAG_TOKEN) == 0 || (mask & flags & HAL_KEY_FLAG_TOKEN) == 0) &&
-        (err = match_one_keystore(hal_ks_volatile_driver, client, session, type, curve,
+        (err = match_one_keystore(hal_ks_volatile, client, session, type, curve,
                                   mask, flags, attributes, attributes_len,
                                   &result, result_len, result_max - *result_len, prev)) != HAL_OK)
       return err;
@@ -1133,19 +1075,12 @@ static hal_error_t pkey_local_set_attributes(const hal_pkey_handle_t pkey,
   if (slot == NULL)
     return HAL_ERROR_KEY_NOT_FOUND;
 
-  hal_ks_t *ks = NULL;
   hal_error_t err;
 
   if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
     return err;
 
-  if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
-      (err = hal_ks_set_attributes(ks, slot, attributes, attributes_len)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
-
-  return err;
+  return hal_ks_set_attributes(ks_from_flags(slot->flags), slot, attributes, attributes_len);
 }
 
 static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
@@ -1159,17 +1094,8 @@ static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
   if (slot == NULL)
     return HAL_ERROR_KEY_NOT_FOUND;
 
-  hal_ks_t *ks = NULL;
-  hal_error_t err;
-
-  if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
-      (err = hal_ks_get_attributes(ks, slot, attributes, attributes_len,
-                                   attributes_buffer, attributes_buffer_len)) == HAL_OK)
-    err = hal_ks_close(ks);
-  else if (ks != NULL)
-    (void) hal_ks_close(ks);
-
-  return err;
+  return hal_ks_get_attributes(ks_from_flags(slot->flags), slot, attributes, attributes_len,
+                               attributes_buffer, attributes_buffer_len);
 }
 
 static hal_error_t pkey_local_export(const hal_pkey_handle_t pkey_handle,
diff --git a/rpc_server.c b/rpc_server.c
index a01572e..f64d7d6 100644
--- a/rpc_server.c
+++ b/rpc_server.c
@@ -993,9 +993,9 @@ hal_error_t hal_rpc_server_init(void)
 {
     hal_error_t err;
 
-    if ((err = hal_ks_init(hal_ks_volatile_driver, 1))  != HAL_OK ||
-        (err = hal_ks_init(hal_ks_token_driver, 1))     != HAL_OK ||
-        (err = hal_rpc_server_transport_init())         != HAL_OK)
+    if ((err = hal_ks_init(hal_ks_volatile, 1)) != HAL_OK ||
+        (err = hal_ks_init(hal_ks_token, 1))    != HAL_OK ||
+        (err = hal_rpc_server_transport_init()) != HAL_OK)
         return err;
 
     return HAL_OK;
@@ -1005,9 +1005,7 @@ hal_error_t hal_rpc_server_close(void)
 {
     hal_error_t err;
 
-    if ((err = hal_rpc_server_transport_close())        != HAL_OK ||
-        (err = hal_ks_shutdown(hal_ks_token_driver))    != HAL_OK ||
-        (err = hal_ks_shutdown(hal_ks_volatile_driver)) != HAL_OK)
+    if ((err = hal_rpc_server_transport_close()) != HAL_OK)
         return err;
 
     return HAL_OK;



More information about the Commits mailing list