aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2019-02-05 13:11:19 -0500
committerPaul Selkirk <paul@psgd.org>2019-04-09 18:08:45 -0400
commit1376b16e3bead769e56e531b1c121ea68b60f49f (patch)
treed82db424fb43708baae51210f9ec7afb47d991a3
parent411b5a9ee7d28d2bce9b297a865132e39712d93b (diff)
Track Joachim's latest keywrap core - KEK remains in the AES core until it times out or is explicitly zeroed out.
-rw-r--r--aes_keywrap.c104
-rw-r--r--hal.h9
-rw-r--r--ks.c19
-rw-r--r--verilog_constants.h4
4 files changed, 109 insertions, 27 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;
}
diff --git a/hal.h b/hal.h
index 6331e3d..026ad6e 100644
--- a/hal.h
+++ b/hal.h
@@ -378,8 +378,17 @@ extern const hal_hash_descriptor_t *hal_hmac_get_descriptor(const hal_hmac_state
* AES key wrap functions.
*/
+
extern int hal_aes_use_keywrap_core(int onoff);
+extern hal_error_t hal_aes_keywrap_get_stats(unsigned *load, unsigned *skip);
+
+extern void hal_aes_keywrap_reset_stats(void);
+
+extern hal_error_t hal_aes_keywrap_zero(hal_core_t *core);
+
+extern hal_error_t hal_aes_keywrap_set_timeout(hal_core_t *core, uint32_t cycles);
+
extern hal_error_t hal_aes_keywrap(hal_core_t *core,
const uint8_t *kek, const size_t kek_length,
const uint8_t *plaintext, const size_t plaintext_length,
diff --git a/ks.c b/ks.c
index a682cd2..51ea303 100644
--- a/ks.c
+++ b/ks.c
@@ -536,9 +536,6 @@ static hal_error_t construct_key_block(hal_ks_block_t *block,
return HAL_ERROR_IMPOSSIBLE;
hal_ks_key_block_t *k = &block->key;
- hal_error_t err = HAL_OK;
- uint8_t kek[KEK_LENGTH];
- size_t kek_len;
memset(block, 0xFF, sizeof(*block));
@@ -552,12 +549,7 @@ static hal_error_t construct_key_block(hal_ks_block_t *block,
k->der_len = SIZEOF_KS_KEY_BLOCK_DER;
k->attributes_len = 0;
- if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK)
- err = hal_aes_keywrap(NULL, kek, kek_len, der, der_len, k->der, &k->der_len);
-
- memset(kek, 0, sizeof(kek));
-
- return err;
+ return hal_aes_keywrap(NULL, NULL, 0, der, der_len, k->der, &k->der_len);
}
/*
@@ -658,19 +650,14 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks,
if (der != NULL) {
- uint8_t kek[KEK_LENGTH];
- size_t kek_len, der_len_;
- hal_error_t err;
+ size_t der_len_;
if (der_len == NULL)
der_len = &der_len_;
*der_len = der_max;
- if ((err = hal_mkm_get_kek(kek, &kek_len, sizeof(kek))) == HAL_OK)
- err = hal_aes_keyunwrap(NULL, kek, kek_len, der, k_der_len, der, der_len);
-
- memset(kek, 0, sizeof(kek));
+ err = hal_aes_keyunwrap(NULL, NULL, 0, der, k_der_len, der, der_len);
}
return err;
diff --git a/verilog_constants.h b/verilog_constants.h
index 8735b12..f058737 100644
--- a/verilog_constants.h
+++ b/verilog_constants.h
@@ -303,10 +303,14 @@
* AES Keywrap core
*/
+#define KEYWRAP_CTRL_ZERO (4)
+#define KEYWRAP_STATUS_LOADED (4)
+
#define KEYWRAP_ADDR_CONFIG (0x0a)
#define KEYWRAP_CONFIG_ENCDEC (1)
#define KEYWRAP_CONFIG_KEYLEN (2)
+#define KEYWRAP_ADDR_TIMEOUT (0x0b)
#define KEYWRAP_ADDR_RLEN (0x0c)
#define KEYWRAP_ADDR_A0 (0x0e)
#define KEYWRAP_ADDR_A1 (0x0f)