diff options
author | Rob Austein <sra@hactrn.net> | 2018-05-19 22:18:56 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2018-05-19 22:24:31 -0400 |
commit | a5b4842f95ea501dacb1ed828c924f372d3f1262 (patch) | |
tree | 91fe51cfe75b908b8392d54a1074f38af976ad5f | |
parent | 0d17fd984e6ed486d6cd622edee226e263aab510 (diff) |
Release keystore lock before unwrapping key.
hal_ks_fetch() was written as lock-at-the-top, unlock-at-the-bottom to
keep it as simple as possible, but this turns out to have bad
performance implications when unwrapping the key is slow. So now we
grab the wrapped key, release the lock, then unwrap, which should be
safe enough given that hal_ks_fetch() is read-only. This lets us make
better use of multiple AES cores to unwrap in parallel when we have
multiple active clients.
-rw-r--r-- | ks.c | 18 |
1 files changed, 13 insertions, 5 deletions
@@ -623,16 +623,17 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks, if ((err = hal_ks_index_find(ks, &slot->name, &b, &slot->hint)) != HAL_OK || (err = hal_ks_block_test_owner(ks, b, slot->client, slot->session)) != HAL_OK || (err = hal_ks_block_read_cached(ks, b, &block)) != HAL_OK) - goto done; + goto unlock; if (hal_ks_block_get_type(block) != HAL_KS_BLOCK_TYPE_KEY) { err = HAL_ERROR_KEYSTORE_WRONG_BLOCK_TYPE; /* HAL_ERROR_KEY_NOT_FOUND */ - goto done; + goto unlock; } hal_ks_cache_mark_used(ks, block, b); hal_ks_key_block_t *k = &block->key; + const size_t k_der_len = k->der_len; slot->type = k->type; slot->curve = k->curve; @@ -641,6 +642,15 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks, if (der == NULL && der_len != NULL) *der_len = k->der_len; + if (der != NULL && k_der_len <= der_max) + memcpy(der, k->der, k_der_len); + + unlock: + hal_ks_unlock(); + + if (err != HAL_OK) + return err; + if (der != NULL) { uint8_t kek[KEK_LENGTH]; @@ -653,13 +663,11 @@ hal_error_t hal_ks_fetch(hal_ks_t *ks, *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, k->der, k->der_len, der, der_len); + err = hal_aes_keyunwrap(NULL, kek, kek_len, der, k_der_len, der, der_len); memset(kek, 0, sizeof(kek)); } - done: - hal_ks_unlock(); return err; } |