Skip to content

Commit 9766c37

Browse files
bigbrettAlexLanzano
authored andcommitted
Refactor to move crypto affinity state to client and add affinity field to generic crypto header
1 parent 77b3283 commit 9766c37

17 files changed

+533
-892
lines changed

docs/draft/crypto_affinity.md

Lines changed: 53 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,94 @@
11
# Crypto Affinity Client API
22

3-
The crypto affinity feature allows a client to control and query whether the server uses **software** or **hardware** cryptographic implementations.
3+
The crypto affinity feature allows a client to control whether the server uses **software** or **hardware** cryptographic implementations on a per-request basis.
4+
5+
Affinity is stored as **client-local state** and is transmitted to the server in every crypto request message header. There is no dedicated round-trip required to change affinity -- setting it is instantaneous and takes effect on the next crypto operation. Affinity persists for all subsequent requests once changed.
46

57
## Affinity Values
68

79
```c
810
enum WH_CRYPTO_AFFINITY_ENUM {
9-
WH_CRYPTO_AFFINITY_SW = 0, // Use software crypto (devId = INVALID_DEVID)
10-
WH_CRYPTO_AFFINITY_HW = 1, // Attempt to use hardware crypto (devId = configured value)
11+
WH_CRYPTO_AFFINITY_HW = 0, // Attempt to use hardware crypto (devId = configured value)
12+
WH_CRYPTO_AFFINITY_SW = 1, // Use software crypto (devId = INVALID_DEVID)
1113
};
1214
```
1315

14-
## SetCryptoAffinity
16+
The default affinity after client initialization is `WH_CRYPTO_AFFINITY_HW`.
17+
18+
## API
1519

16-
### Blocking API (simplest)
20+
### SetCryptoAffinity
1721

1822
```c
19-
int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity,
20-
int32_t* out_rc, uint32_t* out_affinity);
23+
int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity);
2124
```
2225
23-
### Non-blocking (async) API
26+
Sets the client's crypto affinity. This is a **local operation** that does not communicate with the server. The new affinity value will be included in all subsequent crypto request messages.
2427
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-
```
28+
**Parameters:**
29+
- `c` -- Client context
30+
- `affinity` -- `WH_CRYPTO_AFFINITY_SW` or `WH_CRYPTO_AFFINITY_HW`
3331
34-
## GetCryptoAffinity
32+
**Returns:**
33+
- `WH_ERROR_OK` -- Affinity set successfully
34+
- `WH_ERROR_BADARGS` -- NULL context or invalid affinity value
3535
36-
### Blocking API (simplest)
36+
### GetCryptoAffinity
3737
3838
```c
39-
int wh_Client_GetCryptoAffinity(whClientContext* c,
40-
int32_t* out_rc, uint32_t* out_affinity);
39+
int wh_Client_GetCryptoAffinity(whClientContext* c, uint32_t* out_affinity);
4140
```
4241

43-
### Non-blocking (async) API
42+
Retrieves the client's current crypto affinity. This is a **local operation** that does not communicate with the server.
4443

45-
```c
46-
// Send request
47-
int wh_Client_GetCryptoAffinityRequest(whClientContext* c);
44+
**Parameters:**
45+
- `c` -- Client context
46+
- `out_affinity` -- Pointer to receive the current affinity value
4847

49-
// Receive response
50-
int wh_Client_GetCryptoAffinityResponse(whClientContext* c, int32_t* out_rc,
51-
uint32_t* out_affinity);
52-
```
48+
**Returns:**
49+
- `WH_ERROR_OK` -- Affinity retrieved successfully
50+
- `WH_ERROR_BADARGS` -- NULL context or NULL output pointer
5351

5452
## Usage Example
5553

5654
```c
57-
int32_t server_rc;
58-
uint32_t current_affinity;
59-
60-
// Query current crypto affinity
61-
int rc = wh_Client_GetCryptoAffinity(client,
62-
&server_rc,
63-
&current_affinity);
64-
65-
if (rc == WH_ERROR_OK && server_rc == WH_ERROR_OK) {
66-
// current_affinity contains the active affinity
67-
}
55+
uint32_t affinity;
6856

69-
// Switch to software crypto
70-
rc = wh_Client_SetCryptoAffinity(client,
71-
WH_CRYPTO_AFFINITY_SW,
72-
&server_rc,
73-
&current_affinity);
74-
75-
if (rc == WH_ERROR_OK && server_rc == WH_ERROR_OK) {
76-
// Server is now using software crypto
77-
// current_affinity == WH_CRYPTO_AFFINITY_SW
78-
}
79-
80-
// Switch to hardware crypto
81-
rc = wh_Client_SetCryptoAffinity(client,
82-
WH_CRYPTO_AFFINITY_HW,
83-
&server_rc,
84-
&current_affinity);
57+
/* Default affinity is WH_CRYPTO_AFFINITY_SW after wh_Client_Init() */
58+
wh_Client_GetCryptoAffinity(client, &affinity);
59+
/* affinity == WH_CRYPTO_AFFINITY_SW */
8560

61+
/* Switch to hardware crypto -- takes effect immediately, no round-trip */
62+
int rc = wh_Client_SetCryptoAffinity(client, WH_CRYPTO_AFFINITY_HW);
8663
if (rc == WH_ERROR_OK) {
87-
if (server_rc == WH_ERROR_OK) {
88-
// Server is now using hardware crypto
89-
} else if (server_rc == WH_ERROR_NOTIMPL) {
90-
// HW crypto not available (server wasn't configured with a valid devId)
91-
}
64+
/* All subsequent crypto operations will request HW acceleration */
9265
}
93-
```
94-
95-
## Return Values
9666

97-
| Value | Description |
98-
|-------|-------------|
99-
| `rc` (function return) | Transport/communication errors |
100-
| `server_rc` (output parameter) | Server-side result |
67+
/* Perform a crypto operation -- affinity is sent in the request header */
68+
wc_AesCbcEncrypt(&aes, out, in, len);
69+
/* If server has a valid devId, hardware crypto callback is used */
10170

102-
### Server Return Codes (SetCryptoAffinity)
103-
104-
| Code | Description |
105-
|------|-------------|
106-
| `WH_ERROR_OK` | Affinity changed successfully |
107-
| `WH_ERROR_NOTIMPL` | HW requested but no HW crypto configured, `WOLF_CRYPTO_CB` is not defined, or `WOLFHSM_CFG_NO_CRYPTO` is defined |
108-
| `WH_ERROR_BADARGS` | Invalid affinity value |
109-
| `WH_ERROR_ABORTED` | Server crypto context is NULL |
71+
/* Switch back to software crypto */
72+
wh_Client_SetCryptoAffinity(client, WH_CRYPTO_AFFINITY_SW);
73+
/* Subsequent crypto operations use software implementation */
74+
```
11075
111-
### Server Return Codes (GetCryptoAffinity)
76+
## Server Behavior
11277
113-
| Code | Description |
114-
|------|-------------|
115-
| `WH_ERROR_OK` | Affinity queried successfully |
116-
| `WH_ERROR_ABORTED` | Server crypto context is NULL |
117-
| `WH_ERROR_NOTIMPL` | Not implemented (returned when `WOLFHSM_CFG_NO_CRYPTO` is defined) |
78+
When the server receives a crypto request, it reads the affinity field from the generic crypto request header and selects the appropriate `devId`:
11879
119-
## Server Behavior
80+
| Affinity in Request | Server Action |
81+
|---------------------|---------------|
82+
| `WH_CRYPTO_AFFINITY_SW` | Uses `INVALID_DEVID` (wolfCrypt software implementation) |
83+
| `WH_CRYPTO_AFFINITY_HW` | Uses `server->defaultDevId` if valid, otherwise falls back to `INVALID_DEVID` |
12084
121-
When affinity is set:
85+
The `defaultDevId` is configured at server initialization from `config->devId`. If the server was not configured with a valid hardware `devId`, hardware affinity requests will silently fall back to software crypto.
12286
123-
| Affinity | Server Action |
124-
|----------|---------------|
125-
| `WH_CRYPTO_AFFINITY_SW` | `server->devId = INVALID_DEVID` (wolfCrypt uses software) |
126-
| `WH_CRYPTO_AFFINITY_HW` | `server->devId = server->defaultDevId` (wolfCrypt uses registered crypto callback) |
87+
## Protocol Details
12788
128-
When affinity is queried (Get), the server reads the current `devId` and returns the corresponding affinity value without modifying any state.
89+
Affinity is transmitted in the `affinity` field of `whMessageCrypto_GenericRequestHeader`, which is included at the start of every crypto request message. This means:
12990
130-
The `defaultDevId` is stored at server init from `config->devId`.
91+
- Each crypto operation independently specifies its desired affinity
92+
- Multiple clients can use different affinities concurrently without interference
93+
- No server-side affinity state is maintained per-client
94+
- Changing affinity has zero latency (no communication overhead)

src/wh_client.c

Lines changed: 9 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -410,138 +410,26 @@ int wh_Client_CommInfo(whClientContext* c,
410410
return rc;
411411
}
412412

413-
int wh_Client_SetCryptoAffinityRequest(whClientContext* c, uint32_t affinity)
413+
int wh_Client_SetCryptoAffinity(whClientContext* c, uint32_t affinity)
414414
{
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-
437415
if (c == NULL) {
438416
return WH_ERROR_BADARGS;
439417
}
440-
441-
rc = wh_Client_RecvResponse(c, &resp_group, &resp_action, &resp_size, &msg);
442-
if (rc == WH_ERROR_OK) {
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) {
418+
if (affinity != WH_CRYPTO_AFFINITY_SW &&
419+
affinity != WH_CRYPTO_AFFINITY_HW) {
468420
return WH_ERROR_BADARGS;
469421
}
470-
do {
471-
rc = wh_Client_SetCryptoAffinityRequest(c, affinity);
472-
} while (rc == WH_ERROR_NOTREADY);
473-
474-
if (rc == WH_ERROR_OK) {
475-
do {
476-
rc = wh_Client_SetCryptoAffinityResponse(c, out_rc, out_affinity);
477-
} while (rc == WH_ERROR_NOTREADY);
478-
}
479-
return rc;
480-
}
481-
482-
int wh_Client_GetCryptoAffinityRequest(whClientContext* c)
483-
{
484-
if (c == NULL) {
485-
return WH_ERROR_BADARGS;
486-
}
487-
488-
return wh_Client_SendRequest(c, WH_MESSAGE_GROUP_COMM,
489-
WH_MESSAGE_COMM_ACTION_GET_CRYPTO_AFFINITY,
490-
0, NULL);
491-
}
492-
493-
int wh_Client_GetCryptoAffinityResponse(whClientContext* c, int32_t* out_rc,
494-
uint32_t* out_affinity)
495-
{
496-
int rc = 0;
497-
whMessageCommGetCryptoAffinityResponse msg = {0};
498-
uint16_t resp_group = 0;
499-
uint16_t resp_action = 0;
500-
uint16_t resp_size = 0;
501-
502-
if (c == NULL) {
503-
return WH_ERROR_BADARGS;
504-
}
505-
506-
rc = wh_Client_RecvResponse(c, &resp_group, &resp_action, &resp_size, &msg);
507-
if (rc == 0) {
508-
/* Validate response */
509-
if ((resp_group != WH_MESSAGE_GROUP_COMM) ||
510-
(resp_action != WH_MESSAGE_COMM_ACTION_GET_CRYPTO_AFFINITY) ||
511-
(resp_size != sizeof(msg))) {
512-
/* Invalid message */
513-
rc = WH_ERROR_ABORTED;
514-
}
515-
else {
516-
/* Valid message */
517-
if (out_rc != NULL) {
518-
*out_rc = msg.rc;
519-
}
520-
if (out_affinity != NULL) {
521-
*out_affinity = msg.affinity;
522-
}
523-
}
524-
}
525-
return rc;
422+
c->cryptoAffinity = affinity;
423+
return WH_ERROR_OK;
526424
}
527425

528-
int wh_Client_GetCryptoAffinity(whClientContext* c, int32_t* out_rc,
529-
uint32_t* out_affinity)
426+
int wh_Client_GetCryptoAffinity(whClientContext* c, uint32_t* out_affinity)
530427
{
531-
int rc = 0;
532-
if (c == NULL) {
428+
if (c == NULL || out_affinity == NULL) {
533429
return WH_ERROR_BADARGS;
534430
}
535-
do {
536-
rc = wh_Client_GetCryptoAffinityRequest(c);
537-
} while (rc == WH_ERROR_NOTREADY);
538-
539-
if (rc == 0) {
540-
do {
541-
rc = wh_Client_GetCryptoAffinityResponse(c, out_rc, out_affinity);
542-
} while (rc == WH_ERROR_NOTREADY);
543-
}
544-
return rc;
431+
*out_affinity = c->cryptoAffinity;
432+
return WH_ERROR_OK;
545433
}
546434

547435

0 commit comments

Comments
 (0)