Skip to content
Merged
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
9 changes: 6 additions & 3 deletions benchmark/wh_bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@

#if defined(WOLFHSM_CFG_BENCH_ENABLE)

/* Default client ID for benchmarks */
#define WH_BENCH_CLIENT_ID (1)

/* Buffer sizes for transport */
/* Large enough to handle an RSA 4096 key */
#define BUFFER_SIZE \
Expand Down Expand Up @@ -816,7 +819,7 @@ static whCommClientConfig g_mem_cc_conf = {
.transport_cb = &g_mem_tccb,
.transport_context = (void*)&g_mem_tmcc,
.transport_config = (void*)&g_mem_tmcf,
.client_id = 123,
.client_id = WH_BENCH_CLIENT_ID,
};

static whTransportServerCb g_mem_tscb = WH_TRANSPORT_MEM_SERVER_CB;
Expand Down Expand Up @@ -868,7 +871,7 @@ static int _configureClientTransport(whBenchTransportType transport,
.transport_cb = pttcClientShmCb,
.transport_context = (void*)&tccShm,
.transport_config = (void*)&myshmconfig,
.client_id = 12,
.client_id = WH_BENCH_CLIENT_ID,
};

memset(&tccShm, 0, sizeof(posixTransportShmClientContext));
Expand All @@ -888,7 +891,7 @@ static int _configureClientTransport(whBenchTransportType transport,
.transport_cb = &pttcClientTcpCb,
.transport_context = (void*)&tccTcp,
.transport_config = (void*)&mytcpconfig,
.client_id = 12,
.client_id = WH_BENCH_CLIENT_ID,
};

memset(&tccTcp, 0, sizeof(posixTransportTcpClientContext));
Expand Down
62 changes: 32 additions & 30 deletions examples/demo/client/wh_demo_client_keywrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@

#ifdef WOLFHSM_CFG_KEYWRAP

#define WH_TEST_KEKID 1
#define WH_DEMO_KEYWRAP_KEKID 1
static int _InitServerKek(whClientContext* ctx)
{
/* IMPORTANT NOTE: Server KEK is typically intrinsic or set during
* provisioning. Uploading the KEK via the client is for testing purposes
* only and not intended as a recommendation */
whKeyId serverKeyId = WH_TEST_KEKID;
whKeyId serverKeyId = WH_DEMO_KEYWRAP_KEKID;
whNvmFlags flags = WH_NVM_FLAGS_NONEXPORTABLE;
uint8_t label[WH_NVM_LABEL_LEN] = "Server KEK key";
uint8_t kek[] = {0x03, 0x03, 0x0d, 0xd9, 0xeb, 0x18, 0x17, 0x2e,
Expand All @@ -57,43 +57,44 @@ static int _InitServerKek(whClientContext* ctx)

static int _CleanupServerKek(whClientContext* ctx)
{
return wh_Client_KeyErase(ctx, WH_TEST_KEKID);
return wh_Client_KeyErase(ctx, WH_DEMO_KEYWRAP_KEKID);
}

#ifndef NO_AES
#ifdef HAVE_AESGCM

#define WH_TEST_AES_KEYSIZE 16
#define WH_TEST_AES_TEXTSIZE 16
#define WH_TEST_AES_IVSIZE 12
#define WH_TEST_AES_TAGSIZE 16
#define WH_TEST_AES_WRAPPED_KEYSIZE \
(WH_TEST_AES_IVSIZE + WH_TEST_AES_TAGSIZE + WH_TEST_AES_KEYSIZE + \
sizeof(whNvmMetadata))
#define WH_TEST_AESGCM_WRAPKEY_ID 8
#define WH_DEMO_KEYWRAP_AES_KEYSIZE 16
#define WH_DEMO_KEYWRAP_AES_TEXTSIZE 16
#define WH_DEMO_KEYWRAP_AES_IVSIZE 12
#define WH_DEMO_KEYWRAP_AES_TAGSIZE 16
#define WH_DEMO_KEYWRAP_AES_WRAPPED_KEYSIZE \
(WH_DEMO_KEYWRAP_AES_IVSIZE + WH_DEMO_KEYWRAP_AES_TAGSIZE + \
WH_DEMO_KEYWRAP_AES_KEYSIZE + sizeof(whNvmMetadata))
#define WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID 8

int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)
{
int ret = 0;
Aes aes[1];
WC_RNG rng[1];
uint8_t key[WH_TEST_AES_KEYSIZE];
uint8_t exportedKey[WH_TEST_AES_KEYSIZE];
uint8_t key[WH_DEMO_KEYWRAP_AES_KEYSIZE];
uint8_t exportedKey[WH_DEMO_KEYWRAP_AES_KEYSIZE];
whNvmMetadata metadata = {
.id = WH_MAKE_KEYID(WH_KEYTYPE_CRYPTO, 0, WH_TEST_AESGCM_WRAPKEY_ID),
.label = "AES Key Label",
.id = WH_CLIENT_KEYID_MAKE_WRAPPED_META(
client->comm->client_id, WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID),
.label = "AES Key Label",
.access = WH_NVM_ACCESS_ANY,
.len = WH_TEST_AES_KEYSIZE};
.len = WH_DEMO_KEYWRAP_AES_KEYSIZE};
whNvmMetadata exportedMetadata;
uint8_t wrappedKey[WH_TEST_AES_WRAPPED_KEYSIZE];
uint8_t wrappedKey[WH_DEMO_KEYWRAP_AES_WRAPPED_KEYSIZE];
whKeyId wrappedKeyId;

const uint8_t plaintext[] = "hello, wolfSSL AES-GCM!";
uint8_t ciphertext[sizeof(plaintext)];
uint8_t decrypted[sizeof(plaintext)];

uint8_t tag[WH_TEST_AES_TAGSIZE];
uint8_t iv[WH_TEST_AES_IVSIZE];
uint8_t tag[WH_DEMO_KEYWRAP_AES_TAGSIZE];
uint8_t iv[WH_DEMO_KEYWRAP_AES_IVSIZE];
const uint8_t aad[] = {0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe,
0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad,
0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2};
Expand Down Expand Up @@ -129,8 +130,8 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)

/* Now we request the server to wrap the key using the KEK we
* establish above in the first step. */
ret = wh_Client_KeyWrap(client, WC_CIPHER_AES_GCM, WH_TEST_KEKID, key,
sizeof(key), &metadata, wrappedKey,
ret = wh_Client_KeyWrap(client, WC_CIPHER_AES_GCM, WH_DEMO_KEYWRAP_KEKID,
key, sizeof(key), &metadata, wrappedKey,
sizeof(wrappedKey));
if (ret != 0) {
printf("Failed to wh_Client_KeyWrap %d\n", ret);
Expand All @@ -146,9 +147,9 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)
/* Request the server to unwrap and cache the wrapped key we just created.
* This will provide us back a key ID that the client can use to do crypto
* operations */
ret = wh_Client_KeyUnwrapAndCache(client, WC_CIPHER_AES_GCM, WH_TEST_KEKID,
wrappedKey, sizeof(wrappedKey),
&wrappedKeyId);
ret = wh_Client_KeyUnwrapAndCache(client, WC_CIPHER_AES_GCM,
WH_DEMO_KEYWRAP_KEKID, wrappedKey,
sizeof(wrappedKey), &wrappedKeyId);
if (ret != 0) {
printf("Failed to wh_Client_KeyUnwrapAndCache %d\n", ret);
goto cleanup_rng;
Expand All @@ -163,7 +164,8 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)

/* Set the key id for this AES context to the wrapped key ID that the server
* provided us */
ret = wh_Client_AesSetKeyId(aes, wrappedKeyId);
ret =
wh_Client_AesSetKeyId(aes, WH_CLIENT_KEYID_MAKE_WRAPPED(wrappedKeyId));
if (ret != 0) {
printf("Failed to wh_Client_AesSetKeyId %d\n", ret);
goto cleanup_aes;
Expand Down Expand Up @@ -209,12 +211,12 @@ int wh_DemoClient_AesGcmKeyWrap(whClientContext* client)
/* Exporting a wrapped key */

/* Request the server to unwrap and export the wrapped key we created */
ret = wh_Client_KeyUnwrapAndExport(client, WC_CIPHER_AES_GCM, WH_TEST_KEKID,
wrappedKey, sizeof(wrappedKey),
&exportedMetadata, exportedKey,
sizeof(exportedKey));
ret = wh_Client_KeyUnwrapAndExport(client, WC_CIPHER_AES_GCM,
WH_DEMO_KEYWRAP_KEKID, wrappedKey,
sizeof(wrappedKey), &exportedMetadata,
exportedKey, sizeof(exportedKey));
if (ret != 0) {
printf("Failed to wh_Client_KeyUnwrapAndCache %d\n", ret);
printf("Failed to wh_Client_KeyUnwrapAndExport %d\n", ret);
goto cleanup_aes;
}

Expand Down
3 changes: 3 additions & 0 deletions examples/demo/client/wh_demo_client_keywrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include "wolfhsm/wh_client.h"

/* Exposed in header so the demo server can obtain the ID for registration */
#define WH_DEMO_KEYWRAP_AESGCM_WRAPKEY_ID 8

int wh_DemoClient_KeyWrap(whClientContext* clientContext);

#endif /* !DEMO_CLIENT_KEYWRAP_H_ */
9 changes: 9 additions & 0 deletions examples/posix/wh_posix_client/wh_posix_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ static int wh_ClientTask(void* cf, const char* type, int test)

ret = wh_Client_Init(client, config);

if (ret == 0) {
ret = wh_Client_CommInit(client, NULL, NULL);
if (ret != 0) {
printf("Failed to initialize client communication\n");
return -1;
}
}

if (strcmp(type, "dma") == 0) {
#ifdef WOLFSSL_STATIC_MEMORY
printf("Setting up DMA heap with static memory buckets\n");
Expand All @@ -85,6 +93,7 @@ static int wh_ClientTask(void* cf, const char* type, int test)

printf("Client connecting to server...\n");
if (ret == 0 && test) {
printf("Running client demos...\n");
return wh_DemoClient_All(client);
}

Expand Down
1 change: 1 addition & 0 deletions examples/posix/wh_posix_client/wolfhsm_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define WOLFHSM_CFG_COMM_DATA_LEN 5000
#ifndef WOLFHSM_CFG_NO_CRYPTO
#define WOLFHSM_CFG_KEYWRAP
#define WOLFHSM_CFG_GLOBAL_KEYS
#endif

#endif /* WOLFHSM_CFG_H_ */
1 change: 0 additions & 1 deletion examples/posix/wh_posix_server/wh_posix_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ static int loadAndStoreKeys(whServerContext* server, whKeyId* outKeyId,
#endif /* !WOLFHSM_CFG_NO_CRYPTO */
}


static int wh_ServerTask(void* cf, const char* keyFilePath, int keyId,
int clientId)
{
Expand Down
5 changes: 4 additions & 1 deletion examples/posix/wh_posix_server/wolfhsm_cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@
#define WOLFHSM_CFG_CERTIFICATE_MANAGER
#define WOLFHSM_CFG_CERTIFICATE_MANAGER_ACERT

#define XMEMFENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST)

#define WOLFHSM_CFG_KEYWRAP_MAX_KEY_SIZE 5000

#define XMEMFENCE() __atomic_thread_fence(__ATOMIC_SEQ_CST)
#ifndef WOLFHSM_CFG_NO_CRYPTO
#define WOLFHSM_CFG_KEYWRAP
#define WOLFHSM_CFG_GLOBAL_KEYS
#endif

#endif /* WOLFHSM_CFG_H_ */
9 changes: 7 additions & 2 deletions src/wh_client_keywrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,16 @@ int wh_Client_KeyUnwrapAndExportResponse(whClientContext* ctx,
if (group != WH_MESSAGE_GROUP_KEY || action != WH_KEY_UNWRAPEXPORT ||
size < sizeof(*resp) ||
size > sizeof(*resp) + sizeof(*metadataOut) + keySz ||
resp->keySz != keySz || resp->cipherType != cipherType) {
resp->cipherType != cipherType) {
return WH_ERROR_ABORTED;
}

if (resp->rc != 0) {
if (resp->rc != WH_ERROR_OK) {
return resp->rc;
}
else if (resp->keySz != keySz) {
return WH_ERROR_BUFFER_SIZE;
}

/* Copy the metadata and key from the response data into metadataOut and
* keyOut */
Expand Down Expand Up @@ -298,6 +301,8 @@ int wh_Client_KeyUnwrapAndCacheResponse(whClientContext* ctx,
return resp->rc;
}

/* Server returns ID portion only. Client must track ownership
* and specify appropriate flags when later using the key. */
*keyIdOut = resp->keyId;

return WH_ERROR_OK;
Expand Down
69 changes: 69 additions & 0 deletions src/wh_keyid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2025 wolfSSL Inc.
*
* This file is part of wolfHSM.
*
* wolfHSM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfHSM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wolfHSM. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* src/wh_keyid.c
*
* KeyId helper function implementations for wolfHSM
*/

#include "wolfhsm/wh_keyid.h"

whKeyId wh_KeyId_TranslateFromClient(uint16_t type, uint16_t clientId,
whKeyId reqId)
{
uint16_t user = clientId;
whKeyId id = reqId & WH_KEYID_MASK;

#ifdef WOLFHSM_CFG_GLOBAL_KEYS
/* Convert global flag to USER=0 */
if ((reqId & WH_KEYID_CLIENT_GLOBAL_FLAG) != 0) {
user = WH_KEYUSER_GLOBAL;
}
#endif

#ifdef WOLFHSM_CFG_KEYWRAP
/* Convert wrapped flag to TYPE=WH_KETYPE_WRAPPED */
if ((reqId & WH_KEYID_CLIENT_WRAPPED_FLAG) != 0) {
type = WH_KEYTYPE_WRAPPED;
}
#endif

return WH_MAKE_KEYID(type, user, id);
}

whKeyId wh_KeyId_TranslateToClient(whKeyId serverId)
{
whKeyId clientId = WH_KEYID_ID(serverId);

#ifdef WOLFHSM_CFG_GLOBAL_KEYS
/* Convert USER=0 to global flag */
if (WH_KEYID_USER(serverId) == WH_KEYUSER_GLOBAL) {
clientId |= WH_KEYID_CLIENT_GLOBAL_FLAG;
}
#endif

#ifdef WOLFHSM_CFG_KEYWRAP
/* Convert TYPE=WRAPPED to wrapped flag */
if (WH_KEYID_TYPE(serverId) == WH_KEYTYPE_WRAPPED) {
clientId |= WH_KEYID_CLIENT_WRAPPED_FLAG;
}
#endif

return clientId;
}
10 changes: 10 additions & 0 deletions src/wh_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ int wh_Nvm_Init(whNvmContext* context, const whNvmConfig *config)
context->cb = config->cb;
context->context = config->context;

#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLFHSM_CFG_GLOBAL_KEYS)
/* Initialize the global key cache */
memset(&context->globalCache, 0, sizeof(context->globalCache));
#endif

if (context->cb->Init != NULL) {
rc = context->cb->Init(context->context, config->config);
if (rc != 0) {
Expand All @@ -64,6 +69,11 @@ int wh_Nvm_Cleanup(whNvmContext* context)
return WH_ERROR_BADARGS;
}

#if !defined(WOLFHSM_CFG_NO_CRYPTO) && defined(WOLFHSM_CFG_GLOBAL_KEYS)
/* Clear the global key cache */
memset(&context->globalCache, 0, sizeof(context->globalCache));
#endif

/* No callback? Return ABORTED */
if (context->cb->Cleanup == NULL) {
return WH_ERROR_ABORTED;
Expand Down
9 changes: 9 additions & 0 deletions src/wh_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,17 @@ static int _wh_Server_HandleCommRequest(whServerContext* server,
wh_MessageComm_TranslateInitRequest(magic,
(whMessageCommInitRequest*)req_packet, &req);

#ifdef WOLFHSM_CFG_GLOBAL_KEYS
/* USER=0 is reserved for global keys, client_id must be non-zero */
if (req.client_id == WH_KEYUSER_GLOBAL) {
*out_resp_size = 0;
return WH_ERROR_BADARGS;
}
#endif

/* Process the init action */
server->comm->client_id = req.client_id;

resp.client_id = server->comm->client_id;
resp.server_id = server->comm->server_id;

Expand Down
Loading