From 378bcae718b7b8785b06c8cf82344e4f344a9215 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 30 Sep 2016 08:34:59 -0400 Subject: Multi-block object support in keystore. The main reason for supporting multi-block objects is to allow the PKCS #11 code to attach more attributes than will fit comfortably in a single flash block. This may turn out to be unnecessary once we've fleshed out the attribute storage and retrieval code; if so, we can simplify the code, but this way the keystore won't impose arbitrary (and somewhat inscrutable) size limits on PKCS #11 attributes for large keys. This snapshot passes light testing (PKCS #11 "make test" runs), but the tombstone recovery code in ks_init() is a bit involved, and needs more testing with simulated failures (probably induced under GDB). --- hal_internal.h | 52 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) (limited to 'hal_internal.h') diff --git a/hal_internal.h b/hal_internal.h index ef0d763..11f9898 100644 --- a/hal_internal.h +++ b/hal_internal.h @@ -584,32 +584,34 @@ static inline hal_error_t hal_ks_list(hal_ks_t *ks, * 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-ones UUID, which (by definition) cannot be a valid key + * 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. * - * At the moment, this design leaves no room for "continuation" blocks - * (additional blocks for keys so large that they won't fit in a - * single flash sub-sector, or whatever). Not sure we need that, but - * if we do, adding it would be fairly simple: change the keyname - * array to be an array of two-element structures, the first of which - * is the name UUID, the second of which is the offset within the - * series of blocks sharing that name (usually just one block, so the - * offset would usually just be zero). Implement that if and when we - * need it. - * * 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_uuid_t *names; /* Keyname array */ + hal_ks_name_t *names; /* Keyname array */ } hal_ks_index_t; /* @@ -629,21 +631,37 @@ extern hal_error_t hal_ks_index_setup(hal_ks_index_t *ksi); */ extern hal_error_t hal_ks_index_find(hal_ks_index_t *ksi, const hal_uuid_t * const name, - unsigned *blockno); + 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); /* * 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, - unsigned *blockno); + 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, - unsigned *blockno); + const unsigned chunk, + unsigned *blockno, + int *hint); /* * Replace a key block with a new one, return new block number. @@ -653,7 +671,9 @@ extern hal_error_t hal_ks_index_delete(hal_ks_index_t *ksi, extern hal_error_t hal_ks_index_replace(hal_ks_index_t *ksi, const hal_uuid_t * const name, - unsigned *blockno); + const unsigned chunk, + unsigned *blockno, + int *hint); /* * RPC lowest-level send and receive routines. These are blocking, and -- cgit v1.2.3