Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/wh_server_keystore.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ int wh_Server_KeystoreGetCacheSlot(whServerContext* server, whKeyId keyId,
whNvmMetadata** outMeta)
{
whKeyCacheContext* ctx;
int ret;

if (server == NULL || (keySz > WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE &&
keySz > WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE)) {
Expand All @@ -331,6 +332,11 @@ int wh_Server_KeystoreGetCacheSlot(whServerContext* server, whKeyId keyId,
/* Get the appropriate cache context for this key */
ctx = _GetCacheContext(server, keyId);

/* Evict keyId from cache to avoid duplicates */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyId here is very likely NOT the actual keyid that the user is wanting. It was recently added so that the server context could choose between global and local keycaches based on the top bits of the keyid itself. Additionally, evicting a key would be an unexpected side effect of asking the server for an empty cache slot.

Instead, the cache slot logic for "making" a key should match that for importing a key:

  1. Search appropriate cache looking for a matching keyid (should use FindInCache). If found, use that key slot. Remember to reset the committed flag since this key slot will no longer match the backing store (if it had been previously committed).
  2. Find an empty key slot using GetCacheSlot. If found, use that key slot

There's lots more issues in keystore that I can now see. We need to work all of them. More to come

ret = _EvictKeyFromCache(ctx, keyId);
if (ret != WH_ERROR_NOTFOUND && ret != WH_ERROR_OK)
return ret;

/* Use the unified cache slot function */
return _GetKeyCacheSlot(ctx, keySz, outBuf, outMeta);
}
Expand Down
52 changes: 52 additions & 0 deletions test/wh_test_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,55 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
}
return ret;
}

static int whTest_CryptoEccCacheDuplicate(whClientContext* client)
{
int ret = WH_ERROR_OK;
whKeyId keyId = WH_KEYID_ERASED;
uint8_t key1[ECC_BUFSIZE];
uint8_t key2[ECC_BUFSIZE];
uint16_t key1Len = sizeof(key1);
uint16_t key2Len = sizeof(key2);

WH_TEST_PRINT(" Testing ECC cache duplicate returns latest key...\n");

/* Generate first cached key and export it */
ret = wh_Client_EccMakeCacheKey(client, 32, ECC_SECP256R1, &keyId,
WH_NVM_FLAGS_NONE, 0, NULL);
if (ret == WH_ERROR_OK) {
ret = wh_Client_KeyExport(client, keyId, NULL, 0, key1, &key1Len);
}

/* Generate a second key using the same keyId to create a duplicate slot */
if (ret == WH_ERROR_OK) {
ret = wh_Client_EccMakeCacheKey(client, 32, ECC_SECP256R1, &keyId,
WH_NVM_FLAGS_NONE, 0, NULL);
}

/* Export again; result should match the most recent key, not the first */
if (ret == WH_ERROR_OK) {
key2Len = sizeof(key2);
ret = wh_Client_KeyExport(client, keyId, NULL, 0, key2, &key2Len);
}

if (ret == WH_ERROR_OK) {
if ((key1Len == key2Len) && (memcmp(key1, key2, key1Len) == 0)) {
WH_ERROR_PRINT(" FAIL: Export returned original ECC key after "
"duplicate insert\n");
ret = WH_ERROR_ABORTED;
}
else {
WH_TEST_PRINT(
" PASS: Export returned most recent cached ECC key\n");
}
}

if (!WH_KEYID_ISERASED(keyId)) {
wh_Client_KeyEvict(client, keyId);
}

return ret;
}
#endif /* HAVE_ECC */

#ifdef HAVE_CURVE25519
Expand Down Expand Up @@ -4303,6 +4352,9 @@ int whTest_CryptoClientConfig(whClientConfig* config)
if (ret == 0) {
ret = whTest_CryptoEcc(client, WH_DEV_ID, rng);
}
if (ret == 0) {
ret = whTest_CryptoEccCacheDuplicate(client);
}
#endif /* HAVE_ECC */

#ifdef HAVE_CURVE25519
Expand Down