aboutsummaryrefslogtreecommitdiff
path: root/aes_keywrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'aes_keywrap.c')
-rw-r--r--aes_keywrap.c104
1 files changed, 93 insertions, 11 deletions
diff --git a/aes_keywrap.c b/aes_keywrap.c
index a3e223f..63e0cf7 100644
--- a/aes_keywrap.c
+++ b/aes_keywrap.c
@@ -53,7 +53,7 @@
* Enable use of the experimental keywrap core, if present.
*/
-static int use_keywrap_core = 0;
+static int use_keywrap_core = 1;
int hal_aes_use_keywrap_core(int onoff)
{
@@ -82,17 +82,102 @@ size_t hal_aes_keywrap_ciphertext_length(const size_t plaintext_length)
typedef enum { KEK_encrypting, KEK_decrypting } kek_action_t;
+static unsigned _kek_load = 0, _kek_skip = 0;
+
+hal_error_t hal_aes_keywrap_get_stats(unsigned *load, unsigned *skip)
+{
+ if (load == NULL || skip == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ *load = _kek_load;
+ *skip = _kek_skip;
+
+ return HAL_OK;
+}
+
+void hal_aes_keywrap_reset_stats(void)
+{
+ _kek_load = _kek_skip = 0;
+}
+
+hal_error_t hal_aes_keywrap_zero(hal_core_t *core)
+{
+ const int free_core = (core == NULL);
+ hal_error_t err;
+
+ if (core == NULL &&
+ (err = hal_core_alloc(KEYWRAP_NAME, &core, NULL)) != HAL_OK)
+ return err;
+
+ uint8_t buf[4] = { 0, 0, 0, KEYWRAP_CTRL_ZERO };
+ err = hal_io_write(core, ADDR_CTRL, buf, sizeof(buf));
+
+ if (free_core)
+ hal_core_free(core);
+ return err;
+}
+
+hal_error_t hal_aes_keywrap_set_timeout(hal_core_t *core, uint32_t cycles)
+{
+ const int free_core = (core == NULL);
+ hal_error_t err;
+
+ if (core == NULL &&
+ (err = hal_core_alloc(KEYWRAP_NAME, &core, NULL)) != HAL_OK)
+ return err;
+
+ union {
+ uint32_t word;
+ uint8_t bytes[4];
+ } buf;
+ buf.word = htonl(cycles);
+ err = hal_io_write(core, KEYWRAP_ADDR_TIMEOUT, buf.bytes, sizeof(buf));
+
+ if (free_core)
+ hal_core_free(core);
+ return err;
+}
+
+static inline int is_kek_loaded(const hal_core_t *core)
+{
+ uint8_t buf[4];
+
+ if (hal_io_read(core, ADDR_STATUS, buf, sizeof(buf)) == HAL_OK)
+ return (buf[3] & KEYWRAP_STATUS_LOADED);
+
+ return 0;
+}
+
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 size_t kek_len = 0;
uint8_t config[4];
hal_error_t err;
- if (K == NULL)
- return HAL_ERROR_BAD_ARGUMENTS;
+ if (K != NULL) {
+ kek_len = K_len;
+ if ((err = hal_io_write(core, AES_ADDR_KEY0, K, K_len)) != HAL_OK)
+ return err;
+ }
+ else if (!use_keywrap_core || !is_kek_loaded(core)) {
+ ++_kek_load;
+ uint8_t kek[KEK_LENGTH];
+
+ if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK)
+ err = hal_io_write(core, AES_ADDR_KEY0, kek, kek_len);
+
+ memset(kek, 0, sizeof(kek));
+
+ if (err != HAL_OK)
+ return err;
+ }
+ else {
+ ++_kek_skip;
+ }
memset(config, 0, sizeof(config));
- switch (K_len) {
+ switch (kek_len) {
case bitsToBytes(128):
config[3] &= ~AES_CONFIG_KEYLEN;
break;
@@ -120,8 +205,7 @@ static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size
* Load the KEK and tell the core to expand it.
*/
- if ((err = hal_io_write(core, AES_ADDR_KEY0, K, K_len)) != HAL_OK ||
- (err = hal_io_write(core, AES_ADDR_CONFIG, config, sizeof(config))) != HAL_OK ||
+ if ((err = hal_io_write(core, AES_ADDR_CONFIG, config, sizeof(config))) != HAL_OK ||
(err = hal_io_init(core)) != HAL_OK)
return err;
@@ -136,10 +220,6 @@ static hal_error_t load_kek(const hal_core_t *core, const uint8_t *K, const size
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);
@@ -246,7 +326,9 @@ hal_error_t hal_aes_keywrap(hal_core_t *core,
const hal_core_info_t *info = hal_core_info(core);
if (memcmp(info->name, KEYWRAP_NAME, 8) == 0)
use_keywrap_core = 1;
- else if (memcmp(info->name, AES_CORE_NAME, 8) != 0)
+ else if (memcmp(info->name, AES_CORE_NAME, 8) == 0)
+ use_keywrap_core = 0;
+ else
/* I have no idea what this is */
return HAL_ERROR_BAD_ARGUMENTS;
}