aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aes_keywrap.c74
-rw-r--r--verilog_constants.h2
2 files changed, 40 insertions, 36 deletions
diff --git a/aes_keywrap.c b/aes_keywrap.c
index a3e223f..2775b3e 100644
--- a/aes_keywrap.c
+++ b/aes_keywrap.c
@@ -77,12 +77,13 @@ 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.
+ * This should work without modification for the experimental keywrap core,
+ * because ADDR_KEY0 and ADDR_CONFIG are at the same offsets.
*/
-typedef enum { KEK_encrypting, KEK_decrypting } kek_action_t;
+typedef enum { key_encrypting, key_decrypting } key_action_t;
-static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size_t K_len, const kek_action_t action)
+static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size_t K_len, const key_action_t action)
{
uint8_t config[4];
hal_error_t err;
@@ -106,10 +107,10 @@ static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size
}
switch (action) {
- case KEK_encrypting:
+ case key_encrypting:
config[3] |= AES_CONFIG_ENCDEC;
break;
- case KEK_decrypting:
+ case key_decrypting:
config[3] &= ~AES_CONFIG_ENCDEC;
break;
default:
@@ -130,11 +131,11 @@ 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.
+ * Use the experimental keywrap core to wrap/unwrap len bytes 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)
+static hal_error_t do_keywrap_core(const hal_core_t *core, uint8_t * const C, const size_t len, const key_action_t action)
{
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
@@ -142,25 +143,26 @@ static hal_error_t do_keywrap_core(const hal_core_t *core, uint8_t * const C, co
hal_error_t err;
- hal_assert(core != NULL && C != NULL && n > 0);
+ hal_assert(core != NULL && C != NULL && len > 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)
+ const size_t calculated_C_len = hal_aes_keywrap_ciphertext_length(len);
+ /* KEYWRAP_LEN_R_DATA is the number of 4-byte data registers in the core. */
+ if (calculated_C_len - 8 > KEYWRAP_LEN_R_DATA * 4)
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;
+ if (action == key_decrypting) {
+ /* write the first 8 bytes 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)
+ /* write the unpadded length to LENGTH */
+ uint32_t nel = htonl(len);
+ if ((err = hal_io_write(core, KEYWRAP_ADDR_LENGTH, (const uint8_t *)&nel, 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)
+ if ((err = hal_io_write(core, KEYWRAP_ADDR_R_DATA, C + 8, calculated_C_len - 8)) != HAL_OK)
return err;
/* start the wrap/unwrap operation, and wait for it to complete */
@@ -172,8 +174,8 @@ static hal_error_t do_keywrap_core(const hal_core_t *core, uint8_t * const C, co
if ((err = hal_io_read(core, KEYWRAP_ADDR_A0, C, 8)) != HAL_OK)
return err;
- /* read the data to R_DATA */
- if ((err = hal_io_read(core, KEYWRAP_ADDR_R_DATA, C + 8, 8 * n)) != HAL_OK)
+ /* read the data from R_DATA */
+ if ((err = hal_io_read(core, KEYWRAP_ADDR_R_DATA, C + 8, calculated_C_len - 8)) != HAL_OK)
return err;
return HAL_OK;
@@ -256,7 +258,7 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
return err;
}
- if ((err = load_kek(core, K, K_len, KEK_encrypting)) != HAL_OK)
+ if ((err = load_kek(core, K, K_len, key_encrypting)) != HAL_OK)
goto out;
*C_len = calculated_C_len;
@@ -265,21 +267,22 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
memmove(C + 8, Q, m);
if (m % 8 != 0)
memset(C + 8 + m, 0, 8 - (m % 8));
- C[0] = 0xA6;
- C[1] = 0x59;
- C[2] = 0x59;
- C[3] = 0xA6;
- C[4] = (m >> 24) & 0xFF;
- C[5] = (m >> 16) & 0xFF;
- C[6] = (m >> 8) & 0xFF;
- C[7] = (m >> 0) & 0xFF;
-
- n = calculated_C_len/8 - 1;
if (use_keywrap_core) {
- err = do_keywrap_core(core, C, n);
+ if ((err = do_keywrap_core(core, C, m, key_encrypting)) != HAL_OK)
+ goto out;
}
else {
+ C[0] = 0xA6;
+ C[1] = 0x59;
+ C[2] = 0x59;
+ C[3] = 0xA6;
+ C[4] = (m >> 24) & 0xFF;
+ C[5] = (m >> 16) & 0xFF;
+ C[6] = (m >> 8) & 0xFF;
+ C[7] = (m >> 0) & 0xFF;
+
+ n = calculated_C_len/8 - 1;
if (n == 1) {
if ((err = do_block(core, C, C + 8)) != HAL_OK)
goto out;
@@ -345,7 +348,7 @@ hal_error_t hal_aes_keyunwrap(hal_core_t *core,
return err;
}
- if ((err = load_kek(core, K, K_len, KEK_decrypting)) != HAL_OK)
+ if ((err = load_kek(core, K, K_len, key_decrypting)) != HAL_OK)
goto out;
n = (C_len / 8) - 1;
@@ -354,7 +357,8 @@ hal_error_t hal_aes_keyunwrap(hal_core_t *core,
memmove(Q, C, C_len);
if (use_keywrap_core) {
- err = do_keywrap_core(core, Q, n);
+ if ((err = do_keywrap_core(core, Q, C_len - 8, key_decrypting)) != HAL_OK)
+ goto out;
}
else {
if (n == 1) {
diff --git a/verilog_constants.h b/verilog_constants.h
index 8735b12..d190589 100644
--- a/verilog_constants.h
+++ b/verilog_constants.h
@@ -307,7 +307,7 @@
#define KEYWRAP_CONFIG_ENCDEC (1)
#define KEYWRAP_CONFIG_KEYLEN (2)
-#define KEYWRAP_ADDR_RLEN (0x0c)
+#define KEYWRAP_ADDR_LENGTH (0x0c)
#define KEYWRAP_ADDR_A0 (0x0e)
#define KEYWRAP_ADDR_A1 (0x0f)