aboutsummaryrefslogtreecommitdiff
path: root/hal_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'hal_internal.h')
-rw-r--r--hal_internal.h617
1 files changed, 510 insertions, 107 deletions
diff --git a/hal_internal.h b/hal_internal.h
index 5e08c4e..9aa360b 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -36,6 +36,8 @@
#ifndef _HAL_INTERNAL_H_
#define _HAL_INTERNAL_H_
+#include <string.h>
+
#include "hal.h"
#include "verilog_constants.h"
@@ -67,6 +69,20 @@ inline uint32_t htonl(uint32_t w)
#endif
/*
+ * Static memory allocation on start-up. Don't use this except where
+ * really necessary. By design, there's no way to free this, we don't
+ * want to have to manage a heap. Intent is just to allow allocation
+ * things like the large-ish ks_index arrays used by ks_flash.c from a
+ * memory source external to the executable image file (eg, from the
+ * secondary SDRAM chip on the Cryptech Alpha board).
+ *
+ * We shouldn't need this except on the HSM, so for now we don't bother
+ * with implementing a version of this based on malloc() or sbrk().
+ */
+
+extern void *hal_allocate_static_memory(const size_t size);
+
+/*
* Longest hash block and digest we support at the moment.
*/
@@ -169,21 +185,20 @@ typedef struct {
hal_pkey_handle_t *pkey,
const hal_key_type_t type,
const hal_curve_name_t curve,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const uint8_t * const der, const size_t der_len,
const hal_key_flags_t flags);
- hal_error_t (*find)(const hal_client_handle_t client,
+ hal_error_t (*open)(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const hal_key_type_t type,
- const uint8_t * const name, const size_t name_len,
+ const hal_uuid_t * const name,
const hal_key_flags_t flags);
hal_error_t (*generate_rsa)(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const unsigned key_length,
const uint8_t * const public_exponent, const size_t public_exponent_len,
const hal_key_flags_t flags);
@@ -191,7 +206,7 @@ typedef struct {
hal_error_t (*generate_ec)(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const hal_curve_name_t curve,
const hal_key_flags_t flags);
@@ -199,11 +214,11 @@ typedef struct {
hal_error_t (*delete)(const hal_pkey_handle_t pkey);
- hal_error_t (*rename)(const hal_pkey_handle_t pkey,
- const uint8_t * const name, const size_t name_len);
-
hal_error_t (*get_key_type)(const hal_pkey_handle_t pkey,
- hal_key_type_t *key_type);
+ hal_key_type_t *type);
+
+ hal_error_t (*get_key_curve)(const hal_pkey_handle_t pkey,
+ hal_curve_name_t *curve);
hal_error_t (*get_key_flags)(const hal_pkey_handle_t pkey,
hal_key_flags_t *flags);
@@ -213,22 +228,37 @@ typedef struct {
hal_error_t (*get_public_key)(const hal_pkey_handle_t pkey,
uint8_t *der, size_t *der_len, const size_t der_max);
- hal_error_t (*sign)(const hal_session_handle_t session,
- const hal_pkey_handle_t pkey,
+ hal_error_t (*sign)(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
uint8_t * signature, size_t *signature_len, const size_t signature_max);
- hal_error_t (*verify)(const hal_session_handle_t session,
- const hal_pkey_handle_t pkey,
+ hal_error_t (*verify)(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
const uint8_t * const signature, const size_t signature_len);
- hal_error_t (*list)(hal_pkey_info_t *result,
+ hal_error_t (*match)(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 flags,
+ const hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
unsigned *result_len,
const unsigned result_max,
- hal_key_flags_t flags);
+ const hal_uuid_t * const previous_uuid);
+
+ hal_error_t (*set_attributes)(const hal_pkey_handle_t pkey,
+ const hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len);
+
+ hal_error_t (*get_attributes)(const hal_pkey_handle_t pkey,
+ hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ uint8_t *attributes_buffer,
+ const size_t attributes_buffer_len);
} hal_rpc_pkey_dispatch_t;
@@ -241,7 +271,7 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote
* See code in rpc_pkey.c for how this flag fits into the pkey handle.
*/
-#define HAL_PKEY_HANDLE_PROXIMATE_FLAG (1 << 31)
+#define HAL_PKEY_HANDLE_TOKEN_FLAG (1 << 31)
/*
* Mostly used by the local_pkey code, but the mixed_pkey code needs
@@ -251,19 +281,33 @@ extern const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch, hal_rpc_remote
* and just pass the plain hash for everything else.
*/
-extern hal_error_t hal_rpc_pkey_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
- uint8_t *digest_info, size_t *digest_info_len,
- const size_t digest_info_max);
+extern hal_error_t hal_rpc_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
+ uint8_t *digest_info, size_t *digest_info_len,
+ const size_t digest_info_max);
/*
- * Keystore API.
- *
- * The original design for this subsystem used two separate tables,
- * one for RSA keys, one for EC keys, because the RSA keys are so much
- * larger than the EC keys. This led to unnecessarily complex and
- * duplicated code, so for now we treat all keys the same, and waste
- * the unneeded space in the case of EC keys.
+ * CRC-32 stuff (for flash keystore, etc). Dunno if we want a Verilog
+ * implementation of this, or if it would even be faster than doing it
+ * the main CPU taking I/O overhead and so forth into account.
*
+ * These prototypes were generated by pycrc.py, see notes in crc32.c.
+ */
+
+typedef uint32_t hal_crc32_t;
+
+static inline hal_crc32_t hal_crc32_init(void)
+{
+ return 0xffffffff;
+}
+
+extern hal_crc32_t hal_crc32_update(hal_crc32_t crc, const void *data, size_t data_len);
+
+static inline hal_crc32_t hal_crc32_finalize(hal_crc32_t crc)
+{
+ return crc ^ 0xffffffff;
+}
+
+/*
* Sizes for ASN.1-encoded keys, this may not be exact due to ASN.1
* INTEGER encoding rules but should be good enough for buffer sizing:
*
@@ -277,32 +321,21 @@ extern hal_error_t hal_rpc_pkey_pkcs1_construct_digestinfo(const hal_hash_handle
* 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
- * data structure 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.
+ * A buffer big enough for a 8192-bit RSA key would overflow one
+ * sub-sector on the flash chip we're using on the Alpha. We could
+ * invent some more complex scheme where key blocks are allowed to
+ * span multiple sub-sectors, but since an 8192-bit RSA key would also
+ * be unusably slow with the current RSA implementation, for the
+ * moment we take the easy way out and cap this at 4096-bit RSA.
*/
-#define HAL_KS_WRAPPED_KEYSIZE ((4655 + 15) & ~7)
+#define HAL_KS_WRAPPED_KEYSIZE ((2351 + 15) & ~7)
-#ifndef HAL_STATIC_PKEY_STATE_BLOCKS
-#define HAL_STATIC_PKEY_STATE_BLOCKS 0
-#endif
-
-/* This struct is ordered such that all metadata appears before the
- * big buffers, in order for all metadata to be loaded with a single
- * page read from e.g. the ks_flash module.
+/*
+ * PINs.
+ *
+ * The functions here might want renaming, eg, to hal_pin_*().
*/
-typedef struct {
- hal_key_type_t type;
- hal_curve_name_t curve;
- hal_key_flags_t flags;
- uint8_t in_use;
- size_t name_len;
- size_t der_len;
- uint8_t name[HAL_RPC_PKEY_NAME_MAX];
- uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
-} hal_ks_key_t;
#ifndef HAL_PIN_SALT_LENGTH
#define HAL_PIN_SALT_LENGTH 16
@@ -314,40 +347,47 @@ typedef struct {
uint8_t salt[HAL_PIN_SALT_LENGTH];
} hal_ks_pin_t;
-typedef struct {
-
-#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
- hal_ks_key_t keys[HAL_STATIC_PKEY_STATE_BLOCKS];
-#else
- #warning No keys in keydb
-#endif
-
- hal_ks_pin_t wheel_pin;
- hal_ks_pin_t so_pin;
- hal_ks_pin_t user_pin;
-
-} hal_ks_keydb_t;
-
extern hal_error_t hal_set_pin_default_iterations(const hal_client_handle_t client,
const uint32_t iterations);
+extern hal_error_t hal_get_pin(const hal_user_t user,
+ const hal_ks_pin_t **pin);
+
+extern hal_error_t hal_set_pin(const hal_user_t user,
+ const hal_ks_pin_t * const pin);
+
/*
- * Internal functions within the keystore implementation. Think of
- * these as concrete methods for the keystore API subclassed onto
- * various storage technologies.
+ * Master key memory (MKM) and key-encryption-key (KEK).
+ *
+ * Providing a mechanism for storing the KEK in flash is a horrible
+ * kludge which defeats the entire purpose of having the MKM. We
+ * support it for now because the Alpha hardware does not yet have
+ * a working battery backup for the MKM, but it should go away RSN.
*/
-extern const hal_ks_keydb_t *hal_ks_get_keydb(void);
+#ifndef HAL_MKM_FLASH_BACKUP_KLUDGE
+#define HAL_MKM_FLASH_BACKUP_KLUDGE 1
+#endif
+
+#ifndef KEK_LENGTH
+#define KEK_LENGTH (bitsToBytes(256))
+#endif
+
+extern hal_error_t hal_mkm_get_kek(uint8_t *kek, size_t *kek_len, const size_t kek_max);
+
+extern hal_error_t hal_mkm_volatile_read(uint8_t *buf, const size_t len);
+extern hal_error_t hal_mkm_volatile_write(const uint8_t * const buf, const size_t len);
+extern hal_error_t hal_mkm_volatile_erase(const size_t len);
-extern hal_error_t hal_ks_set_keydb(const hal_ks_key_t * const key,
- const int loc,
- const int updating);
+#if HAL_MKM_FLASH_BACKUP_KLUDGE
-extern hal_error_t hal_ks_del_keydb(const int loc);
+/* #warning MKM flash backup kludge enabled. Do NOT use this in production! */
-extern hal_error_t hal_ks_get_kek(uint8_t *kek,
- size_t *kek_len,
- const size_t kek_max);
+extern hal_error_t hal_mkm_flash_read(uint8_t *buf, const size_t len);
+extern hal_error_t hal_mkm_flash_write(const uint8_t * const buf, const size_t len);
+extern hal_error_t hal_mkm_flash_erase(const size_t len);
+
+#endif
/*
* Keystore API for use by the pkey implementation.
@@ -359,44 +399,405 @@ extern hal_error_t hal_ks_get_kek(uint8_t *kek,
* Unclear whether these should also call the ASN.1 encode/decode
* functions. For the moment, the answer is no, but we may need to
* revisit this as the underlying Verilog API evolves.
+ *
+ * hal_pkey_slot_t is defined here too, so that keystore drivers can
+ * piggyback on the pkey database for storage related to keys on which
+ * the user currently has an active pkey handle. Nothing outside the
+ * pkey and keystore code should touch this.
*/
-extern hal_error_t hal_ks_store(const hal_key_type_t type,
- const hal_curve_name_t curve,
- const hal_key_flags_t flags,
- const uint8_t * const name, const size_t name_len,
- const uint8_t * const der, const size_t der_len,
- int *hint);
+typedef struct {
+ hal_client_handle_t client_handle;
+ hal_session_handle_t session_handle;
+ hal_pkey_handle_t pkey_handle;
+ hal_key_type_t type;
+ hal_curve_name_t curve;
+ hal_key_flags_t flags;
+ hal_uuid_t name;
+ int hint;
+
+ /*
+ * This might be where we'd stash a (hal_core_t *) pointing to a
+ * core which has already been loaded with the key, if we were
+ * trying to be clever about using multiple signing cores. Moot
+ * point (ie, no way we could possibly test such a thing) as long as
+ * the FPGA is too small to hold more than one modexp core and ECDSA
+ * is entirely software, so skip it for now, but the implied
+ * semantics are interesting: a pkey handle starts to resemble an
+ * initialized signing core, and once all the cores are in use, one
+ * can't load another key without closing an existing pkey handle.
+ */
+} hal_pkey_slot_t;
+
+typedef struct hal_ks_driver hal_ks_driver_t;
+
+typedef struct hal_ks hal_ks_t;
+
+struct hal_ks_driver {
+
+ hal_error_t (*init)(const hal_ks_driver_t * const driver,
+ const int alloc);
-extern hal_error_t hal_ks_exists(const hal_key_type_t type,
- const uint8_t * const name, const size_t name_len,
- int *hint);
+ hal_error_t (*shutdown)(const hal_ks_driver_t * const driver);
-extern hal_error_t hal_ks_fetch(const hal_key_type_t type,
- const uint8_t * const name, const size_t name_len,
- hal_curve_name_t *curve,
- hal_key_flags_t *flags,
- uint8_t *der, size_t *der_len, const size_t der_max,
- int *hint);
+ hal_error_t (*open)(const hal_ks_driver_t * const driver,
+ hal_ks_t **ks);
-extern hal_error_t hal_ks_delete(const hal_key_type_t type,
- const uint8_t * const name, const size_t name_len,
- int *hint);
+ hal_error_t (*close)(hal_ks_t *ks);
-extern hal_error_t hal_ks_rename(const hal_key_type_t type,
- const uint8_t * const old_name, const size_t old_name_len,
- const uint8_t * const new_name, const size_t new_name_len,
- int *hint);
+ hal_error_t (*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_list(hal_pkey_info_t *result,
- unsigned *result_len,
- const unsigned result_max);
+ hal_error_t (*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_get_pin(const hal_user_t user,
- const hal_ks_pin_t **pin);
+ hal_error_t (*delete)(hal_ks_t *ks,
+ hal_pkey_slot_t *slot);
+
+ hal_error_t (*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 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);
+
+ hal_error_t (*set_attributes)(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len);
+
+ hal_error_t (*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);
+
+};
+
+
+struct hal_ks {
+ const hal_ks_driver_t *driver;
+ /*
+ * Any other common portions of hal_ks_t go here.
+ */
+
+ /*
+ * Driver-specific stuff is handled by a form of subclassing:
+ * driver module embeds this structure at the head of whatever
+ * else it needs, and performs casts as needed.
+ */
+};
+
+extern const hal_ks_driver_t
+ hal_ks_volatile_driver[1],
+ hal_ks_token_driver[1];
+
+static inline hal_error_t hal_ks_init(const hal_ks_driver_t * const driver,
+ const int alloc)
+{
+ if (driver == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (driver->init == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return driver->init(driver, alloc);
+}
+
+static inline hal_error_t hal_ks_shutdown(const hal_ks_driver_t * const driver)
+{
+ if (driver == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (driver->shutdown == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return driver->shutdown(driver);
+}
+
+static inline hal_error_t hal_ks_open(const hal_ks_driver_t * const driver,
+ hal_ks_t **ks)
+{
+ if (driver == NULL || ks == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (driver->open == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return driver->open(driver, ks);
+}
+
+static inline hal_error_t hal_ks_close(hal_ks_t *ks)
+{
+ if (ks == NULL || ks->driver == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->close == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->close(ks);
+}
+
+static inline 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)
+{
+ if (ks == NULL || ks->driver == NULL || slot == NULL || der == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->store == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->store(ks, slot, der, der_len);
+}
+
+static inline 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)
+{
+ if (ks == NULL || ks->driver == NULL || slot == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->fetch == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->fetch(ks, slot, der, der_len, der_max);
+}
+
+static inline hal_error_t hal_ks_delete(hal_ks_t *ks,
+ hal_pkey_slot_t *slot)
+{
+ if (ks == NULL || ks->driver == NULL || slot == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->delete == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->delete(ks, slot);
+}
+
+static inline 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 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 || ks->driver == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->match == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->match(ks, client, session, type, curve, flags, attributes, attributes_len,
+ result, result_len, result_max, previous_uuid);
+}
+
+static inline 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)
+{
+ if (ks == NULL || ks->driver == NULL || slot == NULL ||
+ attributes == NULL || attributes_len == 0)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->set_attributes == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->set_attributes(ks, slot, attributes, attributes_len);
+}
+
+static inline 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)
+{
+ if (ks == NULL || ks->driver == NULL || slot == NULL ||
+ attributes == NULL || attributes_len == 0)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ if (ks->driver->get_attributes == NULL)
+ return HAL_ERROR_NOT_IMPLEMENTED;
+
+ return ks->driver->get_attributes(ks, slot, attributes, attributes_len,
+ attributes_buffer, attributes_buffer_len);
+}
+
+/*
+ * Keystore index. This is intended to be usable by both memory-based
+ * (in-memory, mmap(), ...) keystores and keystores based on raw flash.
+ * Some of the features aren't really necessary for memory-based keystores,
+ * but should be harmless.
+ *
+ * General approach is multiple arrays, all but one of which are
+ * indexed by "block" numbers, where a block number might be a slot in
+ * yet another static array, the number of a flash sub-sector, or
+ * whatever is the appropriate unit for holding one keystore record.
+ *
+ * The index array contains nothing but flags and block numbers, and
+ * is deliberately a small data structure so that moving data around
+ * within it is relatively cheap.
+ *
+ * The index array is divided into two portions: the index proper, and
+ * the free queue. The index proper is ordered according to the names
+ * (UUIDs) of the corresponding blocks; the free queue is a FIFO, to
+ * support a simplistic form of wear leveling in flash-based keystores.
+ *
+ * Key names are kept in a separate array, indexed by block number.
+ * Key names here are a composite of the key's UUID and a "chunk"
+ * number; the latter allows storage of keys whose total size exceeds
+ * one block (whatever a block is). For the moment we keep the UUID
+ * and the chunk number in a single array, which may provide (very)
+ * slightly better performance due to reference locality in SDRAM, but
+ * this may change if we need to reclaim the space wasted by structure
+ * size rounding.
+ *
+ * The all-zeros UUID, which (by definition) cannot be a valid key
+ * UUID, is reserved for the (non-key) block used to stash PINs and
+ * other small data which aren't really part of the keystore proper
+ * but are kept with it because the keystore is the flash we have.
+ *
+ * Note that this API deliberately says nothing about how the keys
+ * themselves are stored, that's up to the keystore driver. This
+ * portion of the API is only concerned with allocation and naming.
+ */
+
+typedef struct {
+ hal_uuid_t name; /* Key name */
+ uint8_t chunk; /* Key chunk number */
+} hal_ks_name_t;
+
+typedef struct {
+ unsigned size; /* Array length */
+ unsigned used; /* How many blocks are in use */
+ uint16_t *index; /* Index/freelist array */
+ hal_ks_name_t *names; /* Keyname array */
+} hal_ks_index_t;
+
+/*
+ * Finish setting up key index. Caller must populate index, free
+ * list, and name array.
+ *
+ * This function checks a few things then sorts the index proper.
+ *
+ * If driver cares about wear leveling, driver must supply the free
+ * list in the desired order (FIFO); figuring out what that order is a
+ * problem for the keystore driver.
+ */
+extern hal_error_t hal_ks_index_setup(hal_ks_index_t *ksi);
+
+/*
+ * Find a key block, return its block number.
+ */
+extern hal_error_t hal_ks_index_find(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned chunk,
+ unsigned *blockno,
+ int *hint);
+
+/*
+ * Find all the blocks in a key, return the block numbers.
+ */
+extern hal_error_t hal_ks_index_find_range(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned max_blocks,
+ unsigned *n_blocks,
+ unsigned *blocknos,
+ int *hint,
+ const int strict);
+
+/*
+ * Add a key block, return its block number.
+ */
+extern hal_error_t hal_ks_index_add(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned chunk,
+ unsigned *blockno,
+ int *hint);
+
+/*
+ * Delete a key block, returns its block number (driver may need it).
+ */
+extern hal_error_t hal_ks_index_delete(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned chunk,
+ unsigned *blockno,
+ int *hint);
+
+/*
+ * Delete all of blocks in a key, returning the block numbers.
+ */
+
+extern hal_error_t hal_ks_index_delete_range(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned max_blocks,
+ unsigned *n_blocks,
+ unsigned *blocknos,
+ int *hint);
+
+/*
+ * Replace a key block with a new one, return new block number.
+ * Name of block does not change. This is an optimization of
+ * a delete immediately followed by an add for the same name.
+ */
+
+extern hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi,
+ const hal_uuid_t * const name,
+ const unsigned chunk,
+ unsigned *blockno,
+ int *hint);
+
+/*
+ * Check the index for errors. At least for the moment, this just
+ * reports errors, it doesn't attempt to fix them.
+ */
+
+extern hal_error_t hal_ks_index_fsck(hal_ks_index_t *ksi);
+
+/*
+ * Keystore attribute utilities, for use by keystore drivers.
+ */
-extern hal_error_t hal_ks_set_pin(const hal_user_t user,
- const hal_ks_pin_t * const pin);
+extern const size_t hal_ks_attribute_header_size;
+
+extern hal_error_t hal_ks_attribute_scan(const uint8_t * const bytes,
+ const size_t bytes_len,
+ hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ size_t *total_len);
+
+extern hal_error_t hal_ks_attribute_delete(uint8_t *bytes,
+ const size_t bytes_len,
+ hal_pkey_attribute_t *attributes,
+ unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type);
+
+extern hal_error_t hal_ks_attribute_insert(uint8_t *bytes, const size_t bytes_len,
+ hal_pkey_attribute_t *attributes,
+ unsigned *attributes_len,
+ size_t *total_len,
+ const uint32_t type,
+ const uint8_t * const value,
+ const size_t value_len);
/*
* RPC lowest-level send and receive routines. These are blocking, and
@@ -421,7 +822,7 @@ extern hal_error_t hal_rpc_server_transport_close(void);
*/
typedef enum {
- RPC_FUNC_GET_VERSION = 0,
+ RPC_FUNC_GET_VERSION,
RPC_FUNC_GET_RANDOM,
RPC_FUNC_SET_PIN,
RPC_FUNC_LOGIN,
@@ -435,7 +836,7 @@ typedef enum {
RPC_FUNC_HASH_UPDATE,
RPC_FUNC_HASH_FINALIZE,
RPC_FUNC_PKEY_LOAD,
- RPC_FUNC_PKEY_FIND,
+ RPC_FUNC_PKEY_OPEN,
RPC_FUNC_PKEY_GENERATE_RSA,
RPC_FUNC_PKEY_GENERATE_EC,
RPC_FUNC_PKEY_CLOSE,
@@ -446,8 +847,10 @@ typedef enum {
RPC_FUNC_PKEY_GET_PUBLIC_KEY,
RPC_FUNC_PKEY_SIGN,
RPC_FUNC_PKEY_VERIFY,
- RPC_FUNC_PKEY_LIST,
- RPC_FUNC_PKEY_RENAME,
+ RPC_FUNC_PKEY_MATCH,
+ RPC_FUNC_PKEY_GET_KEY_CURVE,
+ RPC_FUNC_PKEY_SET_ATTRIBUTES,
+ RPC_FUNC_PKEY_GET_ATTRIBUTES,
} rpc_func_num_t;
#define RPC_VERSION 0x01010000 /* 1.1.0.0 */