diff options
-rw-r--r-- | keywrap.c | 44 |
1 files changed, 33 insertions, 11 deletions
@@ -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) { |