aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keywrap.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/keywrap.c b/keywrap.c
index ccf7ea8..dc1c6ba 100644
--- a/keywrap.c
+++ b/keywrap.c
@@ -52,6 +52,7 @@ typedef union {
uint32_t w;
} byteword_t;
+
/*
* Match uninitialized flash for the "not set" value.
* Leave some bits at 1 for the "set" value to allow
@@ -61,7 +62,7 @@ typedef union {
#define MKM_STATUS_SET 0x0000ffff
#define MKM_STATUS_ERASED 0x00000000
-static hal_error_t mkm_status = HAL_ERROR_IMPOSSIBLE;
+static uint32_t mkm_status = MKM_STATUS_NOT_SET;
static inline hal_error_t hal_io_cmd_read(const hal_core_t *core)
@@ -78,13 +79,13 @@ static inline hal_error_t hal_io_cmd_write(const hal_core_t *core)
/*
- * Check the MKM status
+ * Check the MKM status word.
*/
hal_error_t hal_keywrap_mkm_status(hal_core_t *core)
{
const int free_core = core == NULL;
- uint8_t config[4] = { 0, 0, 0, 0 };
+ uint8_t config[4] = { 0 };
byteword_t status;
hal_error_t err;
@@ -102,17 +103,22 @@ hal_error_t hal_keywrap_mkm_status(hal_core_t *core)
if (err != HAL_OK)
return err;
- switch (htonl(status.w)) {
- case MKM_STATUS_SET: return mkm_status = HAL_OK;
- case MKM_STATUS_NOT_SET: return mkm_status = HAL_ERROR_MASTERKEY_NOT_SET;
- default: return mkm_status = HAL_ERROR_MASTERKEY_FAIL;
+ switch (mkm_status = ntohl(status.w)) {
+ case MKM_STATUS_SET: return HAL_OK;
+ case MKM_STATUS_NOT_SET: return HAL_ERROR_MASTERKEY_NOT_SET;
+ default: return HAL_ERROR_MASTERKEY_FAIL;
}
}
+
+/*
+ * Write a new KEK to the MKM.
+ */
+
hal_error_t hal_keywrap_mkm_write(hal_core_t *core, const uint8_t *K, const size_t K_len)
{
const int free_core = core == NULL;
- uint8_t config[4] = { 0, 0, 0, 0 };
+ uint8_t config[4] = { 0 };
byteword_t status;
hal_error_t err;
@@ -149,6 +155,8 @@ hal_error_t hal_keywrap_mkm_write(hal_core_t *core, const uint8_t *K, const size
(err = hal_io_wait_ready(core)) != HAL_OK)
goto out;
+ mkm_status = ntohl(status.w);
+
out:
if (free_core)
hal_core_free(core);
@@ -156,10 +164,18 @@ out:
return err;
}
+
+/*
+ * Erase the KEK from the MKM.
+ */
+
hal_error_t hal_keywrap_mkm_erase(hal_core_t *core, const size_t K_len)
{
uint8_t buf[KEK_LENGTH] = { 0 };
+ if (K_len != KEK_LENGTH)
+ return HAL_ERROR_MASTERKEY_BAD_LENGTH;
+
return hal_keywrap_mkm_write(core, buf, sizeof(buf));
}
@@ -208,9 +224,15 @@ static hal_error_t load_kek(hal_core_t *core, const uint8_t *K, const size_t K_l
else {
/* read the MKM KEK into the keywrap core */
- if (mkm_status != HAL_OK &&
- (err = hal_keywrap_mkm_status(core)) != HAL_OK)
+ if (mkm_status != MKM_STATUS_SET &&
+ (err = hal_keywrap_mkm_status(core)) != HAL_OK) {
+#if HAL_MKM_FLASH_BACKUP_KLUDGE
+ uint8_t kek[KEK_LENGTH];
+ if ((err = hal_mkm_flash_read_no_lock(kek, sizeof(kek))) == HAL_OK)
+ return load_kek(core, kek, sizeof(kek), action);
+#endif
return err;
+ }
config[3] &= ~KEYWRAP_CONFIG_MKS;
if ((err = hal_io_write(core, KEYWRAP_ADDR_CONFIG, config, sizeof(config))) != HAL_OK ||
@@ -219,7 +241,7 @@ static hal_error_t load_kek(hal_core_t *core, const uint8_t *K, const size_t K_l
return err;
config[3] &= ~KEYWRAP_CONFIG_MKK;
- config[3] |= KEYWRAP_CONFIG_KEYLEN; /* XXX hardwire to 256-bits for now */
+ config[3] |= KEYWRAP_CONFIG_KEYLEN; /* MKM KEK is required to be 256 bits */
}
switch (action) {