aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--hal_internal.h20
-rw-r--r--ks.c26
-rw-r--r--ks.h7
-rw-r--r--ks_token.c (renamed from ks_flash.c)181
-rw-r--r--ks_volatile.c143
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
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: