diff options
author | Rob Austein <sra@hactrn.net> | 2017-05-28 12:11:31 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2017-05-28 12:11:31 -0400 |
commit | f59533ee9807832ea5ca7dd5492592c8991a9f34 (patch) | |
tree | cdca6a55bd7b78721ea03057777911e249ee63c3 | |
parent | 5eccb3e6d7c27149a0092de48eb21baa495879cb (diff) |
Further keystore cleanup and consolidation.
Still not yet expected to compile, much less run, but getting closer.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | hal_internal.h | 20 | ||||
-rw-r--r-- | ks.c | 26 | ||||
-rw-r--r-- | ks.h | 7 | ||||
-rw-r--r-- | ks_token.c (renamed from ks_flash.c) | 181 | ||||
-rw-r--r-- | ks_volatile.c | 143 |
6 files changed, 210 insertions, 171 deletions
@@ -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 @@ -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; } @@ -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) \ @@ -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: |