Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor the HSM server and keystore to handle a #48

Merged
merged 3 commits into from
Aug 9, 2024

Conversation

jpbland1
Copy link
Contributor

seperate cache for larger keys so customers with limited memory can still store a limited number of large keys alongside their smaller keys.

@jpbland1
Copy link
Contributor Author

Addressing the issue @bigbrett brought up where we need to support both large RSA keys while still allowing a large number of smaller keys, by making a separate cache for large keys like RSA and the cmac struct customers with limited memory can still use a large number of smaller keys. Considered changing the cache to a heap but we want the cache to be completely deterministic as to the number of keys you can store, rather than having the customer calculate the cachesize they need they should just be able to pick the number of big and small keys they plan to use.

Copy link
Contributor

@bigbrett bigbrett left a comment

Choose a reason for hiding this comment

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

Nice. A few things and request for clarification but looks solid.

if (i >= WOLFHSM_NUM_RAMKEYS) {
for (i = 0; i < WOLFHSM_NUM_BIG_RAMKEYS; i++) {
if (server->bigCache[i].meta->id == keyId) {
slotCommited = &server->cache[i].commited;
Copy link
Contributor

Choose a reason for hiding this comment

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

copy pasta error:? shouldn't this be:

Suggested change
slotCommited = &server->cache[i].commited;
slotCommited = &server->bigCache[i].commited;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch

Comment on lines 44 to 46
uint16_t keySz = WOLFHSM_KEYCACHE_BIG_BUFSIZE;
#else
uint16_t keySz = WOLFHSM_KEYCACHE_BUFSIZE;
Copy link
Contributor

Choose a reason for hiding this comment

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

pedantic: make this const if not meant to be changed

word32 privSz = CURVE25519_KEYSIZE;
word32 pubSz = CURVE25519_KEYSIZE;
whKeyId keyId = WOLFHSM_KEYTYPE_CRYPTO;
/* get a free slot */
ret = slotIdx = hsmCacheFindSlot(server);
if (ret >= 0) {
ret = hsmCacheFindSlotAndZero(server, CURVE25519_KEYSIZE * 2, &cacheBuf,
Copy link
Contributor

Choose a reason for hiding this comment

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

can we make the val * 2 a local const variable with a self-describing name just to make it extremely obvious what is going on?

Comment on lines 312 to 315
/* get the lengths since they vary by ecc size, expect BUFFER_E since
* LENGTH_ONLY_E isn't supported. Note that this is a dangerous operation
* but by having size of 0 or buffer of NULL we avoid NULL checks when
* getting the length */
Copy link
Contributor

Choose a reason for hiding this comment

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

looks like those args are NULL checked in that wolfCrypt function, so shouldn't necessarily be dangerous - can you elaborate on what you mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's dangerous because I have to pass in a non-NULL nonsense pointer for the length I'm trying to get, the operation will fail as long as at least one of the lengths, qx or qy, is NULL so it should be good but it warrants a comment, might be wise a refactor ecc to allow a LENGTH_ONLY_E return

Comment on lines 363 to 366
if (ret == 0) {
keySz = cacheMeta->len / 3;
ret = wc_ecc_import_unsigned(key, cacheBuf, cacheBuf + keySz,
cacheBuf + keySz * 2, curveId);
Copy link
Contributor

Choose a reason for hiding this comment

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

while we're here, can we constify the magic numbers with self describing names just to make it explicitly clear what is going on at a glance

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this one can't be const because it depends on the length of the particular ecc key pulled from the metadata, will make a descriptive variable for it though

Comment on lines 750 to 755
#ifdef WOLFHSM_SEPARATE_BIG_CACHE
/* evict the aes sized key in the normal cache */
if (moveToBigCache == 1) {
ret = hsmEvictKey(server, keyId);
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Not super clear why we are doing this? Could you explain plz

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if a user pre-caches an aes key to use with cmac it will be in the regular cache initially, when we cache the cmac struct it will need to go into big cache so the now defunct aes key will be hanging if we don't evict it

@jpbland1 jpbland1 requested a review from bigbrett June 28, 2024 03:06
@billphipps
Copy link
Contributor

Love this idea. Any chance we can make this option always enabled and simply use a 0 num of big keys if they are not needed? This would give the same result without a bunch of conditional defines.

Also, I'd like to have the server context use pointers to the cache areas with a config member that indicates the number of slots. this will keep the server context size more consistent and cause the user to allocate the space themselves, as it may make sense to have this cache area somewhere other than in the middle of the context struct. just a thought.

@bigbrett
Copy link
Contributor

bigbrett commented Jul 2, 2024

Any chance we can make this option always enabled and simply use a 0 num of big keys if they are not needed? This would give the same result without a bunch of conditional defines.

Big +1 for this plan. The less code that is macro-ed out, the better! @jpbland1 Could you take a stab?

Also, I'd like to have the server context use pointers to the cache areas with a config member that indicates the number of slots. this will keep the server context size more consistent and cause the user to allocate the space themselves, as it may make sense to have this cache area somewhere other than in the middle of the context struct. just a thought.

Probably food for a follow-up PR IMO

@bigbrett
Copy link
Contributor

@jpbland1 noticed this went stale, could you possibly address Bill's point so we can get it merged:

Any chance we can make this option always enabled and simply use a 0 num of big keys if they are not needed? This would give the same result without a bunch of conditional defines.

@billphipps
Copy link
Contributor

And PR#49 changes the names of config values and provides an info message response as well. Need to add 2 more entries in the info message and API's to support large keys. WOLFHSM_CFG_KEYCACHE_LARGE_COUNT/BUFSIZE?

Copy link
Contributor

@bigbrett bigbrett left a comment

Choose a reason for hiding this comment

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

need to address merge conflicts, as well as Bill's points below:

Any chance we can make this option always enabled and simply use a 0 num of big keys if they are not needed? This would give the same result without a bunch of conditional defines.

and

And PR#49 changes the names of config values and provides an info message response as well. Need to add 2 more entries in the info message and API's to support large keys. WOLFHSM_CFG_KEYCACHE_LARGE_COUNT/BUFSIZE?

@jpbland1 jpbland1 requested a review from bigbrett August 1, 2024 10:52
Copy link
Contributor

@bigbrett bigbrett left a comment

Choose a reason for hiding this comment

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

Might have noticed an issue with the coupling between CMAC and enablement of the big cache, lmk ur thoughts

@@ -94,9 +94,19 @@
#define WOLFHSM_CFG_SERVER_KEYCACHE_COUNT 8
#endif

/* Number of big RAM keys */
#ifndef WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT
#define WOLFHSM_CFG_SERVER_KEYCACHE_BIG_COUNT 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we default to 0 for size here? So it is just an opt-in feature for the user? @billphipps what do you think?

src/wh_server_keystore.c Show resolved Hide resolved
src/wh_server_keystore.c Show resolved Hide resolved
src/wh_server_crypto.c Show resolved Hide resolved
seperate cache for larger keys so customers with limited memory can still store
a limited number of large keys alongside their smaller keys.
@jpbland1 jpbland1 requested a review from bigbrett August 5, 2024 23:09
Copy link
Contributor

@billphipps billphipps left a comment

Choose a reason for hiding this comment

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

Got some reservations about this scheme in general, but I'm going to merge this because it does help with handling large keys. Thanks for putting this together!

Comment on lines +168 to +169
(meta->len > WOLFHSM_CFG_SERVER_KEYCACHE_BUFSIZE
&& meta->len > WOLFHSM_CFG_SERVER_KEYCACHE_BIG_BUFSIZE
Copy link
Contributor

Choose a reason for hiding this comment

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

If BIG_BUFSIZE > BUF_SIZE, then this test could be simplified. Also, the different sizes should only be tested if the number of entries for that size >0.

Recommend eliminate the size test here (which incorrectly returns BADARGS for a len that is too large) and simply test if there is a slot somewhere that has sufficient size. If not, then return NOSPACE. The client won't necessarily know the buf sizes.

@billphipps billphipps merged commit 79f49b5 into wolfSSL:main Aug 9, 2024
1 check passed
jefferyq2 pushed a commit to jefferyq2/wolfHSM that referenced this pull request Nov 10, 2024
refactor the HSM server and keystore to handle a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants