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

add key management commands for caching, exporting #16

Merged
merged 13 commits into from
Apr 10, 2024

Conversation

jpbland1
Copy link
Contributor

@jpbland1 jpbland1 commented Apr 2, 2024

and evicting keys for ram cache

@jpbland1 jpbland1 self-assigned this Apr 2, 2024
@jpbland1 jpbland1 requested review from billphipps and bigbrett April 2, 2024 23:51
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.

Great work! No big issues that I see but a largenumber of little things that should be fixed before merging.

wolfhsm/wh_server_keystore.h Outdated Show resolved Hide resolved
src/wh_server_keystore.c Outdated Show resolved Hide resolved
src/wh_client.c Outdated Show resolved Hide resolved
src/wh_client.c Outdated Show resolved Hide resolved
src/wh_client.c Outdated Show resolved Hide resolved
src/wh_server_keystore.c Show resolved Hide resolved
src/wh_server_keystore.c Outdated Show resolved Hide resolved
src/wh_server_keystore.c Show resolved Hide resolved
src/wh_server_keystore.c Outdated Show resolved Hide resolved
src/wh_server_keystore.c Outdated Show resolved Hide resolved
@bigbrett
Copy link
Contributor

bigbrett commented Apr 4, 2024

@jpbland1 this needs a rebase and some additional changes now that crypto and NVM contexts are no longer stored in the server context (see #11)

@jpbland1 jpbland1 force-pushed the key-cache-export-evict branch from d00d0c6 to 5482af4 Compare April 5, 2024 20:26
@jpbland1 jpbland1 requested a review from bigbrett April 5, 2024 20:27
bigbrett
bigbrett previously approved these changes Apr 8, 2024
billphipps
billphipps previously approved these changes Apr 8, 2024
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.

A number of recommendations to add to the backlog, but let's get this going. Only 1 real bug related to the uniqueId loop end math.

src/wh_client.c Show resolved Hide resolved
src/wh_client.c Outdated
whPacket* packet = (whPacket*)rawPacket;
uint8_t* packOut = (uint8_t*)(&packet->keyExportRes + 1);
if (c == NULL || labelSz > WOLFHSM_NVM_LABEL_LEN || outSz == NULL)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure why any labelSz could cause an error. If the user provides a smaller label storage (even 0), then I think that should be valid. Simply labelSz = min(sizeof(metadata.label), labelSz);

outSz == NULL is valid as long as out == NULL. Probably just a test case, but still consistent.
Should outSz be set to the size of out before the function is called?

Copy link
Contributor Author

@jpbland1 jpbland1 Apr 8, 2024

Choose a reason for hiding this comment

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

labelSz == 1000000000000 would cause out of bounds read, we can't accept any labelSz and outSz can't be NULL because when out is NULL it means the user is expecting outSz to be populated so they know how big their buffer needs to be for a subsequent call

Copy link
Contributor Author

@jpbland1 jpbland1 Apr 9, 2024

Choose a reason for hiding this comment

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

I've thought more about this, we definitely need to validate labelSz because an incorrect value of 25 doesn't guarantee the buffer can actually handle sizeof(metadata.label) which i think is 24. if we have an unknown length we should bail out, going to modify it to only err if label is non-NULL

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Scratch that, actually makes total sense for the buffer to be larger than max if they're reusing some generic buffer, my bad

src/wh_client.c Show resolved Hide resolved
uint16_t size;
int ret;
whPacket packet[1] = {0};
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a fan of unions, but some of these messages are really small. Consider using the smaller structs when possible to avoid a big allocations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it really saved a lot of space in the old design to only have 1 packet for everything huh?

uint16_t keyId)
{
uint8_t rawPacket[WH_COMM_MTU] = {0};
Copy link
Contributor

Choose a reason for hiding this comment

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

The CommClient context already has an MTU-sized packet precisely for construction. The SendRequest helper was put together to simplify calls, but you are welcome to directly use this buffer (at the data offset) and update the SendRequest to not perform the memcpy when the src of the data is the same as the destination. We'll add this to the todo list so we can provide an accessor and avoid extra copies and allocations.

Oh, and this size should be WH_COMM_DATA_LEN, not MTU.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So change it back to using a single packet instead of taking data as a parameter? The way I had it in the old design?

src/wh_server_keystore.c Outdated Show resolved Hide resolved
}
/* if the key wasn't found return an error */
if (i >= WOLFHSM_NUM_RAMKEYS)
ret = WH_ERROR_BADARGS;
Copy link
Contributor

Choose a reason for hiding this comment

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

WH_ERROR_NOTFOUND

Comment on lines +170 to +178
/* find key in cache */
for (i = 0; i < WOLFHSM_NUM_RAMKEYS; i++) {
if (server->cache[i].meta->id == keyId) {
cacheSlot = &server->cache[i];
break;
}
}
if (i >= WOLFHSM_NUM_RAMKEYS)
return WH_ERROR_NOTFOUND;
Copy link
Contributor

Choose a reason for hiding this comment

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

Refactor into _FindCacheIndexByKeyId() or something suitably named.

int hsmEraseKey(whServerContext* server, whNvmId keyId)
{
int i;
if (keyId == WOLFHSM_ID_ERASED)
Copy link
Contributor

Choose a reason for hiding this comment

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

Always check for non-null server. Multiple instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

whPacket* packet = (whPacket*)data;
whNvmMetadata meta[1] = {0};
switch (action)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

The endianness of the server may not be the same as the client. Even if you don't handle it now, at least perform a quick check using the magic number to return an error on mismatch.

if (WH_COMM_FLAGS_SWAPTEST(magic)) return ABORTED or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

Copy link
Contributor Author

Choose a reason for hiding this comment

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

adding this made it error out every time, don't know why but I've commented it out

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's because I made that macro to compare the magics. Should have been !SWAPTEST. My bad.

@jpbland1 jpbland1 dismissed stale reviews from billphipps and bigbrett via c3261d3 April 8, 2024 23:41
@jpbland1 jpbland1 requested review from bigbrett and billphipps April 8, 2024 23:41
billphipps
billphipps previously approved these changes Apr 9, 2024
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.

Updated backlog. Still have some API changes I think are necessary but lets get this in and work down the backlog.

src/wh_client.c Show resolved Hide resolved
src/wh_client.c Show resolved Hide resolved
src/wh_client.c Show resolved Hide resolved
src/wh_server_keystore.c Show resolved Hide resolved
return 0;
}

int hsmReadKey(whServerContext* server, whNvmMetadata* meta, uint8_t* out,
Copy link
Contributor

Choose a reason for hiding this comment

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

This API conflates the NvmId and KeyId, which should be distinct. Recommend to change this API to:
int hsmReadKey(whServerContext* server, whKeyId key_id, whNvmMetadata *out_meta, whNvmSize inout_DataSize, uint8_t data);

out_meta == NULL means don't copy the metadata. inout_DataSize should be set to the length of data and will be set to the actual length if non-null. data == NULL means don't copy the data.

I updated the key_id backlog item to capture the need for distinct key_id functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm confused, are KeyIds not a subset of NvmId? It's just an NvmId but with the context of being a key and with either WOLFHSM_KEYID_CRYPTO, WOLFHSM_KEYID_SHE or WOLFHSM_KEYID_SHE_RAM bits set? Or is there something I'm missing

whPacket* packet = (whPacket*)data;
whNvmMetadata meta[1] = {0};
switch (action)
{
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that's because I made that macro to compare the magics. Should have been !SWAPTEST. My bad.

bigbrett
bigbrett previously approved these changes Apr 9, 2024
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.

@jpbland1 looks like ASAN is failing due to overlapping memcpy in the crypto tests. Good to merge as soon as that is fixed

@jpbland1
Copy link
Contributor Author

jpbland1 commented Apr 9, 2024

working now, please merge

Comment on lines +442 to +444
if (labelSz > sizeof(packet->keyExportRes.label)) {
XMEMCPY(label, packet->keyExportRes.label,
WOLFHSM_NVM_LABEL_LEN);
Copy link
Contributor

Choose a reason for hiding this comment

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

we should probably have the memcpy size argument correspond to the size check we just did

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that's a little messy, still correct but it would be better to use sizeof the actual buffer

@bigbrett bigbrett merged commit 2d2db1a into wolfSSL:main Apr 10, 2024
1 check passed
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