aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-09-09 20:36:24 -0400
committerRob Austein <sra@hactrn.net>2016-09-09 20:36:24 -0400
commitd56ce9ab6cfd874b0bbcba204b33af4e7e762517 (patch)
tree55aee648ed5c2d305ab0a1e836c0c08b128fa9bc
parent8677e58ebc751ab47f1a14273b7ef19dfa17a293 (diff)
Rewrite ks_volatile driver to use new ks_index infrastructure.
-rw-r--r--hal_internal.h5
-rw-r--r--ks_volatile.c172
2 files changed, 90 insertions, 87 deletions
diff --git a/hal_internal.h b/hal_internal.h
index 59efbff..cc2d749 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -293,11 +293,6 @@ extern hal_error_t hal_uuid_format(const hal_uuid_t * const uuid, char *buffer,
*
* Plus we need a bit of AES-keywrap overhead, since we're storing the
* wrapped form (see hal_aes_keywrap_cyphertext_length()).
- *
- * We also need to store PINs somewhere, so they go into the keystore
- * even though they're not keys. Like keys, they're stored in a
- * relatively safe form (PBKDF2), so while we would prefer to keep
- * them private, they don't require tamper-protected RAM.
*/
#define HAL_KS_WRAPPED_KEYSIZE ((4655 + 15) & ~7)
diff --git a/ks_volatile.c b/ks_volatile.c
index 4ff23fb..c38d568 100644
--- a/ks_volatile.c
+++ b/ks_volatile.c
@@ -48,32 +48,31 @@
#define HAL_STATIC_PKEY_STATE_BLOCKS 0
#endif
+#ifndef HAL_STATIC_KS_VOLATILE_SLOTS
+#define HAL_STATIC_KS_VOLATILE_SLOTS HAL_STATIC_PKEY_STATE_BLOCKS
+#endif
+
+#if HAL_STATIC_KS_VOLATILE_SLOTS > 0
+
/*
- * Keystore database itself. For the moment, we stick to the old
- * model where the entire database is wrapped in a C structure. We
- * may want to change this, but if so, we'll need a replacement for
- * the length check. If we do decide to replace it, we may want to
- * keep the C structure but replace the fixed size array with a C99
- * "flexible array", ie,
- *
- * hal_ks_key_t keys[];
- *
- * which is like the old GCC zero-length array hack, and can only
- * go at the end of the structure.
+ * 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).
*/
typedef struct {
+ hal_key_type_t type;
+ hal_curve_name_t curve;
+ hal_key_flags_t flags;
+ size_t der_len;
+ uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
+} ks_key_t;
- hal_ks_pin_t wheel_pin;
- hal_ks_pin_t so_pin;
- hal_ks_pin_t user_pin;
-
-#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
- hal_ks_key_t keys[HAL_STATIC_PKEY_STATE_BLOCKS];
-#else
-#warning No keys in keydb
-#endif
-
+typedef struct {
+ hal_ks_index_t ksi;
+ uint16_t _index[HAL_STATIC_KS_VOLATILE_SLOTS];
+ hal_uuid_t _names[HAL_STATIC_KS_VOLATILE_SLOTS];
+ ks_key_t keys[HAL_STATIC_KS_VOLATILE_SLOTS];
} db_t;
/*
@@ -90,19 +89,51 @@ typedef struct {
static db_t volatile_db;
-static ks_t volatile_ks = { { hal_ks_volatile_driver }, &volatile_db };
+static ks_t volatile_ks = {
+ { hal_ks_volatile_driver },
+ &volatile_db
+};
static inline ks_t *ks_to_ksv(hal_ks_t *ks)
{
return (ks_t *) ks;
}
+static hal_error_t ks_init(db_t *db)
+{
+ assert(db != NULL);
+
+ if (db->ksi.size) /* Already initialized */
+ return HAL_OK;
+
+ /*
+ * 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.
+ */
+
+ db->ksi.size = HAL_STATIC_KS_VOLATILE_SLOTS;
+ db->ksi.used = 0;
+ db->ksi.index = db->_index;
+ db->ksi.names = db->_names;
+
+ for (int i = 0; i < HAL_STATIC_KS_VOLATILE_SLOTS; i++)
+ db->_index[i] = i;
+
+ const hal_error_t err = hal_ks_index_setup(&db->ksi);
+
+ if (err != HAL_OK)
+ db->ksi.size = 0; /* Mark uninitialized if setup failed */
+
+ return err;
+}
+
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;
+ return ks_init(volatile_ks.db);
}
static hal_error_t ks_volatile_close(hal_ks_t *ks)
@@ -132,58 +163,35 @@ static hal_error_t ks_store(hal_ks_t *ks,
ks_t *ksv = ks_to_ksv(ks);
hal_error_t err;
+ unsigned b;
if (ksv->db == NULL)
return HAL_ERROR_KEYSTORE_ACCESS;
- int loc = -1;
-
- for (int i = 0; i < sizeof(ksv->db->keys)/sizeof(*ksv->db->keys); i++) {
- if (!ksv->db->keys[i].in_use && loc < 0)
- loc = i;
- if (ksv->db->keys[i].in_use &&
- hal_uuid_cmp(&ksv->db->keys[i].name, &slot->name) == 0)
- return HAL_ERROR_KEY_NAME_IN_USE;
- }
+ if ((err = hal_ks_index_add(&ksv->db->ksi, &slot->name, &b)) != HAL_OK)
+ return err;
- if (loc < 0)
- return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
+ uint8_t kek[KEK_LENGTH];
+ size_t kek_len;
+ ks_key_t k;
- hal_ks_key_t k;
memset(&k, 0, sizeof(k));
k.der_len = sizeof(k.der);
-
- uint8_t kek[KEK_LENGTH];
- size_t kek_len;
+ k.type = slot->type;
+ k.curve = slot->curve;
+ k.flags = slot->flags;
if ((err = hal_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);
memset(kek, 0, sizeof(kek));
- if (err != HAL_OK)
- return err;
-
- k.name = slot->name;
- k.type = slot->type;
- k.curve = slot->curve;
- k.flags = slot->flags;
-
- ksv->db->keys[loc] = k;
- ksv->db->keys[loc].in_use = 1;
-
- return HAL_OK;
-}
-
-static hal_ks_key_t *find(ks_t *ksv, const hal_uuid_t * const name)
-{
- assert(ksv != NULL && name != NULL);
-
- for (int i = 0; i < sizeof(ksv->db->keys)/sizeof(*ksv->db->keys); i++)
- if (ksv->db->keys[i].in_use && hal_uuid_cmp(&ksv->db->keys[i].name, name) == 0)
- return &ksv->db->keys[i];
+ if (err == HAL_OK)
+ ksv->db->keys[b] = k;
+ else
+ (void) hal_ks_index_delete(&ksv->db->ksi, &slot->name, NULL);
- return NULL;
+ return err;
}
static hal_error_t ks_fetch(hal_ks_t *ks,
@@ -194,14 +202,16 @@ static hal_error_t ks_fetch(hal_ks_t *ks,
return HAL_ERROR_BAD_ARGUMENTS;
ks_t *ksv = ks_to_ksv(ks);
+ hal_error_t err;
+ unsigned b;
if (ksv->db == NULL)
return HAL_ERROR_KEYSTORE_ACCESS;
- const hal_ks_key_t * const k = find(ksv, &slot->name);
+ if ((err = hal_ks_index_find(&ksv->db->ksi, &slot->name, &b)) != HAL_OK)
+ return err;
- if (k == NULL)
- return HAL_ERROR_KEY_NOT_FOUND;
+ const ks_key_t * const k = &ksv->db->keys[b];
slot->type = k->type;
slot->curve = k->curve;
@@ -240,16 +250,16 @@ static hal_error_t ks_delete(hal_ks_t *ks,
return HAL_ERROR_BAD_ARGUMENTS;
ks_t *ksv = ks_to_ksv(ks);
+ hal_error_t err;
+ unsigned b;
if (ksv->db == NULL)
return HAL_ERROR_KEYSTORE_ACCESS;
- hal_ks_key_t *k = find(ksv, &slot->name);
-
- if (k == NULL)
- return HAL_ERROR_KEY_NOT_FOUND;
+ if ((err = hal_ks_index_delete(&ksv->db->ksi, &slot->name, &b)) != HAL_OK)
+ return err;
- memset(k, 0, sizeof(*k));
+ memset(&ksv->db->keys[b], 0, sizeof(ksv->db->keys[b]));
return HAL_OK;
}
@@ -267,23 +277,19 @@ static hal_error_t ks_list(hal_ks_t *ks,
if (ksv->db == NULL)
return HAL_ERROR_KEYSTORE_ACCESS;
- *result_len = 0;
-
- for (int i = 0; i < sizeof(ksv->db->keys)/sizeof(*ksv->db->keys); i++) {
-
- if (!ksv->db->keys[i].in_use)
- continue;
+ if (ksv->db->ksi.used > result_max)
+ return HAL_ERROR_RESULT_TOO_LONG;
- if (*result_len == result_max)
- return HAL_ERROR_RESULT_TOO_LONG;
-
- result[*result_len].type = ksv->db->keys[i].type;
- result[*result_len].curve = ksv->db->keys[i].curve;
- result[*result_len].flags = ksv->db->keys[i].flags;
- result[*result_len].name = ksv->db->keys[i].name;
- ++ *result_len;
+ for (int i = 0; i < ksv->db->ksi.used; i++) {
+ unsigned b = ksv->db->ksi.index[i];
+ result[i].name = ksv->db->ksi.names[b];
+ result[i].type = ksv->db->keys[b].type;
+ result[i].curve = ksv->db->keys[b].curve;
+ result[i].flags = ksv->db->keys[b].flags;
}
+ *result_len = ksv->db->ksi.used;
+
return HAL_OK;
}
@@ -296,6 +302,8 @@ const hal_ks_driver_t hal_ks_volatile_driver[1] = {{
ks_list
}};
+#endif /* HAL_STATIC_KS_VOLATILE_SLOTS > 0 */
+
/*
* Local variables:
* indent-tabs-mode: nil