aboutsummaryrefslogtreecommitdiff
path: root/ks_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'ks_flash.c')
-rw-r--r--ks_flash.c69
1 files changed, 53 insertions, 16 deletions
diff --git a/ks_flash.c b/ks_flash.c
index b14fc6a..300c7c4 100644
--- a/ks_flash.c
+++ b/ks_flash.c
@@ -61,6 +61,7 @@ typedef enum {
BLOCK_TYPE_ERASED = 0xFF, /* Pristine erased block (candidate for reuse) */
BLOCK_TYPE_ZEROED = 0x00, /* Zeroed block (recently used) */
BLOCK_TYPE_KEY = 0x55, /* Block contains key material */
+ BLOCK_TYPE_ATTR = 0x66, /* Block contains key attributes (overflow from key block) */
BLOCK_TYPE_PIN = 0xAA, /* Block contains PINs */
BLOCK_TYPE_UNKNOWN = -1, /* Internal code for "I have no clue what this is" */
} flash_block_type_t;
@@ -89,9 +90,7 @@ typedef struct {
} flash_block_header_t;
/*
- * We probably want some kind of TLV format for optional attributes
- * in key objects, and might want to put the DER key itself there to
- * save space.
+ * Key block. Tail end of "der" field (after der_len) used for attributes.
*/
typedef struct {
@@ -101,9 +100,27 @@ typedef struct {
hal_curve_name_t curve;
hal_key_flags_t flags;
size_t der_len;
- uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
+ unsigned attributes_len;
+ uint8_t der[]; /* Must be last field -- C99 "flexible array member" */
} flash_key_block_t;
+#define SIZEOF_FLASH_KEY_BLOCK_DER \
+ (KEYSTORE_SUBSECTOR_SIZE - offsetof(flash_key_block_t, der))
+
+/*
+ * Key attribute overflow block (attributes which don't fit in der field of key block).
+ */
+
+typedef struct {
+ flash_block_header_t header;
+ hal_uuid_t name;
+ unsigned attributes_len;
+ uint8_t attributes[]; /* Must be last field -- C99 "flexible array member" */
+} flash_attributes_block_t;
+
+#define SIZEOF_FLASH_ATTRIBUTE_BLOCK_ATTRIBUTES \
+ (KEYSTORE_SUBSECTOR_SIZE - offsetof(flash_attributes_block_t, attributes))
+
/*
* PIN block. Also includes space for backing up the KEK when
* HAL_MKM_FLASH_BACKUP_KLUDGE is enabled.
@@ -127,10 +144,11 @@ typedef struct {
*/
typedef union {
- uint8_t bytes[KEYSTORE_SUBSECTOR_SIZE];
- flash_block_header_t header;
- flash_key_block_t key;
- flash_pin_block_t pin;
+ uint8_t bytes[KEYSTORE_SUBSECTOR_SIZE];
+ flash_block_header_t header;
+ flash_key_block_t key;
+ flash_attributes_block_t attr;
+ flash_pin_block_t pin;
} flash_block_t;
/*
@@ -326,6 +344,7 @@ static hal_error_t block_read(const unsigned blockno, flash_block_t *block)
return HAL_OK;
case BLOCK_TYPE_KEY:
case BLOCK_TYPE_PIN:
+ case BLOCK_TYPE_ATTR:
break;
default:
return HAL_ERROR_KEYSTORE_BAD_BLOCK_TYPE;
@@ -474,6 +493,7 @@ static hal_error_t block_write(const unsigned blockno, flash_block_t *block)
switch (block_get_type(block)) {
case BLOCK_TYPE_KEY:
case BLOCK_TYPE_PIN:
+ case BLOCK_TYPE_ATTR:
block->header.crc = calculate_block_crc(block);
break;
default:
@@ -562,10 +582,15 @@ static hal_error_t ks_init(const hal_ks_driver_t * const driver)
else
return err;
- if (block_types[i] == BLOCK_TYPE_KEY || block_types[i] == BLOCK_TYPE_PIN)
+ switch (block_types[i]) {
+ case BLOCK_TYPE_KEY:
+ case BLOCK_TYPE_PIN:
+ case BLOCK_TYPE_ATTR:
block_status[i] = block_get_status(block);
- else
+ break;
+ default:
block_status[i] = BLOCK_STATUS_UNKNOWN;
+ }
/*
* First erased block we see is head of the free list.
@@ -580,12 +605,20 @@ static hal_error_t ks_init(const hal_ks_driver_t * const driver)
* in the index, so we can look them up by name if we must.
*/
- if (block_types[i] == BLOCK_TYPE_KEY || block_types[i] == BLOCK_TYPE_PIN) {
- db.ksi.names[i].name = block_types[i] == BLOCK_TYPE_KEY ? block->key.name : pin_uuid;
+ const hal_uuid_t *uuid = NULL;
+
+ switch (block_types[i]) {
+ case BLOCK_TYPE_KEY: uuid = &block->key.name; break;
+ case BLOCK_TYPE_ATTR: uuid = &block->attr.name; break;
+ case BLOCK_TYPE_PIN: uuid = &pin_uuid; break;
+ default: /* Keep GCC happy */ break;
+ }
+
+ if (uuid != NULL) {
+ db.ksi.names[i].name = *uuid;
db.ksi.names[i].chunk = block->header.this_chunk;
db.ksi.index[n++] = i;
}
-
}
db.ksi.used = n;
@@ -873,7 +906,7 @@ static inline int acceptable_key_type(const hal_key_type_t type)
}
static hal_error_t ks_store(hal_ks_t *ks,
- const hal_pkey_slot_t * const slot,
+ hal_pkey_slot_t *slot,
const uint8_t * const der, const size_t der_len)
{
if (ks != &db.ks || slot == NULL || der == NULL || der_len == 0 || !acceptable_key_type(slot->type))
@@ -905,7 +938,7 @@ static hal_error_t ks_store(hal_ks_t *ks,
k->type = slot->type;
k->curve = slot->curve;
k->flags = slot->flags;
- k->der_len = sizeof(k->der);
+ k->der_len = SIZEOF_FLASH_KEY_BLOCK_DER;
if ((err = hal_mkm_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);
@@ -975,7 +1008,7 @@ static hal_error_t ks_fetch(hal_ks_t *ks,
}
static hal_error_t ks_delete(hal_ks_t *ks,
- const hal_pkey_slot_t * const slot)
+ hal_pkey_slot_t *slot)
{
if (ks != &db.ks || slot == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
@@ -996,6 +1029,8 @@ static hal_error_t ks_delete(hal_ks_t *ks,
}
static hal_error_t ks_list(hal_ks_t *ks,
+ const hal_client_handle_t client,
+ const hal_session_handle_t session,
hal_pkey_info_t *result,
unsigned *result_len,
const unsigned result_max)
@@ -1032,6 +1067,8 @@ static hal_error_t ks_list(hal_ks_t *ks,
}
static hal_error_t 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,