aboutsummaryrefslogtreecommitdiff
path: root/hal_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'hal_internal.h')
-rw-r--r--hal_internal.h512
1 files changed, 133 insertions, 379 deletions
diff --git a/hal_internal.h b/hal_internal.h
index 461feec..b698611 100644
--- a/hal_internal.h
+++ b/hal_internal.h
@@ -48,7 +48,7 @@
*/
/*
- * htonl is not available in arm-none-eabi headers or libc.
+ * htonl and htons are not available in arm-none-eabi headers or libc.
*/
#ifndef STM32F4XX
#include <arpa/inet.h>
@@ -62,25 +62,80 @@ inline uint32_t htonl(uint32_t w)
((w & 0x00ff0000) >> 8) +
((w & 0xff000000) >> 24);
}
+inline uint16_t htons(uint16_t w)
+{
+ return
+ ((w & 0x00ff) << 8) +
+ ((w & 0xff00) >> 8);
+}
#else /* big endian */
#define htonl(x) (x)
+#define htons(x) (x)
#endif
#define ntohl htonl
+#define ntohs htons
#endif
/*
+ * Low-level I/O convenience functions, moved here from hal.h
+ * because they use symbols defined in verilog_constants.h.
+ */
+
+static inline hal_error_t hal_io_zero(const hal_core_t *core)
+{
+ const uint8_t buf[4] = { 0, 0, 0, 0 };
+ return hal_io_write(core, ADDR_CTRL, buf, sizeof(buf));
+}
+
+static inline hal_error_t hal_io_init(const hal_core_t *core)
+{
+ const uint8_t buf[4] = { 0, 0, 0, CTRL_INIT };
+ return hal_io_write(core, ADDR_CTRL, buf, sizeof(buf));
+}
+
+static inline hal_error_t hal_io_next(const hal_core_t *core)
+{
+ const uint8_t buf[4] = { 0, 0, 0, CTRL_NEXT };
+ return hal_io_write(core, ADDR_CTRL, buf, sizeof(buf));
+}
+
+static inline hal_error_t hal_io_wait_ready(const hal_core_t *core)
+{
+ int limit = -1;
+ return hal_io_wait(core, STATUS_READY, &limit);
+}
+
+static inline hal_error_t hal_io_wait_valid(const hal_core_t *core)
+{
+ int limit = -1;
+ return hal_io_wait(core, STATUS_VALID, &limit);
+}
+
+static inline hal_error_t hal_io_wait_ready2(const hal_core_t *core1, const hal_core_t *core2)
+{
+ int limit = -1;
+ return hal_io_wait2(core1, core2, STATUS_READY, &limit);
+}
+
+static inline hal_error_t hal_io_wait_valid2(const hal_core_t *core1, const hal_core_t *core2)
+{
+ int limit = -1;
+ return hal_io_wait2(core1, core2, STATUS_VALID, &limit);
+}
+
+/*
* 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).
+ * really necessary. Intent is just to allow allocation of 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);
+extern hal_error_t hal_free_static_memory(const void * const ptr);
/*
* Longest hash block and digest we support at the moment.
@@ -235,6 +290,15 @@ typedef struct {
const hal_curve_name_t curve,
const hal_key_flags_t flags);
+ hal_error_t (*generate_hashsig)(const hal_client_handle_t client,
+ const hal_session_handle_t session,
+ hal_pkey_handle_t *pkey,
+ hal_uuid_t *name,
+ const size_t hss_levels,
+ const lms_algorithm_t lms_type,
+ const lmots_algorithm_t lmots_type,
+ const hal_key_flags_t flags);
+
hal_error_t (*close)(const hal_pkey_handle_t pkey);
hal_error_t (*delete)(const hal_pkey_handle_t pkey);
@@ -360,18 +424,17 @@ static inline hal_crc32_t hal_crc32_finalize(hal_crc32_t crc)
* EC P-384: 185 bytes
* EC P-521: 240 bytes
*
+ * Plus extra space for pre-computed speed-up factors specific to our
+ * Verilog implementation, which we store as fixed-length byte strings.
+ *
* Plus we need a bit of AES-keywrap overhead, since we're storing the
* wrapped form (see hal_aes_keywrap_cyphertext_length()).
*
- * 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.
+ * Length check warning moved to ks.h since size of keystore blocks is
+ * internal to the keystore implementation.
*/
-#define HAL_KS_WRAPPED_KEYSIZE ((2373 + 15) & ~7)
+#define HAL_KS_WRAPPED_KEYSIZE ((2373 + 6 * 4096 / 8 + 6 * 4 + 15) & ~7)
/*
* PINs.
@@ -398,8 +461,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).
*
@@ -435,6 +496,12 @@ extern hal_error_t hal_mkm_flash_erase(const size_t len);
#endif
/*
+ * Clean up pkey stuff that's tied to a particular client on logout.
+ */
+
+extern hal_error_t hal_pkey_logout(const hal_client_handle_t client);
+
+/*
* Keystore API for use by the pkey implementation.
*
* In an attempt to emulate what current theory says will eventually
@@ -452,9 +519,9 @@ extern hal_error_t hal_mkm_flash_erase(const size_t len);
*/
typedef struct {
- hal_client_handle_t client_handle;
- hal_session_handle_t session_handle;
- hal_pkey_handle_t pkey_handle;
+ hal_client_handle_t client;
+ hal_session_handle_t session;
+ hal_pkey_handle_t pkey;
hal_key_type_t type;
hal_curve_name_t curve;
hal_key_flags_t flags;
@@ -474,377 +541,63 @@ typedef struct {
*/
} hal_pkey_slot_t;
-typedef struct hal_ks_driver hal_ks_driver_t;
+/*
+ * Keystore is an opaque type, we just pass pointers.
+ */
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);
-
- hal_error_t (*shutdown)(const hal_ks_driver_t * const driver);
-
- hal_error_t (*open)(const hal_ks_driver_t * const driver,
- hal_ks_t **ks);
-
- hal_error_t (*close)(hal_ks_t *ks);
-
- hal_error_t (*store)(hal_ks_t *ks,
- hal_pkey_slot_t *slot,
- const uint8_t * const der, const size_t der_len);
-
- 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_ks_t * const hal_ks_token;
+extern hal_ks_t * const hal_ks_volatile;
- hal_error_t (*delete)(hal_ks_t *ks,
- hal_pkey_slot_t *slot);
+extern hal_error_t hal_ks_init(hal_ks_t *ks,
+ const int alloc);
- 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 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 void hal_ks_init_read_only_pins_only(void);
- hal_error_t (*set_attributes)(hal_ks_t *ks,
+extern hal_error_t hal_ks_store(hal_ks_t *ks,
hal_pkey_slot_t *slot,
- const hal_pkey_attribute_t *attributes,
- const unsigned attributes_len);
+ const uint8_t * const der, const size_t der_len);
- hal_error_t (*get_attributes)(hal_ks_t *ks,
+extern hal_error_t hal_ks_fetch(hal_ks_t *ks,
hal_pkey_slot_t *slot,
- hal_pkey_attribute_t *attributes,
+ 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,
- 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 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 || 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, mask, 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 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_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,
- 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);
+ uint8_t *attributes_buffer,
+ const size_t attributes_buffer_len);
+
+extern hal_error_t hal_ks_logout(hal_ks_t *ks,
+ const hal_client_handle_t client);
+
+extern hal_error_t hal_ks_rewrite_der(hal_ks_t *ks,
+ hal_pkey_slot_t *slot,
+ const uint8_t * const der, const size_t der_len);
/*
* RPC lowest-level send and receive routines. These are blocking, and
@@ -900,9 +653,10 @@ typedef enum {
RPC_FUNC_PKEY_GET_ATTRIBUTES,
RPC_FUNC_PKEY_EXPORT,
RPC_FUNC_PKEY_IMPORT,
+ RPC_FUNC_PKEY_GENERATE_HASHSIG,
} rpc_func_num_t;
-#define RPC_VERSION 0x01010000 /* 1.1.0.0 */
+#define RPC_VERSION 0x01010100 /* 1.1.1.0 */
/*
* RPC client locality. These have to be defines rather than an enum,
@@ -919,7 +673,7 @@ typedef enum {
*/
#ifndef HAL_RPC_MAX_PKT_SIZE
-#define HAL_RPC_MAX_PKT_SIZE 4096
+#define HAL_RPC_MAX_PKT_SIZE 16384
#endif
/*