From 2caa6c72640877abc5f3572c4d926a23ff672ab1 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 28 May 2017 16:11:25 -0400 Subject: 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,9 +46,16 @@ */ #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. * @@ -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. */ @@ -80,13 +84,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; -- cgit v1.2.3