diff options
Diffstat (limited to 'aes_keywrap.c')
-rw-r--r-- | aes_keywrap.c | 74 |
1 files changed, 39 insertions, 35 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) { |