From db32574d6c85bb48a2f01d80eec6e241152704ff Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 7 Oct 2016 17:32:14 -0400 Subject: Checkpoint along the way to adding keystore attribute support. This is mostly to archive a commit where PKCS #11 "make test" still works after converting the ks_volatile code to use SDRAM allocated at startup instead of (large) static variables. The attribute code itself is incomplete at this point. --- hal_internal.h | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) (limited to 'hal_internal.h') diff --git a/hal_internal.h b/hal_internal.h index 11f9898..0d40922 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -242,6 +242,30 @@ typedef struct { const unsigned result_max, hal_key_flags_t flags); + hal_error_t (*match)(const hal_key_type_t type, + const hal_curve_name_t curve, + const hal_key_flags_t flags, + hal_rpc_pkey_attribute_t *attributes, + const unsigned attributes_len, + hal_uuid_t *result, + unsigned *result_len, + const unsigned result_max, + hal_uuid_t *previous_uuid); + + hal_error_t (*set_attribute)(const hal_pkey_handle_t pkey, + const uint32_t type, + const uint8_t * const value, + const size_t value_len); + + hal_error_t (*get_attribute)(const hal_pkey_handle_t pkey, + const uint32_t type, + uint8_t *value, + size_t *value_len, + const size_t value_max); + + hal_error_t (*delete_attribute)(const hal_pkey_handle_t pkey, + const uint32_t type); + } hal_rpc_pkey_dispatch_t; @@ -470,6 +494,35 @@ struct hal_ks_driver { hal_pkey_info_t *result, unsigned *result_len, const unsigned result_max); + + hal_error_t (*match)(hal_ks_t *ks, + const hal_key_type_t type, + const hal_curve_name_t curve, + const hal_key_flags_t flags, + hal_rpc_pkey_attribute_t *attributes, + const unsigned attributes_len, + hal_uuid_t *result, + unsigned *result_len, + const unsigned result_max, + hal_uuid_t *previous_uuid); + + hal_error_t (*set_attribute)(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type, + const uint8_t * const value, + const size_t value_len); + + hal_error_t (*get_attribute)(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type, + uint8_t *value, + size_t *value_len, + const size_t value_max); + + hal_error_t (*delete_attribute)(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type); + }; @@ -563,6 +616,59 @@ static inline hal_error_t hal_ks_list(hal_ks_t *ks, return ks->driver->list(ks, result, result_len, result_max); } +static inline hal_error_t hal_ks_match(hal_ks_t *ks, + const hal_key_type_t type, + const hal_curve_name_t curve, + const hal_key_flags_t flags, + hal_rpc_pkey_attribute_t *attributes, + const unsigned attributes_len, + hal_uuid_t *result, + unsigned *result_len, + const unsigned result_max, + hal_uuid_t *previous_uuid) +{ + if (ks == NULL || ks->driver == NULL || ks->driver->match == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + return ks->driver->match(ks, type, curve, flags, attributes, attributes_len, + result, result_len, result_max, previous_uuid); +} + +static inline hal_error_t hal_ks_set_attribute(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type, + const uint8_t * const value, + const size_t value_len) +{ + if (ks == NULL || ks->driver == NULL || ks->driver->set_attribute == NULL || slot == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + return ks->driver->set_attribute(ks, slot, type, value, value_len); +} + +static inline hal_error_t hal_ks_get_attribute(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type, + uint8_t *value, + size_t *value_len, + const size_t value_max) +{ + if (ks == NULL || ks->driver == NULL || ks->driver->get_attribute == NULL || slot == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + return ks->driver->get_attribute(ks, slot, type, value, value_len, value_max); +} + +static inline hal_error_t hal_ks_delete_attribute(hal_ks_t *ks, + hal_pkey_slot_t *slot, + const uint32_t type) +{ + if (ks == NULL || ks->driver == NULL || ks->driver->delete_attribute == NULL || slot == NULL) + return HAL_ERROR_BAD_ARGUMENTS; + + return ks->driver->delete_attribute(ks, slot, type); +} + /* * Keystore index. This is intended to be usable by both memory-based * (in-memory, mmap(), ...) keystores and keystores based on raw flash. @@ -675,6 +781,69 @@ extern hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi, unsigned *blockno, int *hint); +/* + * Keystore attribute utilities, for use by keystore drivers. + * + * Basic model here is probably to replace the "der" block in a key + * object with a byte array. We could use padding to get alignment, + * but it's probably easier just to do this DNS style, pulling a + * 16-bit length and 32-bit attribute type out of the byte array + * directly. Well, maybe. I guess if we cast the uint8_t* to a + * structure pointer we could use the structure to pull out the header + * fields, but that has portability issues, particulary if the + * compiler gets tetchy about type punning. + * + * Unclear whether we should treat the key DER specially. Might just + * give it an attribute code of 0xFFFFFFFF and treat it same as + * everything else, just always first for convenience. This assumes + * that PKCS #11 will never use 0xFFFFFFFF, which is a bit risky, but + * maybe the code just treats it a little bit specially and knows to + * skip over the key DER when looking for attributes, etc. + * + * We probably don't want to let attributes span block boundaries. We + * probably do want to attempt to fit a new attribute into the first + * available space which can hold it. In theory, taken together, this + * means we will only have to update multiple blocks when required to + * add a new block (in which case the max_blocks count changes). Most + * of this only applies to flash, for volatile we can use as much + * memory as we like, although even there we might want smaller chunks + * to avoid wasting huge tracts of space that don't end up being used. + * But maybe that's just a configuration thing for the volatile + * keystore(s). + * + * If we have to rewrite a block at all we might as well compact it, + * so fragmentation in that sense is a non-issue. Might need to + * collapse blocks when deletion has freed up enough space, but that + * might be something we handle directly in ks_flash rather than in + * the ks_attribute code. + * + * We need some way of figuring out how many attributes there are. + * Options are a marker (like the IPv4 END-OF-OPTIONS option) or a + * count in the header. Count is simpler and lets us pre-allocate + * arrays so probably go with that. + */ + +extern hal_error_t hal_ks_attribute_scan(const uint8_t * const bytes, + const size_t bytes_len, + hal_rpc_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_rpc_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_rpc_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 * transport-specific (sockets, USB). @@ -725,6 +894,10 @@ typedef enum { RPC_FUNC_PKEY_VERIFY, RPC_FUNC_PKEY_LIST, RPC_FUNC_PKEY_RENAME, + RPC_FUNC_PKEY_MATCH, + RPC_FUNC_PKEY_SET_ATTRIBUTE, + RPC_FUNC_PKEY_GET_ATTRIBUTE, + RPC_FUNC_PKEY_DELETE_ATTRIBUTE, } rpc_func_num_t; #define RPC_VERSION 0x01010000 /* 1.1.0.0 */ -- cgit v1.2.3