From d008267960337e9e44b270b26555a7a894808746 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 24 Apr 2017 08:33:11 -0400 Subject: Clean up pkey slots and volatile keys on client logout. --- ks_volatile.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index d565c60..363441a 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -614,6 +614,33 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks, return err; } +static void ks_client_cleanup(hal_ks_t *ks, + hal_client_handle_t client) +{ + if (ks == NULL || client.handle = HAL_HANDLE_NONE) + return HAL_ERROR_BAD_ARGUMENTS; + + ks_t *ksv = ks_to_ksv(ks); + hal_error_t err = HAL_OK; + + hal_ks_lock(); + + for (int i = 0; i < ksv->db->ksi.used; i++) { + unsigned b = ksv->db->ksi.index[i]; + if (ksv->db->keys[b].client.handle == client.handle) { + int hint = i; + if ((err = hal_ks_index_delete(&ksv->db->ksi, &ksv->db->ksi.names[b].name, 0, NULL, &hint)) != HAL_OK) + goto done; + memset(&ksv->db->keys[b], 0, sizeof(ksv->db->keys[b])); + i--; + } + } + + done: + hal_ks_unlock(); + return err; +} + const hal_ks_driver_t hal_ks_volatile_driver[1] = {{ .init = ks_volatile_init, .shutdown = ks_volatile_shutdown, @@ -624,7 +651,8 @@ const hal_ks_driver_t hal_ks_volatile_driver[1] = {{ .delete = ks_delete, .match = ks_match, .set_attributes = ks_set_attributes, - .get_attributes = ks_get_attributes + .get_attributes = ks_get_attributes, + .client_cleanup = ks_client_cleanup }}; #endif /* STATIC_KS_VOLATILE_SLOTS > 0 */ -- cgit v1.2.3 From 4ee44177c6da04e210a52528763b2c96a8f3d824 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 24 Apr 2017 17:23:17 -0400 Subject: Call a portable entrenching tool a portable entrenching tool. --- ks_volatile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 363441a..29c3576 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -614,8 +614,8 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks, return err; } -static void ks_client_cleanup(hal_ks_t *ks, - hal_client_handle_t client) +static void ks_logout(hal_ks_t *ks, + hal_client_handle_t client) { if (ks == NULL || client.handle = HAL_HANDLE_NONE) return HAL_ERROR_BAD_ARGUMENTS; @@ -652,7 +652,7 @@ const hal_ks_driver_t hal_ks_volatile_driver[1] = {{ .match = ks_match, .set_attributes = ks_set_attributes, .get_attributes = ks_get_attributes, - .client_cleanup = ks_client_cleanup + .logout = ks_logout }}; #endif /* STATIC_KS_VOLATILE_SLOTS > 0 */ -- cgit v1.2.3 From 358b3803cdedad607cf649221d0b7e3ce66b45f2 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 25 Apr 2017 17:14:40 -0400 Subject: Shake dumb compile-time bugs out of new logout code. What I get for writing code while build and test environment is tied up with a multi-day run testing something else. --- ks_volatile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 29c3576..6a17e45 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -614,10 +614,10 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks, return err; } -static void ks_logout(hal_ks_t *ks, - hal_client_handle_t client) +static hal_error_t ks_logout(hal_ks_t *ks, + hal_client_handle_t client) { - if (ks == NULL || client.handle = HAL_HANDLE_NONE) + if (ks == NULL || client.handle == HAL_HANDLE_NONE) return HAL_ERROR_BAD_ARGUMENTS; ks_t *ksv = ks_to_ksv(ks); -- cgit v1.2.3 From 2b4dc660d9d10eed407851319bfe63d5f9c3acd1 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 22 May 2017 23:22:09 -0400 Subject: First pass on experimental one-size-fits-nobody keystore. Support for variable-length keystore objects significantly complicates the keystore implementation, including serious some serious code bloat and a complex recovery algorithm to deal with crashes or loss of power at exactly the wrong time. Perhaps we don't really need this? So this is an experiment to see whether we can replace variable-length keystore objects with fixed-length, perhaps with a compile time option to let us make the fixed object length be 8192 bytes instead of 4096 bytes when needed to hold things like large RSA keys. First pass on this is just throwing away nearly 1,000 lines of excessively complex code. The result probably won't even compile yet, but it's already significantly easier to read. --- ks_volatile.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index d565c60..f8bed1a 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -423,9 +423,6 @@ static hal_error_t ks_match(hal_ks_t *ks, unsigned b = ksv->db->ksi.index[i]; - if (ksv->db->ksi.names[b].chunk > 0) - continue; - if (type != HAL_KEY_TYPE_NONE && type != ksv->db->keys[b].type) continue; -- cgit v1.2.3 From d532e6bbcd63c550f91fc97446f6114f37d18bde Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 23 May 2017 00:05:49 -0400 Subject: Whack previous commit with club until it compiles. --- ks_volatile.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index f8bed1a..2dcb599 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -261,7 +261,7 @@ static hal_error_t ks_store(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_add(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_add(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; uint8_t kek[KEK_LENGTH]; @@ -284,7 +284,7 @@ static hal_error_t ks_store(hal_ks_t *ks, if (err == HAL_OK) ksv->db->keys[b] = k; else - (void) hal_ks_index_delete(&ksv->db->ksi, &slot->name, 0, NULL, &slot->hint); + (void) hal_ks_index_delete(&ksv->db->ksi, &slot->name, NULL, &slot->hint); done: hal_ks_unlock(); @@ -309,7 +309,7 @@ static hal_error_t ks_fetch(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; const ks_key_t * const k = &ksv->db->keys[b]; @@ -364,7 +364,7 @@ static hal_error_t ks_delete(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, &ksv->db->keys[b])) { @@ -372,7 +372,7 @@ static hal_error_t ks_delete(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_delete(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_delete(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; memset(&ksv->db->keys[b], 0, sizeof(ksv->db->keys[b])); @@ -412,7 +412,7 @@ static hal_error_t ks_match(hal_ks_t *ks, *result_len = 0; - err = hal_ks_index_find(&ksv->db->ksi, previous_uuid, 0, NULL, &i); + err = hal_ks_index_find(&ksv->db->ksi, previous_uuid, NULL, &i); if (err == HAL_ERROR_KEY_NOT_FOUND) i--; @@ -464,7 +464,7 @@ static hal_error_t ks_match(hal_ks_t *ks, continue; } - result[*result_len] = ksv->db->ksi.names[b].name; + result[*result_len] = ksv->db->ksi.names[b]; ++*result_len; } @@ -495,7 +495,7 @@ static hal_error_t ks_set_attributes(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; ks_key_t * const k = &ksv->db->keys[b]; @@ -556,7 +556,7 @@ static hal_error_t ks_get_attributes(hal_ks_t *ks, goto done; } - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, 0, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) goto done; const ks_key_t * const k = &ksv->db->keys[b]; -- cgit v1.2.3 From dc8c7d92118541bba8d6f76f75a5661416055fb8 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 23 May 2017 00:57:29 -0400 Subject: Goodbye ancient mmap()-based keystore. The Novena-era mmap()-based keystore is far enough out of date that it's not worth maintaining (and we haven't been doing so): if we ever need one again, it would be easier to rewrite it from scratch. --- ks_volatile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 2dcb599..515a8e8 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -53,9 +53,9 @@ #endif /* - * In-memory keystore database. This should also be usable for - * mmap(), if and when we get around to rewriting that driver (and in - * which case this driver probably ought to be renamed ks_memory). + * In-memory keystore database. This is a bit more complicated than + * necessary because originally I though we would want to continue + * supporting an mmap()-based keystore as well. Needs cleaning up. */ typedef struct { -- cgit v1.2.3 From 5eccb3e6d7c27149a0092de48eb21baa495879cb Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Thu, 25 May 2017 11:18:39 -0400 Subject: Checkpoint while refactoring. Almost certainly will not compile. --- ks_volatile.c | 607 ++++++++++------------------------------------------------ 1 file changed, 99 insertions(+), 508 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 515a8e8..e9a0ef4 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -41,591 +41,182 @@ #include "hal.h" #include "hal_internal.h" - -#define KEK_LENGTH (bitsToBytes(256)) +#include "ks.h" #ifndef STATIC_KS_VOLATILE_SLOTS #define STATIC_KS_VOLATILE_SLOTS HAL_STATIC_PKEY_STATE_BLOCKS #endif -#ifndef STATIC_KS_VOLATILE_ATTRIBUTE_SPACE -#define STATIC_KS_VOLATILE_ATTRIBUTE_SPACE 4096 +#ifndef KS_VOLATILE_CACHE_SIZE +#define KS_VOLATILE_CACHE_SIZE 4 #endif -/* - * In-memory keystore database. This is a bit more complicated than - * necessary because originally I though we would want to continue - * supporting an mmap()-based keystore as well. Needs cleaning up. - */ - typedef struct { - hal_key_type_t type; - hal_curve_name_t curve; - hal_key_flags_t flags; hal_client_handle_t client; hal_session_handle_t session; - size_t der_len; - unsigned attributes_len; - uint8_t der[HAL_KS_WRAPPED_KEYSIZE + STATIC_KS_VOLATILE_ATTRIBUTE_SPACE]; -} ks_key_t; + hal_ks_block_t block; +} volatile_key_t; -typedef struct { - hal_ks_index_t ksi; - ks_key_t *keys; -} db_t; - -/* - * "Subclass" (well, what one can do in C) of hal_ks_t. This is - * separate from db_t primarily to simplify things like rewriting the - * old ks_mmap driver to piggy-back on the ks_volatile driver: we - * wouldn't want the hal_ks_t into the mmap()ed file. - */ - -typedef struct { +static struct db { hal_ks_t ks; /* Must be first */ - db_t *db; /* Which memory-based keystore database */ - int per_session; /* Whether objects are per-session */ -} ks_t; + volatile_key_t *keys; +} db; /* - * If we also supported mmap, there would be a separate definition for - * HAL_KS_MMAP_SLOTS above, and the bulk of the code would be under a - * conditional testing whether either HAL_KS_*_SLOTS were nonzero. + * Read a block. CRC probably not necessary for RAM. */ -#if STATIC_KS_VOLATILE_SLOTS > 0 +static hal_error_t block_read(hal_k_t *ks, const unsigned blockno, ks_block_t *block) +{ + if (ks != &db.ks || db.keys == NULL || block == NULL || blockno >= ks->size) + return HAL_ERROR_IMPOSSIBLE; -static ks_t volatile_ks; + memcpy(block, &db.keys[blockno].block, sizeof(*block)); -static inline ks_t *ks_to_ksv(hal_ks_t *ks) -{ - return (ks_t *) ks; + return HAL_OK; } /* - * Check whether the current session can see a particular key. One - * might expect this to be based on whether the session matches, and - * indeed it would be in a sane world, but in the world of PKCS #11, - * keys belong to sessions, are visible to other sessions, and may - * even be modifiable by other sessions, but softly and silently - * vanish away when the original creating session is destroyed. - * - * In our terms, this means that visibility of session objects is - * determined only by the client handle, so taking the session handle - * as an argument here isn't really necessary, but we've flipflopped - * on that enough times that at least for now I'd prefer to leave the - * session handle here and not have to revise all the RPC calls again. - * Remove it at some later date and redo the RPC calls if we manage to - * avoid revising this yet again. + * Convert a live block into a tombstone. */ -static inline int key_visible_to_session(const ks_t * const ksv, - const hal_client_handle_t client, - const hal_session_handle_t session, - const ks_key_t * const k) +static hal_error_t block_deprecate(hal_k_t *ks, const unsigned blockno) { - return (!ksv->per_session || - client.handle == HAL_HANDLE_NONE || - k->client.handle == client.handle || - hal_rpc_is_logged_in(client, HAL_USER_WHEEL) == HAL_OK); -} - -static inline void *gnaw(uint8_t **mem, size_t *len, const size_t size) -{ - if (mem == NULL || *mem == NULL || len == NULL || size > *len) - return NULL; - void *ret = *mem; - *mem += size; - *len -= size; - return ret; -} - -static hal_error_t ks_init(const hal_ks_driver_t * const driver, - const int per_session, - ks_t *ksv, - uint8_t *mem, - size_t len) -{ - if (ksv == NULL) - return HAL_ERROR_IMPOSSIBLE; - - if (mem != NULL) { - memset(ksv, 0, sizeof(*ksv)); - memset(mem, 0, len); - - ksv->db = gnaw(&mem, &len, sizeof(*ksv->db)); - ksv->db->ksi.index = gnaw(&mem, &len, sizeof(*ksv->db->ksi.index) * STATIC_KS_VOLATILE_SLOTS); - ksv->db->ksi.names = gnaw(&mem, &len, sizeof(*ksv->db->ksi.names) * STATIC_KS_VOLATILE_SLOTS); - ksv->db->keys = gnaw(&mem, &len, sizeof(*ksv->db->keys) * STATIC_KS_VOLATILE_SLOTS); - ksv->db->ksi.size = STATIC_KS_VOLATILE_SLOTS; - } - - if (ksv->db == NULL || - ksv->db->ksi.index == NULL || - ksv->db->ksi.names == NULL || - ksv->db->keys == NULL) + if (ks != &db.ks || db.keys == NULL || blockno >= ks->size) return HAL_ERROR_IMPOSSIBLE; - if (mem == NULL) { - memset(ksv->db->ksi.index, 0, sizeof(*ksv->db->ksi.index) * STATIC_KS_VOLATILE_SLOTS); - memset(ksv->db->ksi.names, 0, sizeof(*ksv->db->ksi.names) * STATIC_KS_VOLATILE_SLOTS); - memset(ksv->db->keys, 0, sizeof(*ksv->db->keys) * STATIC_KS_VOLATILE_SLOTS); - } - - ksv->ks.driver = driver; - ksv->per_session = per_session; - ksv->db->ksi.used = 0; - - /* - * Set up keystore with empty index and full free list. - * Since this driver doesn't care about wear leveling, - * just populate the free list in block numerical order. - */ - - for (int i = 0; i < STATIC_KS_VOLATILE_SLOTS; i++) - ksv->db->ksi.index[i] = i; + db.keys[blockno].block.header->block_status = BLOCK_STATUS_TOMBSTONE; - return hal_ks_index_setup(&ksv->db->ksi); + return HAL_OK; } -static hal_error_t ks_volatile_init(const hal_ks_driver_t * const driver, const int alloc) -{ - hal_error_t err = HAL_OK; - - hal_ks_lock(); - - const size_t len = (sizeof(*volatile_ks.db) + - sizeof(*volatile_ks.db->ksi.index) * STATIC_KS_VOLATILE_SLOTS + - sizeof(*volatile_ks.db->ksi.names) * STATIC_KS_VOLATILE_SLOTS + - sizeof(*volatile_ks.db->keys) * STATIC_KS_VOLATILE_SLOTS); - - uint8_t *mem = NULL; +/* + * Zero (not erase) a flash block. + */ - if (alloc && (mem = hal_allocate_static_memory(len)) == NULL) - err = HAL_ERROR_ALLOCATION_FAILURE; - else - err = ks_init(driver, 1, &volatile_ks, mem, len); +static hal_error_t block_zero(hal_k_t *ks, const unsigned blockno) +{ + if (ks != &db.ks || db.keys == NULL || blockno >= ks->size) + return HAL_ERROR_IMPOSSIBLE; - hal_ks_unlock(); - return err; -} + 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; -static hal_error_t ks_volatile_shutdown(const hal_ks_driver_t * const driver) -{ - if (volatile_ks.ks.driver != driver) - return HAL_ERROR_KEYSTORE_ACCESS; return HAL_OK; } -static hal_error_t ks_volatile_open(const hal_ks_driver_t * const driver, - hal_ks_t **ks) -{ - assert(driver != NULL && ks != NULL); - *ks = &volatile_ks.ks; - return HAL_OK; -} +/* + * Erase a flash block. + */ -static hal_error_t ks_volatile_close(hal_ks_t *ks) +static hal_error_t block_erase(hal_k_t *ks, const unsigned blockno) { + if (ks != &db.ks || 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; + return HAL_OK; } -static inline int acceptable_key_type(const hal_key_type_t type) -{ - switch (type) { - case HAL_KEY_TYPE_RSA_PRIVATE: - case HAL_KEY_TYPE_EC_PRIVATE: - case HAL_KEY_TYPE_RSA_PUBLIC: - case HAL_KEY_TYPE_EC_PUBLIC: - return 1; - default: - return 0; - } -} +/* + * Write a flash block. CRC probably not necessary for RAM. + */ -static hal_error_t ks_store(hal_ks_t *ks, - hal_pkey_slot_t *slot, - const uint8_t * const der, const size_t der_len) +static hal_error_t block_write(hal_k_t *ks, const unsigned blockno, ks_block_t *block) { - if (ks == NULL || slot == NULL || der == NULL || der_len == 0 || !acceptable_key_type(slot->type)) - return HAL_ERROR_BAD_ARGUMENTS; + if (ks != &db.ks || db.keys == NULL || block == NULL || blockno >= ks->size) + return HAL_ERROR_IMPOSSIBLE; - ks_t *ksv = ks_to_ksv(ks); - hal_error_t err = HAL_OK; - unsigned b; + memcpy(&db.keys[blockno].block, block, sizeof(*block)); - hal_ks_lock(); + return HAL_OK; +} - if (ksv->db == NULL) { - err = HAL_ERROR_KEYSTORE_ACCESS; - goto done; - } +/* + * Set key ownership. + */ - if ((err = hal_ks_index_add(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) - goto done; +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) +{ + if (ks != &db.ks || db.keys == NULL || blockno >= ks->size) + return HAL_ERROR_IMPOSSIBLE; - uint8_t kek[KEK_LENGTH]; - size_t kek_len; - ks_key_t k; + db.keys[blockno].client = client; + db.keys[blockno].session = session; - memset(&k, 0, sizeof(k)); - k.der_len = sizeof(k.der); - k.type = slot->type; - k.curve = slot->curve; - k.flags = slot->flags; - k.client = slot->client_handle; - k.session = slot->session_handle; + return HAL_OK; +} - if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) - err = hal_aes_keywrap(NULL, kek, kek_len, der, der_len, k.der, &k.der_len); +/* + * Test key ownership. + */ - memset(kek, 0, sizeof(kek)); +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) +{ + if (ks != &db.ks || db.keys == NULL || blockno >= ks->size) + return HAL_ERROR_IMPOSSIBLE; - if (err == HAL_OK) - ksv->db->keys[b] = k; + if (db.keys[blockno].client.handle == client.handle && + db.keys[blockno].session.handle == session.handle) + return HAL_OK; else - (void) hal_ks_index_delete(&ksv->db->ksi, &slot->name, NULL, &slot->hint); - - done: - hal_ks_unlock(); - return err; + return HAL_ERROR_KEY_NOT_FOUND; } -static hal_error_t ks_fetch(hal_ks_t *ks, - hal_pkey_slot_t *slot, - uint8_t *der, size_t *der_len, const size_t der_max) -{ - if (ks == NULL || slot == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - ks_t *ksv = ks_to_ksv(ks); - hal_error_t err = HAL_OK; - unsigned b; - - hal_ks_lock(); - - if (ksv->db == NULL) { - err = HAL_ERROR_KEYSTORE_ACCESS; - goto done; - } - - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) - goto done; - - const ks_key_t * const k = &ksv->db->keys[b]; - - if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, k)) { - err = HAL_ERROR_KEY_NOT_FOUND; - goto done; - } - - slot->type = k->type; - slot->curve = k->curve; - slot->flags = k->flags; - - if (der == NULL && der_len != NULL) - *der_len = k->der_len; - - if (der != NULL) { - - uint8_t kek[KEK_LENGTH]; - size_t kek_len, der_len_; - - if (der_len == NULL) - der_len = &der_len_; - - *der_len = der_max; - - if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK) - err = hal_aes_keyunwrap(NULL, kek, kek_len, k->der, k->der_len, der, der_len); - - memset(kek, 0, sizeof(kek)); - } +/* + * Initialize keystore. + */ - done: - hal_ks_unlock(); - return err; -} +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 +}}; -static hal_error_t ks_delete(hal_ks_t *ks, - hal_pkey_slot_t *slot) + hal_error_t hal_ks_volatile_init(const int alloc) { - if (ks == NULL || slot == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - ks_t *ksv = ks_to_ksv(ks); hal_error_t err = HAL_OK; - unsigned b; hal_ks_lock(); - if (ksv->db == NULL) { - err = HAL_ERROR_KEYSTORE_ACCESS; - goto done; - } - - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) - goto done; - if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, &ksv->db->keys[b])) { - err = HAL_ERROR_KEY_NOT_FOUND; + 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_index_delete(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) + if ((err = hal_ks_init_common(&db.ks, hal_ks_volatile_driver)) != HAL_OK) goto done; - memset(&ksv->db->keys[b], 0, sizeof(ksv->db->keys[b])); - - done: - hal_ks_unlock(); - return err; -} - -static hal_error_t ks_match(hal_ks_t *ks, - hal_client_handle_t client, - 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) -{ - if (ks == NULL || (attributes == NULL && attributes_len > 0) || - result == NULL || result_len == NULL || previous_uuid == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - ks_t *ksv = ks_to_ksv(ks); - - if (ksv->db == NULL) - return HAL_ERROR_KEYSTORE_ACCESS; - - hal_error_t err = HAL_OK; - int i = -1; - - hal_ks_lock(); - - *result_len = 0; - - err = hal_ks_index_find(&ksv->db->ksi, previous_uuid, NULL, &i); - - if (err == HAL_ERROR_KEY_NOT_FOUND) - i--; - else if (err != HAL_OK) + if (alloc && (db.keys = hal_allocate_static_memory(sizeof(*db.keys) * db.ks.size)) == NULL) { + err = HAL_ERROR_ALLOCATION_FAILURE; goto done; - - while (*result_len < result_max && ++i < ksv->db->ksi.used) { - - unsigned b = ksv->db->ksi.index[i]; - - if (type != HAL_KEY_TYPE_NONE && type != ksv->db->keys[b].type) - continue; - - if (curve != HAL_CURVE_NONE && curve != ksv->db->keys[b].curve) - continue; - - if (((flags ^ ksv->db->keys[b].flags) & mask) != 0) - continue; - - if (!key_visible_to_session(ksv, client, session, &ksv->db->keys[b])) - continue; - - if (attributes_len > 0) { - const ks_key_t * const k = &ksv->db->keys[b]; - int ok = 1; - - if (k->attributes_len == 0) - continue; - - hal_pkey_attribute_t key_attrs[k->attributes_len]; - - if ((err = hal_ks_attribute_scan(k->der + k->der_len, sizeof(k->der) - k->der_len, - key_attrs, k->attributes_len, NULL)) != HAL_OK) - goto done; - - for (const hal_pkey_attribute_t *required = attributes; - ok && required < attributes + attributes_len; required++) { - - hal_pkey_attribute_t *present = key_attrs; - while (ok && present->type != required->type) - ok = ++present < key_attrs + k->attributes_len; - - if (ok) - ok = (present->length == required->length && - !memcmp(present->value, required->value, present->length)); - } - - if (!ok) - continue; - } - - result[*result_len] = ksv->db->ksi.names[b]; - ++*result_len; - } - - err = HAL_OK; - - done: - hal_ks_unlock(); - return err; -} - -static hal_error_t ks_set_attributes(hal_ks_t *ks, - hal_pkey_slot_t *slot, - const hal_pkey_attribute_t *attributes, - const unsigned attributes_len) -{ - if (ks == NULL || slot == NULL || attributes == NULL || attributes_len == 0) - return HAL_ERROR_BAD_ARGUMENTS; - - ks_t *ksv = ks_to_ksv(ks); - hal_error_t err = HAL_OK; - unsigned b; - - hal_ks_lock(); - - { - if (ksv->db == NULL) { - err = HAL_ERROR_KEYSTORE_ACCESS; - goto done; - } - - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) - goto done; - - ks_key_t * const k = &ksv->db->keys[b]; - - if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, k)) { - err = HAL_ERROR_KEY_NOT_FOUND; - goto done; - } - - hal_pkey_attribute_t attrs[k->attributes_len + attributes_len]; - uint8_t *bytes = k->der + k->der_len; - size_t bytes_len = sizeof(k->der) - k->der_len; - size_t total_len; - - if ((err = hal_ks_attribute_scan(bytes, bytes_len, attrs, k->attributes_len, &total_len)) != HAL_OK) - goto done; - - for (const hal_pkey_attribute_t *a = attributes; a < attributes + attributes_len; a++) { - if (a->length == HAL_PKEY_ATTRIBUTE_NIL) - err = hal_ks_attribute_delete(bytes, bytes_len, attrs, &k->attributes_len, &total_len, - a->type); - else - err = hal_ks_attribute_insert(bytes, bytes_len, attrs, &k->attributes_len, &total_len, - a->type, a->value, a->length); - if (err != HAL_OK) - goto done; - } - - err = HAL_OK; - } - done: - hal_ks_unlock(); - return err; -} - -static hal_error_t 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) -{ - if (ks == NULL || slot == NULL || attributes == NULL || attributes_len == 0 || - attributes_buffer == NULL) - return HAL_ERROR_BAD_ARGUMENTS; - - ks_t *ksv = ks_to_ksv(ks); - hal_error_t err = HAL_OK; - unsigned b; - - hal_ks_lock(); - - { - if (ksv->db == NULL) { - err = HAL_ERROR_KEYSTORE_ACCESS; - goto done; - } - - if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b, &slot->hint)) != HAL_OK) - goto done; - - const ks_key_t * const k = &ksv->db->keys[b]; - - if (!key_visible_to_session(ksv, slot->client_handle, slot->session_handle, k)) { - err = HAL_ERROR_KEY_NOT_FOUND; - goto done; - } - - hal_pkey_attribute_t attrs[k->attributes_len > 0 ? k->attributes_len : 1]; - - if ((err = hal_ks_attribute_scan(k->der + k->der_len, sizeof(k->der) - k->der_len, - attrs, k->attributes_len, NULL)) != HAL_OK) + for (unsigned b = 0; b < db.ks.size; i++) + if ((err = block_erase(&db.ks, b)) != HAL_OK) goto done; - uint8_t *abuf = attributes_buffer; - - for (int i = 0; i < attributes_len; i++) { - int j = 0; - while (j < k->attributes_len && attrs[j].type != attributes[i].type) - j++; - const int found = j < k->attributes_len; - - if (attributes_buffer_len == 0) { - attributes[i].value = NULL; - attributes[i].length = found ? attrs[j].length : 0; - continue; - } - - if (!found) { - err = HAL_ERROR_ATTRIBUTE_NOT_FOUND; - goto done; - } - - if (attrs[j].length > attributes_buffer + attributes_buffer_len - abuf) { - err = HAL_ERROR_RESULT_TOO_LONG; - goto done; - } - - memcpy(abuf, attrs[j].value, attrs[j].length); - attributes[i].value = abuf; - attributes[i].length = attrs[j].length; - abuf += attrs[j].length; - } - - err = HAL_OK; - - } + err = HAL_OK; done: hal_ks_unlock(); return err; } -const hal_ks_driver_t hal_ks_volatile_driver[1] = {{ - .init = ks_volatile_init, - .shutdown = ks_volatile_shutdown, - .open = ks_volatile_open, - .close = ks_volatile_close, - .store = ks_store, - .fetch = ks_fetch, - .delete = ks_delete, - .match = ks_match, - .set_attributes = ks_set_attributes, - .get_attributes = ks_get_attributes -}}; - -#endif /* STATIC_KS_VOLATILE_SLOTS > 0 */ - /* * Local variables: * indent-tabs-mode: nil -- cgit v1.2.3 From f59533ee9807832ea5ca7dd5492592c8991a9f34 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 28 May 2017 12:11:31 -0400 Subject: Further keystore cleanup and consolidation. Still not yet expected to compile, much less run, but getting closer. --- ks_volatile.c | 143 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 83 insertions(+), 60 deletions(-) (limited to 'ks_volatile.c') 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; @@ -217,6 +219,27 @@ static const hal_ks_driver_t hal_ks_volatile_driver[1] = {{ return err; } +/* + * 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 -- cgit v1.2.3 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. --- ks_volatile.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'ks_volatile.c') 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 }; -- cgit v1.2.3 From 9e20f2fa42bcd493548bf7764958848ab72d1255 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sun, 28 May 2017 18:50:23 -0400 Subject: Debug new keystore init code. --- ks_volatile.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 42d1ba1..c1ea72d 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -205,13 +205,18 @@ static hal_error_t ks_volatile_init(hal_ks_t *ks, const int alloc) db->keys = mem; } - if ((err = hal_ks_init_common(ks)) != HAL_OK) + if (db->keys == NULL) { + err = HAL_ERROR_IMPOSSIBLE; goto done; + } for (unsigned b = 0; b < db->ks.size; b++) if ((err = hal_ks_block_erase(ks, b)) != HAL_OK) goto done; + if ((err = hal_ks_init_common(ks)) != HAL_OK) + goto done; + err = HAL_OK; done: -- cgit v1.2.3 From 5cee716555db92942c5b11c824839bb00aaf35b9 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 29 May 2017 00:44:18 -0400 Subject: Debug per-session keys. --- ks_volatile.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index c1ea72d..0b39133 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -169,8 +169,8 @@ static hal_error_t ks_volatile_set_owner(hal_ks_t *ks, * Test key ownership. */ -static hal_error_t ks_volatile_test_owner(hal_ks_t *ks, const - unsigned blockno, +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) { @@ -184,6 +184,22 @@ static hal_error_t ks_volatile_test_owner(hal_ks_t *ks, const return HAL_ERROR_KEY_NOT_FOUND; } +/* + * Copy key ownership. + */ + +static hal_error_t ks_volatile_copy_owner(hal_ks_t *ks, + const unsigned source, + const unsigned target) +{ + if (ks != hal_ks_volatile || db->keys == NULL || source >= ks->size || target >= ks->size) + return HAL_ERROR_IMPOSSIBLE; + + db->keys[target].client = db->keys[source].client; + db->keys[target].session = db->keys[source].session; + return HAL_OK; +} + /* * Initialize keystore. */ @@ -217,6 +233,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; + ks->per_session = 1; + err = HAL_OK; done: @@ -238,7 +256,8 @@ static const hal_ks_driver_t ks_volatile_driver = { .erase = ks_volatile_erase, .erase_maybe = ks_volatile_erase, /* sic */ .set_owner = ks_volatile_set_owner, - .test_owner = ks_volatile_test_owner + .test_owner = ks_volatile_test_owner, + .copy_owner = ks_volatile_copy_owner }; static ks_volatile_db_t _db = { .ks.driver = &ks_volatile_driver }; -- cgit v1.2.3 From 776c4e8cfed92bc2d894f002cb7d222abc65bb50 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Mon, 29 May 2017 13:16:14 -0400 Subject: Simplify per-session keys. Cosmetic cleanup of pkey_slot along the way. --- ks_volatile.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 0b39133..02054ff 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -167,6 +167,20 @@ static hal_error_t ks_volatile_set_owner(hal_ks_t *ks, /* * Test key ownership. + * + * One might expect this to be based on whether the session matches, + * and indeed it would be in a sane world, but in the world of PKCS + * #11, keys belong to sessions, are visible to other sessions, and + * may even be modifiable by other sessions, but softly and silently + * vanish away when the original creating session is destroyed. + * + * In our terms, this means that visibility of session objects is + * determined only by the client handle, so taking the session handle + * as an argument here isn't really necessary, but we've flipflopped + * on that enough times that at least for now I'd prefer to leave the + * session handle here and not have to revise all the RPC calls again. + * Remove it at some later date and redo the RPC calls if we manage to + * avoid revising this yet again. */ static hal_error_t ks_volatile_test_owner(hal_ks_t *ks, @@ -177,11 +191,14 @@ static hal_error_t ks_volatile_test_owner(hal_ks_t *ks, 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 == HAL_HANDLE_NONE || + db->keys[blockno].client.handle == client.handle) + return HAL_OK; + + if (hal_rpc_is_logged_in(client, HAL_USER_WHEEL) == HAL_OK) return HAL_OK; - else - return HAL_ERROR_KEY_NOT_FOUND; + + return HAL_ERROR_KEY_NOT_FOUND; } /* @@ -233,8 +250,6 @@ 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; - ks->per_session = 1; - err = HAL_OK; done: -- cgit v1.2.3 From b9188794e2634aa4918ba46298b88f03f2454dd4 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 30 May 2017 19:26:50 -0400 Subject: Missed one instance of one API change in "logout" branch merge. --- ks_volatile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 57806e8..2b5bb61 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -235,8 +235,8 @@ static hal_error_t ks_volatile_logout(hal_ks_t *ks, if (db->keys[b].client.handle != client.handle) continue; - if ((err = hal_ks_index_delete(ks, &ks->names[b], 0, NULL, &hint)) != HAL_OK || - (err = hal_ks_block_zero(ks, b)) != HAL_OK) + if ((err = hal_ks_index_delete(ks, &ks->names[b], NULL, &hint)) != HAL_OK || + (err = hal_ks_block_zero(ks, b)) != HAL_OK) return err; i--; -- cgit v1.2.3 From 6b881dfa81a0d51d4897c62de5abdb94c1aba0b7 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 30 May 2017 19:52:32 -0400 Subject: Hold keystore lock before calling keystore driver methods. Most keystore methods already followed this rule, but hal_ks_*_init() and hal_ks_*_logout() were confused, in different ways. --- ks_volatile.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) (limited to 'ks_volatile.c') diff --git a/ks_volatile.c b/ks_volatile.c index 2b5bb61..1586f3d 100644 --- a/ks_volatile.c +++ b/ks_volatile.c @@ -254,35 +254,28 @@ 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_error_t err; - hal_ks_lock(); + if (alloc && + (err = hal_ks_alloc_common(ks, STATIC_KS_VOLATILE_SLOTS, KS_VOLATILE_CACHE_SIZE, + &mem, sizeof(*db->keys) * STATIC_KS_VOLATILE_SLOTS)) != HAL_OK) + return err; - 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; + if (alloc) db->keys = mem; - } - if (db->keys == NULL) { - err = HAL_ERROR_IMPOSSIBLE; - goto done; - } + if (db->keys == NULL) + return HAL_ERROR_IMPOSSIBLE; for (unsigned b = 0; b < db->ks.size; b++) if ((err = hal_ks_block_erase(ks, b)) != HAL_OK) - goto done; + return err; if ((err = hal_ks_init_common(ks)) != HAL_OK) - goto done; - - err = HAL_OK; + return err; - done: - hal_ks_unlock(); - return err; + return HAL_OK; } /* -- cgit v1.2.3