Skip to content

Commit 31452b2

Browse files
committed
Implement HW/SW crypto affinity
1 parent 83cfd06 commit 31452b2

12 files changed

Lines changed: 820 additions & 10 deletions

docs/draft/crypto_affinity.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# SetCryptoAffinity Client API
2+
3+
The SetCryptoAffinity feature allows a client to control whether the server uses **software** or **hardware** cryptographic implementations.
4+
5+
## Affinity Values
6+
7+
```c
8+
enum WH_CRYPTO_AFFINITY_ENUM {
9+
WH_CRYPTO_AFFINITY_SW = 0, // Use software crypto (devId = INVALID_DEVID)
10+
WH_CRYPTO_AFFINITY_HW = 1, // Use hardware crypto (devId = configured value)
11+
};
12+
```
13+
14+
## Client API Functions
15+
16+
### Blocking API (simplest)
17+
18+
```c
19+
int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity,
20+
int32_t* out_rc, uint32_t* out_affinity);
21+
```
22+
23+
### Non-blocking (async) API
24+
25+
```c
26+
// Send request
27+
int wh_Client_SetCryptoAffinityRequest(whClientContext* c, uint32_t affinity);
28+
29+
// Receive response
30+
int wh_Client_SetCryptoAffinityResponse(whClientContext* c, int32_t* out_rc,
31+
uint32_t* out_affinity);
32+
```
33+
34+
## Usage Example
35+
36+
```c
37+
int32_t server_rc;
38+
uint32_t current_affinity;
39+
40+
// Switch to software crypto
41+
int rc = wh_Client_SetCryptoAffinity(client,
42+
WH_CRYPTO_AFFINITY_SW,
43+
&server_rc,
44+
&current_affinity);
45+
46+
if (rc == WH_ERROR_OK && server_rc == WH_ERROR_OK) {
47+
// Server is now using software crypto
48+
// current_affinity == WH_CRYPTO_AFFINITY_SW
49+
}
50+
51+
// Switch to hardware crypto
52+
rc = wh_Client_SetCryptoAffinity(client,
53+
WH_CRYPTO_AFFINITY_HW,
54+
&server_rc,
55+
&current_affinity);
56+
57+
if (rc == WH_ERROR_OK) {
58+
if (server_rc == WH_ERROR_OK) {
59+
// Server is now using hardware crypto
60+
} else if (server_rc == WH_ERROR_BADCONFIG) {
61+
// HW crypto not available (server wasn't configured with a valid devId)
62+
}
63+
}
64+
```
65+
66+
## Return Values
67+
68+
| Value | Description |
69+
|-------|-------------|
70+
| `rc` (function return) | Transport/communication errors |
71+
| `server_rc` (output parameter) | Server-side result |
72+
73+
### Server Return Codes
74+
75+
| Code | Description |
76+
|------|-------------|
77+
| `WH_ERROR_OK` | Affinity changed successfully |
78+
| `WH_ERROR_BADCONFIG` | HW requested but no HW crypto configured |
79+
| `WH_ERROR_BADARGS` | Invalid affinity value |
80+
| `WH_ERROR_ABORTED` | Server crypto context is NULL |
81+
| `WH_ERROR_NOTIMPL` | Affinity change not implemented (returned when `WOLF_CRYPTO_CB` is not defined and HW affinity is requested, or when `WOLFHSM_CFG_NO_CRYPTO` is defined) |
82+
83+
## Server Behavior
84+
85+
When affinity is set:
86+
87+
| Affinity | Server Action |
88+
|----------|---------------|
89+
| `WH_CRYPTO_AFFINITY_SW` | `server->crypto->devId = INVALID_DEVID` (wolfCrypt uses software) |
90+
| `WH_CRYPTO_AFFINITY_HW` | `server->crypto->devId = server->crypto->configDevId` (wolfCrypt uses registered crypto callback) |
91+
92+
The `configDevId` is stored at server init from `config->devId`.

src/wh_client.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,75 @@ int wh_Client_CommInfo(whClientContext* c,
410410
return rc;
411411
}
412412

413+
int wh_Client_SetCryptoAffinityRequest(whClientContext* c, uint32_t affinity)
414+
{
415+
whMessageCommSetCryptoAffinityRequest msg = {0};
416+
417+
if (c == NULL) {
418+
return WH_ERROR_BADARGS;
419+
}
420+
421+
msg.affinity = affinity;
422+
423+
return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_COMM,
424+
WH_MESSAGE_COMM_ACTION_SET_CRYPTO_AFFINITY,
425+
sizeof(msg), &msg);
426+
}
427+
428+
int wh_Client_SetCryptoAffinityResponse(whClientContext* c, int32_t* out_rc,
429+
uint32_t* out_affinity)
430+
{
431+
int rc = 0;
432+
whMessageCommSetCryptoAffinityResponse msg = {0};
433+
uint16_t resp_group = 0;
434+
uint16_t resp_action = 0;
435+
uint16_t resp_size = 0;
436+
437+
if (c == NULL) {
438+
return WH_ERROR_BADARGS;
439+
}
440+
441+
rc = wh_Client_RecvResponse(c, &resp_group, &resp_action, &resp_size, &msg);
442+
if (rc == 0) {
443+
/* Validate response */
444+
if ((resp_group != WH_MESSAGE_GROUP_COMM) ||
445+
(resp_action != WH_MESSAGE_COMM_ACTION_SET_CRYPTO_AFFINITY) ||
446+
(resp_size != sizeof(msg))) {
447+
/* Invalid message */
448+
rc = WH_ERROR_ABORTED;
449+
}
450+
else {
451+
/* Valid message */
452+
if (out_rc != NULL) {
453+
*out_rc = msg.rc;
454+
}
455+
if (out_affinity != NULL) {
456+
*out_affinity = msg.affinity;
457+
}
458+
}
459+
}
460+
return rc;
461+
}
462+
463+
int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity,
464+
int32_t* out_rc, uint32_t* out_affinity)
465+
{
466+
int rc = 0;
467+
if (c == NULL) {
468+
return WH_ERROR_BADARGS;
469+
}
470+
do {
471+
rc = wh_Client_SetCryptoAffinityRequest(c, affinity);
472+
} while (rc == WH_ERROR_NOTREADY);
473+
474+
if (rc == 0) {
475+
do {
476+
rc = wh_Client_SetCryptoAffinityResponse(c, out_rc, out_affinity);
477+
} while (rc == WH_ERROR_NOTREADY);
478+
}
479+
return rc;
480+
}
481+
413482

414483
int wh_Client_CommCloseRequest(whClientContext* c)
415484
{

src/wh_message_comm.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,25 @@ int wh_MessageComm_TranslateInfoResponse(uint16_t magic,
8383
return 0;
8484
}
8585

86+
int wh_MessageComm_TranslateSetCryptoAffinityRequest(
87+
uint16_t magic, const whMessageCommSetCryptoAffinityRequest* src,
88+
whMessageCommSetCryptoAffinityRequest* dest)
89+
{
90+
if ((src == NULL) || (dest == NULL)) {
91+
return WH_ERROR_BADARGS;
92+
}
93+
WH_T32(magic, dest, src, affinity);
94+
return 0;
95+
}
8696

97+
int wh_MessageComm_TranslateSetCryptoAffinityResponse(
98+
uint16_t magic, const whMessageCommSetCryptoAffinityResponse* src,
99+
whMessageCommSetCryptoAffinityResponse* dest)
100+
{
101+
if ((src == NULL) || (dest == NULL)) {
102+
return WH_ERROR_BADARGS;
103+
}
104+
WH_T32(magic, dest, src, rc);
105+
WH_T32(magic, dest, src, affinity);
106+
return 0;
107+
}

src/wh_server.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ int wh_Server_Init(whServerContext* server, whServerConfig* config)
8181
if (server->crypto != NULL) {
8282
#if defined(WOLF_CRYPTO_CB)
8383
server->crypto->devId = config->devId;
84+
server->crypto->configDevId = config->devId;
8485
#else
8586
server->crypto->devId = INVALID_DEVID;
87+
server->crypto->configDevId = INVALID_DEVID;
8688
#endif
8789
}
8890
#ifdef WOLFHSM_CFG_SHE_EXTENSION
@@ -247,6 +249,56 @@ static int _wh_Server_HandleCommRequest(whServerContext* server,
247249
*out_resp_size = sizeof(resp);
248250
}; break;
249251

252+
case WH_MESSAGE_COMM_ACTION_SET_CRYPTO_AFFINITY: {
253+
whMessageCommSetCryptoAffinityRequest req = {0};
254+
whMessageCommSetCryptoAffinityResponse resp = {0};
255+
256+
wh_MessageComm_TranslateSetCryptoAffinityRequest(
257+
magic, (const whMessageCommSetCryptoAffinityRequest*)req_packet,
258+
&req);
259+
260+
#ifndef WOLFHSM_CFG_NO_CRYPTO
261+
if (server->crypto == NULL) {
262+
resp.rc = WH_ERROR_ABORTED;
263+
resp.affinity = WH_CRYPTO_AFFINITY_SW;
264+
}
265+
else {
266+
switch (req.affinity) {
267+
case WH_CRYPTO_AFFINITY_SW:
268+
server->crypto->devId = INVALID_DEVID;
269+
resp.rc = WH_ERROR_OK;
270+
break;
271+
case WH_CRYPTO_AFFINITY_HW:
272+
#ifdef WOLF_CRYPTO_CB
273+
if (server->crypto->configDevId != INVALID_DEVID) {
274+
server->crypto->devId = server->crypto->configDevId;
275+
resp.rc = WH_ERROR_OK;
276+
}
277+
else {
278+
resp.rc = WH_ERROR_BADCONFIG;
279+
}
280+
break;
281+
#else
282+
resp.rc = WH_ERROR_NOTIMPL;
283+
break;
284+
#endif
285+
default:
286+
resp.rc = WH_ERROR_BADARGS;
287+
break;
288+
}
289+
resp.affinity = (server->crypto->devId == INVALID_DEVID)
290+
? WH_CRYPTO_AFFINITY_SW
291+
: WH_CRYPTO_AFFINITY_HW;
292+
}
293+
#else
294+
resp.rc = WH_ERROR_NOTIMPL;
295+
resp.affinity = WH_CRYPTO_AFFINITY_SW;
296+
#endif
297+
298+
wh_MessageComm_TranslateSetCryptoAffinityResponse(
299+
magic, &resp, (whMessageCommSetCryptoAffinityResponse*)resp_packet);
300+
*out_resp_size = sizeof(resp);
301+
}; break;
250302

251303
case WH_MESSAGE_COMM_ACTION_CLOSE:
252304
{

test/wh_test.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "wh_test_log.h"
4343
#include "wh_test_lock.h"
4444
#include "wh_test_posix_threadsafe_stress.h"
45+
#include "wh_test_crypto_affinity.h"
4546

4647
#if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER)
4748
#include "wh_test_cert.h"
@@ -93,6 +94,10 @@ int whTest_Unit(void)
9394
/* Crypto Tests */
9495
WH_TEST_ASSERT(0 == whTest_Crypto());
9596

97+
#ifdef WOLF_CRYPTO_CB
98+
WH_TEST_ASSERT(0 == whTest_CryptoAffinity());
99+
#endif
100+
96101
#if defined(WOLFHSM_CFG_SERVER_IMG_MGR) && !defined(WOLFHSM_CFG_NO_CRYPTO)
97102
/* Image Manager Tests */
98103
WH_TEST_ASSERT(0 == whTest_ServerImgMgr(WH_NVM_TEST_BACKEND_FLASH));

test/wh_test_check_struct_padding.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727

2828

2929
#include "wolfhsm/wh_message_comm.h"
30-
whMessageComm_ErrorResponse whMessageComm_ErrorResponse_test;
31-
whMessageCommInitRequest whMessageCommInitRequest_test;
32-
whMessageCommInitResponse whMessageCommInitResponse_test;
33-
whMessageCommInfoResponse whMessageCommInfoResponse_test;
30+
whMessageComm_ErrorResponse whMessageComm_ErrorResponse_test;
31+
whMessageCommInitRequest whMessageCommInitRequest_test;
32+
whMessageCommInitResponse whMessageCommInitResponse_test;
33+
whMessageCommInfoResponse whMessageCommInfoResponse_test;
34+
whMessageCommSetCryptoAffinityRequest whMessageCommSetCryptoAffinityRequest_test;
35+
whMessageCommSetCryptoAffinityResponse whMessageCommSetCryptoAffinityResponse_test;
3436

3537
#include "wolfhsm/wh_message_customcb.h"
3638
whMessageCustomCb_Request whMessageCustomCb_Request_test;

0 commit comments

Comments
 (0)