|
1 | 1 | # Crypto Affinity Client API |
2 | 2 |
|
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. |
4 | 6 |
|
5 | 7 | ## Affinity Values |
6 | 8 |
|
7 | 9 | ```c |
8 | 10 | 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) |
11 | 13 | }; |
12 | 14 | ``` |
13 | 15 |
|
14 | | -## SetCryptoAffinity |
| 16 | +The default affinity after client initialization is `WH_CRYPTO_AFFINITY_HW`. |
| 17 | + |
| 18 | +## API |
15 | 19 |
|
16 | | -### Blocking API (simplest) |
| 20 | +### SetCryptoAffinity |
17 | 21 |
|
18 | 22 | ```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); |
21 | 24 | ``` |
22 | 25 |
|
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. |
24 | 27 |
|
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` |
33 | 31 |
|
34 | | -## GetCryptoAffinity |
| 32 | +**Returns:** |
| 33 | +- `WH_ERROR_OK` -- Affinity set successfully |
| 34 | +- `WH_ERROR_BADARGS` -- NULL context or invalid affinity value |
35 | 35 |
|
36 | | -### Blocking API (simplest) |
| 36 | +### GetCryptoAffinity |
37 | 37 |
|
38 | 38 | ```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); |
41 | 40 | ``` |
42 | 41 |
|
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. |
44 | 43 |
|
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 |
48 | 47 |
|
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 |
53 | 51 |
|
54 | 52 | ## Usage Example |
55 | 53 |
|
56 | 54 | ```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 | | - ¤t_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; |
68 | 56 |
|
69 | | -// Switch to software crypto |
70 | | -rc = wh_Client_SetCryptoAffinity(client, |
71 | | - WH_CRYPTO_AFFINITY_SW, |
72 | | - &server_rc, |
73 | | - ¤t_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 | | - ¤t_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 */ |
85 | 60 |
|
| 61 | +/* Switch to hardware crypto -- takes effect immediately, no round-trip */ |
| 62 | +int rc = wh_Client_SetCryptoAffinity(client, WH_CRYPTO_AFFINITY_HW); |
86 | 63 | 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 */ |
92 | 65 | } |
93 | | -``` |
94 | | - |
95 | | -## Return Values |
96 | 66 |
|
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 */ |
101 | 70 |
|
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 | +``` |
110 | 75 |
|
111 | | -### Server Return Codes (GetCryptoAffinity) |
| 76 | +## Server Behavior |
112 | 77 |
|
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`: |
118 | 79 |
|
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` | |
120 | 84 |
|
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. |
122 | 86 |
|
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 |
127 | 88 |
|
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: |
129 | 90 |
|
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) |
0 commit comments