2525 * _whTest_KeywrapTrustedKekPolicy - wrap-export and unwrap-and-cache must
2626 * refuse a plain client KEK, and a client
2727 * cannot forge WH_NVM_FLAGS_TRUSTED via the
28- * NVM add, HKDF cache, or key cache paths
28+ * NVM add, HKDF cache, key cache, or key
29+ * cache-random paths
2930 * _whTest_KeywrapDataWrapUsage - data wrap requires USAGE_WRAP on the KEK
3031 * _whTest_KeywrapKeyUnwrapUnderflow - undersized wrapped-key blobs must
3132 * return WH_ERROR_BADARGS, not underflow
7374#define WH_TEST_KW_NVM_FORGE_ID 0x63
7475#define WH_TEST_KW_NOWRAP_ID 0x64
7576#define WH_TEST_KW_META_ID 0x65
77+ #define WH_TEST_KW_RAND_FORGE_ID 0x66
7678
7779/* Cache a plain software KEK with wrap usage. It is an ordinary client key:
7880 * good enough for KeyWrap/KeyUnwrapAndExport, never for the trusted-KEK
@@ -98,14 +100,15 @@ static int _CacheSwKek(whClientContext* client, whKeyId* outKekId)
98100 * WH_NVM_FLAGS_TRUSTED). Prove that (a) a plain client-cached USAGE_WRAP key is
99101 * refused as their KEK, and that a client cannot forge a trusted KEK by
100102 * setting WH_NVM_FLAGS_TRUSTED itself through (b) the checked NVM add path, (c)
101- * the HKDF cache-import path, or (d) the key cache path -- the server strips
102- * the flag on each, so the key is still refused */
103+ * the HKDF cache-import path, (d) the key cache path, or (e) the cache-random
104+ * path -- the server strips the flag on each, so the key is still refused */
103105static int _whTest_KeywrapTrustedKekPolicy (whClientContext * client )
104106{
105107 int ret ;
106- whKeyId kekId = WH_KEYID_ERASED ;
107- whKeyId srcKeyId = WH_TEST_KW_SRC_ID ;
108- whKeyId forgeId = WH_TEST_KW_CACHE_FORGE_ID ;
108+ whKeyId kekId = WH_KEYID_ERASED ;
109+ whKeyId srcKeyId = WH_TEST_KW_SRC_ID ;
110+ whKeyId forgeId = WH_TEST_KW_CACHE_FORGE_ID ;
111+ whKeyId randForgeId = WH_TEST_KW_RAND_FORGE_ID ;
109112 uint8_t srcKey [WH_TEST_KW_KEYSIZE ];
110113 uint8_t label [WH_NVM_LABEL_LEN ] = "TrustedKek key" ;
111114 uint8_t wrappedKey [WH_TEST_KW_WRAPPED_KEYSIZE ];
@@ -265,6 +268,37 @@ static int _whTest_KeywrapTrustedKekPolicy(whClientContext* client)
265268 ret = WH_ERROR_ABORTED ;
266269 goto cleanup ;
267270 }
271+
272+ /* (e) Same forgery through the cache-random path, where the server picks
273+ * the key material. The evict must succeed too: an unstripped TRUSTED flag
274+ * freezes the slot against every client op, evict included */
275+ ret = wh_Client_KeyCacheRandom (
276+ client , WH_NVM_FLAGS_TRUSTED | WH_NVM_FLAGS_USAGE_WRAP , label ,
277+ (uint16_t )sizeof (label ), WH_TEST_KW_KEYSIZE , & randForgeId );
278+ if (ret != WH_ERROR_OK ) {
279+ WH_ERROR_PRINT ("trusted-kek: cache-random forged KEK failed %d\n" , ret );
280+ goto cleanup ;
281+ }
282+ wrappedKeySz = sizeof (wrappedKey );
283+ ret = wh_Client_KeyWrapExport (client , WC_CIPHER_AES_GCM , srcKeyId ,
284+ WH_KEYTYPE_CRYPTO , randForgeId , wrappedKey ,
285+ & wrappedKeySz );
286+ if (ret != WH_ERROR_ACCESS ) {
287+ WH_ERROR_PRINT ("trusted-kek: wrap-export with cache-random KEK "
288+ "expected ACCESS, got %d\n" ,
289+ ret );
290+ (void )wh_Client_KeyEvict (client , randForgeId );
291+ ret = WH_ERROR_ABORTED ;
292+ goto cleanup ;
293+ }
294+ ret = wh_Client_KeyEvict (client , randForgeId );
295+ if (ret != WH_ERROR_OK ) {
296+ WH_ERROR_PRINT ("trusted-kek: evict cache-random KEK expected OK, got "
297+ "%d\n" ,
298+ ret );
299+ ret = WH_ERROR_ABORTED ;
300+ goto cleanup ;
301+ }
268302 ret = WH_ERROR_OK ;
269303
270304cleanup :
0 commit comments