aboutsummaryrefslogtreecommitdiff
path: root/aes_keywrap.c
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2020-04-28 12:11:49 -0400
committerPaul Selkirk <paul@psgd.org>2020-04-29 11:48:37 -0400
commit401965f1e9f74b43c88477d2ff6ac4d6c62ab5a8 (patch)
tree5e534ba8dd169a961abc5ec8643da54f5744efc5 /aes_keywrap.c
parent6f8ac4f72ef2fb003038293a62e47edf6c962b36 (diff)
The new keywrap core now talks directly to the MKM, so I split the code
that talks to that core out of aes_keywrap.c. The HSM will now be built with just the keywrap core, with no user access to aes or mkmif.
Diffstat (limited to 'aes_keywrap.c')
-rw-r--r--aes_keywrap.c193
1 files changed, 30 insertions, 163 deletions
diff --git a/aes_keywrap.c b/aes_keywrap.c
index 3a5ce2e..8680588 100644
--- a/aes_keywrap.c
+++ b/aes_keywrap.c
@@ -51,44 +51,6 @@
#include "hal_internal.h"
/*
- * Enable use of the keywrap core, if present.
- */
-
-static enum {
- unknown = -1,
- aes_core = 0,
- keywrap_core = 1
-} which_core = unknown;
-
-static char *core_name[] = {
- AES_CORE_NAME,
- KEYWRAP_NAME
-};
-
-static inline hal_error_t init_aes_keywrap(void)
-{
- if (which_core != unknown)
- return HAL_OK;
- else if (hal_core_find(KEYWRAP_NAME, NULL) != NULL)
- return (which_core = keywrap_core), HAL_OK;
- else if (hal_core_find(AES_CORE_NAME, NULL) != NULL)
- return (which_core = aes_core), HAL_OK;
- else
- return HAL_ERROR_CORE_NOT_FOUND;
-}
-
-hal_error_t hal_aes_use_keywrap_core(int onoff)
-{
- if (onoff && hal_core_find(KEYWRAP_NAME, NULL) != NULL)
- return (which_core = keywrap_core), HAL_OK;
- else if (!onoff && hal_core_find(AES_CORE_NAME, NULL) != NULL)
- return (which_core = aes_core), HAL_OK;
- else
- return HAL_ERROR_CORE_NOT_FOUND;
-}
-
-
-/*
* How long the ciphertext will be for a given plaintext length.
* This rounds up the length to a multiple of 8, and adds 8 for the IV.
*/
@@ -102,8 +64,6 @@ size_t hal_aes_keywrap_ciphertext_length(const size_t plaintext_length)
/*
* Check the KEK, then load it into the AES core.
* Note that our AES core only supports 128 and 256 bit keys.
- *
- * This should work without modification for the experimental keywrap core.
*/
typedef enum { KEK_encrypting, KEK_decrypting } kek_action_t;
@@ -156,57 +116,6 @@ static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size
/*
- * Use the experimental keywrap core to wrap/unwrap n 64-bit blocks of plaintext.
- * The wrapped/unwrapped key is returned in the same buffer.
- */
-
-static hal_error_t do_keywrap_core(const hal_core_t *core, uint8_t * const C, const size_t n)
-{
-#ifndef min
-#define min(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
- hal_error_t err;
-
- hal_assert(core != NULL && C != NULL && n > 0);
-
- /* n is the number of 64-bit (8-byte) blocks in the input.
- * KEYWRAP_LEN_R_DATA is the number of 4-byte data registers in the core.
- */
- if (n == 0 || n > KEYWRAP_LEN_R_DATA * 2)
- return HAL_ERROR_BAD_ARGUMENTS;
-
- /* write the AIV to A */
- if ((err = hal_io_write(core, KEYWRAP_ADDR_A0, C, 8)) != HAL_OK)
- return err;
-
- /* write the length to RLEN */
- uint32_t nn = htonl(n);
- if ((err = hal_io_write(core, KEYWRAP_ADDR_RLEN, (const uint8_t *)&nn, 4)) != HAL_OK)
- return err;
-
- /* write the data to R_DATA */
- if ((err = hal_io_write(core, KEYWRAP_ADDR_R_DATA, C + 8, 8 * n)) != HAL_OK)
- return err;
-
- /* start the wrap/unwrap operation, and wait for it to complete */
- if ((err = hal_io_next(core)) != HAL_OK ||
- (err = hal_io_wait_ready(core)) != HAL_OK)
- return err;
-
- /* read the A registers */
- if ((err = hal_io_read(core, KEYWRAP_ADDR_A0, C, 8)) != HAL_OK)
- return err;
-
- /* read the data from R_DATA */
- if ((err = hal_io_read(core, KEYWRAP_ADDR_R_DATA, C + 8, 8 * n)) != HAL_OK)
- return err;
-
- return HAL_OK;
-}
-
-
-/*
* Process one block. Since AES Key Wrap always deals with 64-bit
* half blocks and since the bus is going to break this up into 32-bit
* words no matter what we do, we can eliminate a few gratuitous
@@ -265,24 +174,8 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
if (Q == NULL || C == NULL || C_len == NULL || *C_len < calculated_C_len)
return HAL_ERROR_BAD_ARGUMENTS;
- /* If we're passed a core, we should figure out which one it is.
- * In practice, core is always NULL, so this is UNTESTED CODE.
- */
- if (core) {
- const hal_core_info_t *info = hal_core_info(core);
- if (memcmp(info->name, KEYWRAP_NAME, 8) == 0)
- which_core = keywrap_core;
- else if (memcmp(info->name, AES_CORE_NAME, 8) == 0)
- which_core = aes_core;
- else
- /* I have no idea what this is */
- return HAL_ERROR_BAD_ARGUMENTS;
- }
- else {
- if ((err = init_aes_keywrap()) != HAL_OK ||
- (err = hal_core_alloc(core_name[which_core], &core, NULL)) != HAL_OK)
- return err;
- }
+ if (free_core && (err = hal_core_alloc(AES_CORE_NAME, &core, NULL)) != HAL_OK)
+ return err;
if ((err = load_kek(core, K, K_len, KEK_encrypting)) != HAL_OK)
goto out;
@@ -308,26 +201,21 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
if ((err = hal_io_wait_ready(core)) != HAL_OK)
goto out;
- if (which_core == keywrap_core) {
- err = do_keywrap_core(core, C, n);
+ if (n == 1) {
+ if ((err = do_block(core, C, C + 8)) != HAL_OK)
+ goto out;
}
- else {
- if (n == 1) {
- if ((err = do_block(core, C, C + 8)) != HAL_OK)
- goto out;
- }
- else {
- for (size_t j = 0; j <= 5; j++) {
- for (size_t i = 1; i <= n; i++) {
- uint32_t t = n * j + i;
- if ((err = do_block(core, C, C + i * 8)) != HAL_OK)
- goto out;
- C[7] ^= t & 0xFF; t >>= 8;
- C[6] ^= t & 0xFF; t >>= 8;
- C[5] ^= t & 0xFF; t >>= 8;
- C[4] ^= t & 0xFF;
- }
+ else {
+ for (size_t j = 0; j <= 5; j++) {
+ for (size_t i = 1; i <= n; i++) {
+ uint32_t t = n * j + i;
+ if ((err = do_block(core, C, C + i * 8)) != HAL_OK)
+ goto out;
+ C[7] ^= t & 0xFF; t >>= 8;
+ C[6] ^= t & 0xFF; t >>= 8;
+ C[5] ^= t & 0xFF; t >>= 8;
+ C[4] ^= t & 0xFF;
}
}
}
@@ -360,24 +248,8 @@ hal_error_t hal_aes_keyunwrap(hal_core_t *core,
if (C == NULL || Q == NULL || C_len % 8 != 0 || C_len < 16 || Q_len == NULL || *Q_len < C_len)
return HAL_ERROR_BAD_ARGUMENTS;
- /* If we're passed a core, we should figure out which one it is.
- * In practice, core is always NULL, so this is UNTESTED CODE.
- */
- if (core) {
- const hal_core_info_t *info = hal_core_info(core);
- if (memcmp(info->name, KEYWRAP_NAME, 8) == 0)
- which_core = keywrap_core;
- else if (memcmp(info->name, AES_CORE_NAME, 8) == 0)
- which_core = aes_core;
- else
- /* I have no idea what this is */
- return HAL_ERROR_BAD_ARGUMENTS;
- }
- else {
- if ((err = init_aes_keywrap()) != HAL_OK ||
- (err = hal_core_alloc(core_name[which_core], &core, NULL)) != HAL_OK)
- return err;
- }
+ if (free_core && (err = hal_core_alloc(AES_CORE_NAME, &core, NULL)) != HAL_OK)
+ return err;
if ((err = load_kek(core, K, K_len, KEK_decrypting)) != HAL_OK)
goto out;
@@ -391,26 +263,21 @@ hal_error_t hal_aes_keyunwrap(hal_core_t *core,
if ((err = hal_io_wait_ready(core)) != HAL_OK)
goto out;
- if (which_core == keywrap_core) {
- err = do_keywrap_core(core, Q, n);
+ if (n == 1) {
+ if ((err = do_block(core, Q, Q + 8)) != HAL_OK)
+ goto out;
}
- else {
- if (n == 1) {
- if ((err = do_block(core, Q, Q + 8)) != HAL_OK)
- goto out;
- }
- else {
- for (long j = 5; j >= 0; j--) {
- for (size_t i = n; i >= 1; i--) {
- uint32_t t = n * j + i;
- Q[7] ^= t & 0xFF; t >>= 8;
- Q[6] ^= t & 0xFF; t >>= 8;
- Q[5] ^= t & 0xFF; t >>= 8;
- Q[4] ^= t & 0xFF;
- if ((err = do_block(core, Q, Q + i * 8)) != HAL_OK)
- goto out;
- }
+ else {
+ for (long j = 5; j >= 0; j--) {
+ for (size_t i = n; i >= 1; i--) {
+ uint32_t t = n * j + i;
+ Q[7] ^= t & 0xFF; t >>= 8;
+ Q[6] ^= t & 0xFF; t >>= 8;
+ Q[5] ^= t & 0xFF; t >>= 8;
+ Q[4] ^= t & 0xFF;
+ if ((err = do_block(core, Q, Q + i * 8)) != HAL_OK)
+ goto out;
}
}
}