Skip to content

Commit dabcc52

Browse files
committed
Wrapped key overhaul using flags to ensure server can uniquely ID them
1 parent 74fe9aa commit dabcc52

File tree

11 files changed

+148
-312
lines changed

11 files changed

+148
-312
lines changed

examples/demo/client/wh_demo_client_keywrap.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,11 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)
7777
WC_RNG rng[1];
7878
uint8_t key[WH_DEMO_KEYWRAP_AES_KEYSIZE];
7979
uint8_t exportedKey[WH_DEMO_KEYWRAP_AES_KEYSIZE];
80-
whNvmMetadata metadata = {.id = WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID,
81-
.label = "AES Key Label",
82-
.access = WH_NVM_ACCESS_ANY,
83-
.len = WH_DEMO_KEYWRAP_AES_KEYSIZE};
80+
whNvmMetadata metadata = {
81+
.id = WH_MAKE_KEYID_WRAPPED(WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID),
82+
.label = "AES Key Label",
83+
.access = WH_NVM_ACCESS_ANY,
84+
.len = WH_DEMO_KEYWRAP_AES_KEYSIZE};
8485
whNvmMetadata exportedMetadata;
8586
uint8_t wrappedKey[WH_DEMO_KEYWRAP_AES_WRAPPED_KEYSIZE];
8687
whKeyId wrappedKeyId;

examples/posix/wh_posix_server/wh_posix_server.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030
#include "wh_posix_cfg.h"
3131
#include "wh_posix_server_cfg.h"
32-
/* For demo wrapped key ID registration */
33-
#include "../../demo/client/wh_demo_client_keywrap.h"
3432

3533
/** Local declarations */
3634
static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId,
@@ -126,20 +124,6 @@ static int _InitDemoServer(whServerContext* server, whServerConfig* config)
126124

127125
ret = wh_Server_Init(server, config);
128126

129-
#ifdef WOLFHSM_CFG_KEYWRAP
130-
if (ret == WH_ERROR_OK) {
131-
/* Register wrapped keys from demo client (wh_demo_client_keywrap.h) */
132-
const whKeyId wrappedIds[] = {WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID};
133-
ret = wh_Server_KeystoreRegisterWrappedKeys(
134-
server, wrappedIds,
135-
(uint16_t)(sizeof(wrappedIds) / sizeof(wrappedIds[0])));
136-
if (ret != WH_ERROR_OK) {
137-
printf("Failed to register wrapped key IDs: %d\n", ret);
138-
(void)wh_Server_Cleanup(server);
139-
}
140-
}
141-
#endif
142-
143127
return ret;
144128
}
145129

src/wh_client_keywrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx,
298298
return resp->rc;
299299
}
300300

301-
*keyIdOut = resp->keyId;
301+
*keyIdOut = WH_MAKE_KEYID_WRAPPED(resp->keyId);
302302

303303
return WH_ERROR_OK;
304304
}

src/wh_server_keystore.c

Lines changed: 41 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -82,98 +82,6 @@ static whKeyCacheContext* _GetCacheContext(whServerContext* server,
8282
return &server->localCache;
8383
}
8484

85-
#ifdef WOLFHSM_CFG_KEYWRAP
86-
/*
87-
* @brief Retrieve the wrapped-key registry associated with keyId
88-
*/
89-
static whWrappedKeyRegistry* _GetWrappedRegistry(whServerContext* server,
90-
whKeyId keyId)
91-
{
92-
whKeyCacheContext* ctx = _GetCacheContext(server, keyId);
93-
return (ctx != NULL) ? &ctx->wrappedKeys : NULL;
94-
}
95-
96-
/**
97-
* @brief Check if keyId is present in a wrapped-key registry
98-
*
99-
* Note: Registry stores client-relative IDs (0-255), so keyId parameter
100-
* should be the extracted client-relative ID, not a full server-encoded keyId.
101-
*/
102-
static int _WrappedRegistryContains(const whWrappedKeyRegistry* registry,
103-
whKeyId keyId)
104-
{
105-
uint16_t i;
106-
107-
if (registry == NULL) {
108-
return 0;
109-
}
110-
111-
for (i = 0; i < registry->count; i++) {
112-
if (registry->ids[i] == keyId) {
113-
return 1;
114-
}
115-
}
116-
return 0;
117-
}
118-
119-
/**
120-
* @brief Add keyId to a wrapped-key registry if not already present
121-
*
122-
* Extracts and stores only the client-relative ID portion (0-255) from keyId.
123-
* This allows registration before knowing which client will connect.
124-
*/
125-
static int _WrappedRegistryAdd(whWrappedKeyRegistry* registry, whKeyId keyId)
126-
{
127-
uint8_t clientRelativeId;
128-
129-
if (registry == NULL) {
130-
return WH_ERROR_BADARGS;
131-
}
132-
133-
/* Extract client-relative ID portion (0-255) from keyId */
134-
clientRelativeId = WH_KEYID_ID(keyId);
135-
136-
if (clientRelativeId == WH_KEYID_ERASED) {
137-
return WH_ERROR_BADARGS;
138-
}
139-
140-
/* Check if already registered (using client-relative ID) */
141-
if (_WrappedRegistryContains(registry, (whKeyId)clientRelativeId)) {
142-
return WH_ERROR_OK;
143-
}
144-
145-
if (registry->count >= WOLFHSM_CFG_SERVER_WRAPPED_KEY_COUNT) {
146-
return WH_ERROR_NOSPACE;
147-
}
148-
149-
/* Store only the client-relative ID portion */
150-
registry->ids[registry->count++] = (whKeyId)clientRelativeId;
151-
return WH_ERROR_OK;
152-
}
153-
154-
/**
155-
* @brief Determine if a keyId is registered as a wrapped key
156-
*
157-
* Extracts the client-relative ID portion from keyId before checking registry.
158-
* This allows the registry to match regardless of the client ID encoded in
159-
* keyId.
160-
*/
161-
static int _IsKnownWrappedKey(whServerContext* server, whKeyId keyId)
162-
{
163-
whWrappedKeyRegistry* registry;
164-
uint8_t clientRelativeId;
165-
166-
/* Get the appropriate registry (local or global) based on keyId encoding */
167-
registry = _GetWrappedRegistry(server, keyId);
168-
169-
/* Extract client-relative ID (0-255) for comparison */
170-
clientRelativeId = WH_KEYID_ID(keyId);
171-
172-
/* Registry stores client-relative IDs, so pass extracted ID */
173-
return _WrappedRegistryContains(registry, (whKeyId)clientRelativeId);
174-
}
175-
#endif /* WOLFHSM_CFG_KEYWRAP */
176-
17785
/**
17886
* @brief Find a key in the specified cache context
17987
*/
@@ -354,19 +262,17 @@ int wh_Server_KeystoreGetUniqueId(whServerContext* server, whNvmId* inout_id)
354262

355263
whKeyCacheContext* ctx = _GetCacheContext(server, key_id);
356264

265+
/* Wrapped keys must be provisioned with explicit identifiers */
266+
if (type == WH_KEYTYPE_WRAPPED) {
267+
return WH_ERROR_BADARGS;
268+
}
269+
357270
/* try every index until we find a unique one, don't worry about capacity */
358271
for (id = WH_KEYID_IDMAX; id > WH_KEYID_ERASED; id--) {
359272
/* id loop var is not an input client ID so we don't need to handle the
360273
* global case */
361274
buildId = WH_MAKE_KEYID(type, user, id);
362275

363-
#ifdef WOLFHSM_CFG_KEYWRAP
364-
/* Skip over known wrapped keys */
365-
if (_IsKnownWrappedKey(server, buildId)) {
366-
continue;
367-
}
368-
#endif
369-
370276
/* Check against cache keys using unified cache functions */
371277
ret = _FindInKeyCache(ctx, buildId, NULL, NULL, NULL, NULL);
372278
if (ret == WH_ERROR_OK) {
@@ -579,6 +485,26 @@ static int _ExistsInCache(whServerContext* server, whKeyId keyId)
579485
}
580486
#endif /* WOLFHSM_CFG_KEYWRAP */
581487

488+
#ifdef WOLFHSM_CFG_KEYWRAP
489+
int wh_Server_KeystoreIsWrappedKey(whServerContext* server, whKeyId keyId,
490+
int* outIsWrapped)
491+
{
492+
int isWrapped;
493+
494+
if (server == NULL || WH_KEYID_ISERASED(keyId)) {
495+
return WH_ERROR_BADARGS;
496+
}
497+
498+
(void)server;
499+
isWrapped = (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED);
500+
if (outIsWrapped != NULL) {
501+
*outIsWrapped = isWrapped;
502+
}
503+
504+
return WH_ERROR_OK;
505+
}
506+
#endif /* WOLFHSM_CFG_KEYWRAP */
507+
582508
/* try to put the specified key into cache if it isn't already, return pointers
583509
* to meta and the cached data*/
584510
int wh_Server_KeystoreFreshenKey(whServerContext* server, whKeyId keyId,
@@ -593,12 +519,10 @@ int wh_Server_KeystoreFreshenKey(whServerContext* server, whKeyId keyId,
593519
return WH_ERROR_BADARGS;
594520
}
595521

596-
#ifdef WOLFHSM_CFG_KEYWRAP
597-
/* Reject attempts to freshen a known wrapped key */
598-
if (_IsKnownWrappedKey(server, keyId)) {
522+
/* Reject attempts to freshen wrapped keys from NVM */
523+
if (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED) {
599524
return WH_ERROR_ABORTED;
600525
}
601-
#endif
602526

603527
ret = _FindInCache(server, keyId, &foundIndex, &foundBigIndex, outBuf,
604528
outMeta);
@@ -658,12 +582,10 @@ int wh_Server_KeystoreReadKey(whServerContext* server, whKeyId keyId,
658582
return 0;
659583
}
660584

661-
#ifdef WOLFHSM_CFG_KEYWRAP
662585
/* Prevent exposing wrapped blobs through the unwrapped read path */
663-
if (_IsKnownWrappedKey(server, keyId)) {
586+
if (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED) {
664587
return WH_ERROR_NOTFOUND;
665588
}
666-
#endif
667589

668590
/* Not in cache, try to read the metadata from NVM */
669591
ret = wh_Nvm_GetMetadata(server->nvm, keyId, meta);
@@ -737,11 +659,9 @@ int wh_Server_KeystoreCommitKey(whServerContext* server, whNvmId keyId)
737659
return WH_ERROR_BADARGS;
738660
}
739661

740-
#ifdef WOLFHSM_CFG_KEYWRAP
741-
if (_IsKnownWrappedKey(server, keyId)) {
662+
if (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED) {
742663
return WH_ERROR_ABORTED;
743664
}
744-
#endif
745665

746666
/* Get the appropriate cache context for this key */
747667
ctx = _GetCacheContext(server, keyId);
@@ -765,11 +685,9 @@ int wh_Server_KeystoreEraseKey(whServerContext* server, whNvmId keyId)
765685
return WH_ERROR_BADARGS;
766686
}
767687

768-
#ifdef WOLFHSM_CFG_KEYWRAP
769-
if (_IsKnownWrappedKey(server, keyId)) {
688+
if (WH_KEYID_TYPE(keyId) == WH_KEYTYPE_WRAPPED) {
770689
return WH_ERROR_ABORTED;
771690
}
772-
#endif
773691

774692
/* remove the key from the cache if present */
775693
(void)wh_Server_KeystoreEvictKey(server, keyId);
@@ -778,54 +696,6 @@ int wh_Server_KeystoreEraseKey(whServerContext* server, whNvmId keyId)
778696
return wh_Nvm_DestroyObjects(server->nvm, 1, &keyId);
779697
}
780698

781-
#ifdef WOLFHSM_CFG_KEYWRAP
782-
int wh_Server_KeystoreRegisterWrappedKeys(whServerContext* server,
783-
const whKeyId* keyIds, size_t count)
784-
{
785-
uint16_t i;
786-
int ret;
787-
788-
if (server == NULL || keyIds == NULL || count == 0) {
789-
return WH_ERROR_BADARGS;
790-
}
791-
792-
if (count > WOLFHSM_CFG_SERVER_WRAPPED_KEY_COUNT) {
793-
return WH_ERROR_BADARGS;
794-
}
795-
796-
for (i = 0; i < count; i++) {
797-
whWrappedKeyRegistry* registry = _GetWrappedRegistry(server, keyIds[i]);
798-
ret = _WrappedRegistryAdd(registry, keyIds[i]);
799-
if (ret != WH_ERROR_OK) {
800-
return ret;
801-
}
802-
}
803-
804-
return WH_ERROR_OK;
805-
}
806-
807-
int wh_Server_KeystoreRegisterWrappedKey(whServerContext* server, whKeyId keyId)
808-
{
809-
return wh_Server_KeystoreRegisterWrappedKeys(server, &keyId, 1);
810-
}
811-
812-
int wh_Server_KeystoreIsWrappedKey(whServerContext* server, whKeyId keyId,
813-
int* outIsWrapped)
814-
{
815-
int isWrapped;
816-
817-
if (server == NULL || WH_KEYID_ISERASED(keyId)) {
818-
return WH_ERROR_BADARGS;
819-
}
820-
821-
isWrapped = _IsKnownWrappedKey(server, keyId);
822-
if (outIsWrapped != NULL) {
823-
*outIsWrapped = isWrapped;
824-
}
825-
826-
return WH_ERROR_OK;
827-
}
828-
829699
#ifndef NO_AES
830700
#ifdef HAVE_AESGCM
831701

@@ -1001,6 +871,10 @@ static int _HandleWrapKeyRequest(whServerContext* server,
1001871
memcpy(&metadata, reqData, sizeof(metadata));
1002872
memcpy(key, reqData + sizeof(metadata), req->keySz);
1003873

874+
if (!WH_KEYID_ISWRAPPED(metadata.id)) {
875+
return WH_ERROR_CONFIG;
876+
}
877+
1004878
/* Store the wrapped key in the response data */
1005879
wrappedKey = respData;
1006880

@@ -1089,6 +963,10 @@ static int _HandleUnwrapAndExportKeyRequest(
1089963
return ret;
1090964
}
1091965

966+
if (!WH_KEYID_ISWRAPPED(metadata->id)) {
967+
return WH_ERROR_CONFIG;
968+
}
969+
1092970
/* Check if the key is exportable */
1093971
if (metadata->flags & WH_NVM_FLAGS_NONEXPORTABLE) {
1094972
return WH_ERROR_ACCESS;
@@ -1177,9 +1055,8 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server,
11771055
metadata.id = WH_TRANSLATE_CLIENT_KEYID(
11781056
WH_KEYTYPE_CRYPTO, server->comm->client_id, metadata.id);
11791057

1180-
/* If not a known wrapped key then there is a configuration error, we can't
1181-
* handle unknown wrapped keys in the system */
1182-
if (!_IsKnownWrappedKey(server, metadata.id)) {
1058+
/* Require explicit wrapped-key encoding */
1059+
if (WH_KEYID_TYPE(metadata.id) != WH_KEYTYPE_WRAPPED) {
11831060
return WH_ERROR_CONFIG;
11841061
}
11851062

@@ -1191,14 +1068,12 @@ _HandleUnwrapAndCacheKeyRequest(whServerContext* server,
11911068
/* Store the assigned key ID in the response (ID portion only). We should
11921069
* NOT return the upper bits back to the client */
11931070
/* TODO: should we not return the global bit? */
1194-
resp->keyId = WH_KEYID_ID(metadata.id);
1071+
resp->keyId = WH_KEYID_TO_CLIENT(metadata.id);
11951072

11961073
/* Cache the key */
11971074
return wh_Server_KeystoreCacheKey(server, &metadata, key);
11981075
}
11991076

1200-
#endif /* WOLFHSM_CFG_KEYWRAP */
1201-
12021077
int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic,
12031078
uint16_t action, uint16_t req_size,
12041079
const void* req_packet, uint16_t* out_resp_size,

0 commit comments

Comments
 (0)