-
Notifications
You must be signed in to change notification settings - Fork 16
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
use key type and key user as part of the internal keyId #22
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few things I'd like to see (here or in next PR):
- Helper functions/macros for keyId bit manipulation/masking, as they are used lots of places in the code and easy to screw up
- Expanded testing (check all return values and invariants for one - I already pointed out the bitmasking bug with the keyIds earlier that wasn't caught by tests). Perhaps using other keyIds and different keys, ensuring they changes are propagated through
This is definitely getting close to what I was hoping. Instead of hitting each file with repeated comments, I'm going to identify a few design misses that should be pretty quick to correct and some items that need to be made more clear before we move too much farther down the road. Stuff that is close but must be corrected:
Here's some examples:
Hopefully this will better show how the whNvmId and whNvmFlags were intended to be used. Also, it should point out that there should be a distinct whKeyId type passed in and out of the key functions that don't need the client_id encoded in the top nibble because it is the server that actually handles that. FLAGS_KEY_* should include: AES, RSA_PRIVATE, RSA_PUBLIC, ECC_PRIVATE, ECC_PUBLIC, HMAC. I haven't worked through how we should tag KDF'ed keys yet, but we'll get there. Can you update your code to put the key types into the flags field and switch the user to client_id and make it a member of the server context? I can craft a quickie that provides the whClient_SetClientId() functions if you'd like. |
f9f209e
to
94f8fb0
Compare
splitting the key handle up into 3 parts internally, while presenting a one byte key id to the user, allows the same external or user facing key to be identical for each user value and between SHE and crypto keys. algorithm types were added as flags instead of being a part of the key handle and the user param was added to the client so a user can split operations between 16 clients. may not fully implement multiple client handling but seems good for keys
clients. adds safety tests to make sure 2 users can't access each others keys
94f8fb0
to
133aa3c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good! A few nits, but I'd like to merge it as is and we'll fix a few things in the next round. Only bug I see is not using the client_id correctly, but I'll fix as I go.
|
||
void wh_Client_SetKeyRsa(RsaKey* key, whNvmId keyId) | ||
{ | ||
XMEMCPY(key->devCtx, (void*)&keyId, sizeof(keyId)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will likely not set the entire devCtx value since whNvmId is probably a smaller size than void*. Recommend to use uintptr_t to let the compiler promote the unsigned integer up to the proper size.
Like: key->devCtx = (void*) ((uintptr_t)keyId);
@@ -56,6 +57,7 @@ static int hsmLoadKeyRsa(whServerContext* server, RsaKey* key, whKeyId keyId) | |||
int slotIdx = 0; | |||
uint32_t idx = 0; | |||
uint32_t size; | |||
keyId |= (WOLFHSM_KEYTYPE_CRYPTO | (server->comm->client_id << 8)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should be a macro or function as I suspect we'll need this a lot.
ret = WH_ERROR_NOSPACE; | ||
/* ultimately, return found id */ | ||
if (ret == 0) | ||
ret = (id | WOLFHSM_KEYID_CRYPTO); | ||
*outId |= buildId; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either check the parameter for NULL at the beginning and return WH_ERROR_BADARGS or gate it here.
/* check against cache keys */ | ||
for (i = 0; i < WOLFHSM_NUM_RAMKEYS; i++) { | ||
if ((id | WOLFHSM_KEYID_CRYPTO) == server->cache[i].meta->id) | ||
if (buildId == server->cache[i].meta->id) | ||
break; | ||
} | ||
/* try again if match */ | ||
if (i < WOLFHSM_NUM_RAMKEYS) | ||
continue; | ||
/* if keyId exists */ | ||
ret = wh_Nvm_List(server->nvm, WOLFHSM_NVM_ACCESS_ANY, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recommend to simply use wh_Nvm_GetMetadata() != WH_ERROR_NOTFOUND since you are only looking for an exact match.
/* test evict */ | ||
/* test cache with duplicate keyId for a different user */ | ||
WH_TEST_RETURN_ON_FAIL(wh_Client_CommClose(client)); | ||
client->comm->client_id = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't work this way. The server should be applying the client id that it stored after the client invoked wh_Client_CommInit(c); I understand this is for testing only, but I don't see how comm->client_id is being used at all in the code. Are we sure this is working the way you expected?
/* keep alive for 2 user changes */ | ||
if (am_connected != WH_COMM_CONNECTED && userChange < 2) { | ||
if (userChange == 0) | ||
server->comm->client_id = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this and simply use the wh_Client_CommInit function to update the server-side state.
splitting the key handle up into 3 parts internally, while presenting a one byte key id to the user, allows the same external or user facing key to be identical for each user value and between SHE and crypto keys. algorithm types were added as flags instead of being a part of the key handle and the user param was added to the client so a user can split operations between 16 clients. may not fully implement multiple client handling but seems good for keys