Skip to content

Commit b468279

Browse files
committed
add sensitive flag for wrapped keys
1 parent 35a983e commit b468279

File tree

3 files changed

+140
-22
lines changed

3 files changed

+140
-22
lines changed

src/wh_server_keystore.c

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,11 @@ static int _HandleUnwrapAndExportKeyRequest(
969969
return WH_ERROR_ACCESS;
970970
}
971971

972+
/* Check if the key is sensitive */
973+
if (metadata->flags & WH_NVM_FLAGS_SENSITIVE) {
974+
return WH_ERROR_ACCESS;
975+
}
976+
972977
/* Validate client ownership.
973978
* The USER field in wrapped key metadata specifies the owner.
974979
* Only the owning client can export wrapped keys. */
@@ -1304,34 +1309,40 @@ int wh_Server_HandleKeyRequest(whServerContext* server, uint16_t magic,
13041309
server->comm->client_id, req.id),
13051310
meta, out, &keySz);
13061311

1307-
/* Check if key is non-exportable */
1308-
if (ret == WH_ERROR_OK &&
1309-
(meta->flags & WH_NVM_FLAGS_NONEXPORTABLE)) {
1310-
ret = WH_ERROR_ACCESS;
1311-
/* Clear any key data that may have been read */
1312-
memset(out, 0, keySz);
1312+
if (ret == WH_ERROR_OK) {
1313+
/* Check if key is non-exportable */
1314+
if (meta->flags & WH_NVM_FLAGS_NONEXPORTABLE) {
1315+
ret = WH_ERROR_ACCESS;
1316+
}
1317+
1318+
/* Check if key is sensitive */
1319+
if (meta->flags & WH_NVM_FLAGS_SENSITIVE) {
1320+
ret = WH_ERROR_ACCESS;
1321+
}
1322+
1323+
if (ret != WH_ERROR_OK) {
1324+
/* Clear any key data that may have been read */
1325+
memset(out, 0, keySz);
1326+
}
13131327
}
13141328

1329+
/* propagate any failures back to client */
13151330
resp.rc = ret;
1316-
/* TODO: Are there any fatal server errors? */
13171331
ret = WH_ERROR_OK;
13181332

1319-
if (ret == WH_ERROR_OK) {
1320-
/* Only provide key output if no error */
1321-
if (resp.rc == WH_ERROR_OK) {
1322-
resp.len = keySz;
1323-
}
1324-
else {
1325-
resp.len = 0;
1326-
}
1327-
memcpy(resp.label, meta->label, sizeof(meta->label));
1333+
/* Only provide key output if no error */
1334+
if (resp.rc == WH_ERROR_OK) {
1335+
resp.len = keySz;
1336+
}
1337+
else {
1338+
resp.len = 0;
1339+
}
1340+
memcpy(resp.label, meta->label, sizeof(meta->label));
13281341

1329-
(void)wh_MessageKeystore_TranslateExportResponse(
1330-
magic, &resp,
1331-
(whMessageKeystore_ExportResponse*)resp_packet);
1342+
(void)wh_MessageKeystore_TranslateExportResponse(
1343+
magic, &resp, (whMessageKeystore_ExportResponse*)resp_packet);
13321344

1333-
*out_resp_size = sizeof(resp) + resp.len;
1334-
}
1345+
*out_resp_size = sizeof(resp) + resp.len;
13351346
} break;
13361347

13371348
case WH_KEY_COMMIT: {
@@ -1583,6 +1594,11 @@ int wh_Server_KeystoreExportKeyDma(whServerContext* server, whKeyId keyId,
15831594
return WH_ERROR_ACCESS;
15841595
}
15851596

1597+
/* Check if key is sensitive */
1598+
if (cacheMeta->flags & WH_NVM_FLAGS_SENSITIVE) {
1599+
return WH_ERROR_ACCESS;
1600+
}
1601+
15861602
if (keySz < cacheMeta->len) {
15871603
return WH_ERROR_NOSPACE;
15881604
}

test/wh_test_keywrap.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,100 @@ static int _AesGcm_KeyWrap(whClientContext* client, WC_RNG* rng)
227227
return ret;
228228
}
229229

230+
static int _TestKeyWrapSensitive(whClientContext* client, int cipher)
231+
{
232+
int ret = 0;
233+
uint8_t tmpPlainKey[WH_TEST_AES_KEYSIZE];
234+
uint8_t wrappedKey[WH_TEST_AES_WRAPPED_KEYSIZE];
235+
whKeyId wrappedKeyId = WH_KEYID_ERASED;
236+
uint16_t tmpOutSz = 0;
237+
whNvmMetadata metadata = {
238+
.id = WH_CLIENT_KEYID_MAKE_WRAPPED_META(WH_TEST_DEFAULT_CLIENT_ID,
239+
WH_TEST_AESGCM_KEYID + 1),
240+
.label = "Sensitive AES Key",
241+
.len = WH_TEST_AES_KEYSIZE,
242+
.flags = WH_NVM_FLAGS_SENSITIVE,
243+
};
244+
whNvmMetadata tmpMetadata = {0};
245+
246+
const uint8_t hardcodedKey[WH_TEST_AES_KEYSIZE] = {
247+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
248+
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
249+
0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
250+
251+
/* Wrap the key with SENSITIVE flag */
252+
ret =
253+
wh_Client_KeyWrap(client, cipher, WH_TEST_KEKID, (uint8_t*)hardcodedKey,
254+
(uint16_t)sizeof(hardcodedKey), &metadata, wrappedKey,
255+
(uint16_t)sizeof(wrappedKey));
256+
if (ret != WH_ERROR_OK) {
257+
WH_ERROR_PRINT("Failed to wh_Client_KeyWrap with SENSITIVE flag %d\n",
258+
ret);
259+
return ret;
260+
}
261+
262+
/* Unwrap and cache the sensitive key - should succeed */
263+
ret = wh_Client_KeyUnwrapAndCache(client, cipher, WH_TEST_KEKID, wrappedKey,
264+
(uint16_t)sizeof(wrappedKey),
265+
&wrappedKeyId);
266+
if (ret != WH_ERROR_OK) {
267+
WH_ERROR_PRINT(
268+
"Failed to wh_Client_KeyUnwrapAndCache for sensitive key %d\n",
269+
ret);
270+
return ret;
271+
}
272+
273+
/* Now test that all export paths back to client are blocked */
274+
275+
/* Attempts to directly export should fail with WH_ERROR_ACCESS */
276+
tmpOutSz = (uint16_t)sizeof(tmpPlainKey);
277+
ret = wh_Client_KeyExport(client, wrappedKeyId, NULL, 0, tmpPlainKey,
278+
&tmpOutSz);
279+
if (ret != WH_ERROR_ACCESS) {
280+
WH_ERROR_PRINT("wh_Client_KeyExport should return WH_ERROR_ACCESS for "
281+
"sensitive key, got %d\n",
282+
ret);
283+
(void)wh_Client_KeyEvict(client, wrappedKeyId);
284+
return ret;
285+
}
286+
287+
#ifdef WOLFHSM_CFG_DMA
288+
/* Attempts to directly export via DMA should fail with WH_ERROR_ACCESS */
289+
tmpOutSz = (uint16_t)sizeof(tmpPlainKey);
290+
ret = wh_Client_KeyExportDma(client, wrappedKeyId, (const void*)tmpPlainKey,
291+
(uint16_t)sizeof(tmpPlainKey), NULL, 0,
292+
&tmpOutSz);
293+
if (ret != WH_ERROR_ACCESS) {
294+
WH_ERROR_PRINT("wh_Client_KeyExportDma should return WH_ERROR_ACCESS "
295+
"for sensitive key, got %d\n",
296+
ret);
297+
(void)wh_Client_KeyEvict(client, wrappedKeyId);
298+
return ret;
299+
}
300+
#endif
301+
302+
/* Attempts to unwrap and export via the keywrap API should fail with
303+
* WH_ERROR_ACCESS */
304+
ret = wh_Client_KeyUnwrapAndExport(
305+
client, cipher, WH_TEST_KEKID, wrappedKey, (uint16_t)sizeof(wrappedKey),
306+
&tmpMetadata, tmpPlainKey, (uint16_t)sizeof(tmpPlainKey));
307+
if (ret != WH_ERROR_ACCESS) {
308+
WH_ERROR_PRINT("wh_Client_KeyUnwrapAndExport should return "
309+
"WH_ERROR_ACCESS for sensitive key, got %d\n",
310+
ret);
311+
(void)wh_Client_KeyEvict(client, wrappedKeyId);
312+
return ret;
313+
}
314+
315+
/* Success */
316+
ret = WH_ERROR_OK;
317+
318+
/* Cleanup */
319+
(void)wh_Client_KeyEvict(client, wrappedKeyId);
320+
321+
return ret;
322+
}
323+
230324
#endif /* HAVE_AESGCM */
231325

232326
int whTest_Client_KeyWrap(whClientContext* client)
@@ -253,6 +347,14 @@ int whTest_Client_KeyWrap(whClientContext* client)
253347
}
254348
#endif
255349

350+
/* Test sensitive key attribute */
351+
if (ret == WH_ERROR_OK) {
352+
ret = _TestKeyWrapSensitive(client, WC_CIPHER_AES_GCM);
353+
if (ret != WH_ERROR_OK) {
354+
WH_ERROR_PRINT("Failed to _TestKeyWrapSensitive %d\n", ret);
355+
}
356+
}
357+
256358
_CleanupServerKek(client);
257359

258360
(void)wc_FreeRng(rng);

wolfhsm/wh_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ typedef uint16_t whNvmFlags;
7070
#define WH_NVM_FLAGS_ANY ((whNvmFlags)-1)
7171

7272
#define WH_NVM_FLAGS_IMMUTABLE ((whNvmFlags)1 << 0) /* Cannot be overwritten */
73-
#define WH_NVM_FLAGS_SENSITIVE ((whNvmFlags)1 << 1) /* Holds private/secret data */
73+
#define WH_NVM_FLAGS_SENSITIVE ((whNvmFlags)1 << 1) /* Cannot be exported in unwrapped form */
7474
#define WH_NVM_FLAGS_NONEXPORTABLE ((whNvmFlags)1 << 2) /* Cannot be exported */
7575
#define WH_NVM_FLAGS_LOCAL ((whNvmFlags)1 << 3) /* Was generated locally */
7676
#define WH_NVM_FLAGS_EPHEMERAL ((whNvmFlags)1 << 4) /* Cannot be cached nor committed */

0 commit comments

Comments
 (0)