diff --git a/test-refactor/README.md b/test-refactor/README.md index 2be3a952e..4ea7e7278 100644 --- a/test-refactor/README.md +++ b/test-refactor/README.md @@ -82,6 +82,7 @@ Translated tests: | `wh_test_keystore_reqsize.c::whTest_KeystoreReqSize` | `misc/wh_test_keystore_reqsize.c::whTest_KeystoreReqSize` | Misc | | | `wh_test_cert.c::whTest_CertRamSim` | `server/wh_test_cert.c::whTest_CertVerify` | Server | remove ramsim coupling and migrate to server group | | `wh_test_crypto.c::whTest_Crypto` | `client-server/wh_test_crypto_{aes,cmac,curve25519,ecc,ed25519,kdf,keypolicy,mldsa,rng,rsa,sha}.c::whTest_Crypto_*` | Client | Split into per-algorithm suites; key revocation is gated by `WOLFHSM_CFG_TEST_ALLOW_PERSISTENT_NVM_ARTIFACTS` | +| `wh_test_crypto.c::whTest_CryptoKeyUsagePolicies` (AES CTR/ECB/GCM subset) | `client-server/wh_test_crypto_aes.c::whTest_CryptoAesKeyUsagePolicies` | Client | AES-CTR/ECB/GCM key usage enforcement (non-DMA and DMA variants) | | `wh_test_clientserver.c` (echo and server-info paths) | `client-server/wh_test_echo.c::whTest_Echo`, `client-server/wh_test_server_info.c::whTest_ServerInfo` | Client | pthread test ported, sequential test dropped | | `wh_test_wolfcrypt_test.c::whTest_WolfCryptTest` | `client-server/wh_test_wolfcrypt.c::whTest_WolfCryptTest` | Client | | | `wh_test_flash_ramsim.c::whTest_Flash_RamSim` | `posix/wh_test_flash_ramsim.c::{whTest_FlashWriteLock, whTest_FlashEraseProgramVerify, whTest_FlashUnitOps}` | POSIX port-specific (`whTestGroup_RunOne`) | remove ramsim coupling and migrate to server group | diff --git a/test-refactor/client-server/wh_test_crypto_aes.c b/test-refactor/client-server/wh_test_crypto_aes.c index 881fdcdaa..12a1e4d06 100644 --- a/test-refactor/client-server/wh_test_crypto_aes.c +++ b/test-refactor/client-server/wh_test_crypto_aes.c @@ -442,6 +442,580 @@ static int whTest_CryptoAesCbcStreaming(whClientContext* ctx) } #endif /* HAVE_AES_CBC */ +int whTest_CryptoAesKeyUsagePolicies(whClientContext* ctx) +{ + int ret = 0; + WC_RNG rng[1]; + uint8_t plaintext[AES_BLOCK_SIZE] = {0}; + uint8_t ciphertext[AES_BLOCK_SIZE] = {0}; + uint8_t key[32] = {0}; + uint32_t keyLen = sizeof(key); + whKeyId keyId = WH_KEYID_ERASED; + + ret = wc_InitRng_ex(rng, NULL, WH_DEV_ID); + if (ret != 0) { + WH_ERROR_PRINT("Failed to wc_InitRng_ex %d\n", ret); + return ret; + } + + ret = wc_RNG_GenerateBlock(rng, plaintext, sizeof(plaintext)); + if (ret == 0) + ret = wc_RNG_GenerateBlock(rng, key, sizeof(key)); + if (ret != 0) { + WH_ERROR_PRINT("Failed to generate random data: %d\n", ret); + goto done; + } + +#ifdef WOLFSSL_AES_COUNTER + /* AES-CTR: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrCipher[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"ctr-no-enc", strlen("ctr-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCtr(ctx, aes, 1, plaintext, + sizeof(plaintext), ctrCipher); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CTR enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-CTR: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrOut[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"ctr-no-dec", strlen("ctr-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCtr(ctx, aes, 0, ciphertext, + sizeof(ciphertext), ctrOut); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CTR dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* WOLFSSL_AES_COUNTER */ + +#ifdef HAVE_AES_ECB + /* AES-ECB: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t ecbCipher[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"ecb-no-enc", strlen("ecb-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesEcbEncrypt(aes, ecbCipher, plaintext, + sizeof(plaintext)); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-ECB enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-ECB: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t ecbOut[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"ecb-no-dec", strlen("ecb-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesEcbDecrypt(aes, ecbOut, ciphertext, + sizeof(ciphertext)); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-ECB dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AESGCM + /* AES-GCM: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmCipher[AES_BLOCK_SIZE] = {0}; + uint8_t gcmTag[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"gcm-no-enc", strlen("gcm-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesGcmEncrypt(aes, gcmCipher, plaintext, + sizeof(plaintext), gcmIv, + sizeof(gcmIv), gcmTag, sizeof(gcmTag), + NULL, 0); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-GCM enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-GCM: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmOut[AES_BLOCK_SIZE] = {0}; + uint8_t gcmTag[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"gcm-no-dec", strlen("gcm-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesGcmDecrypt(aes, gcmOut, ciphertext, + sizeof(ciphertext), gcmIv, + sizeof(gcmIv), gcmTag, sizeof(gcmTag), + NULL, 0); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-GCM dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* HAVE_AESGCM */ + +#ifdef WOLFHSM_CFG_DMA +#ifdef WOLFSSL_AES_COUNTER + /* AES-CTR DMA: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrCipher[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"dctr-no-enc", + strlen("dctr-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCtrDma(ctx, aes, 1, plaintext, + sizeof(plaintext), ctrCipher); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CTR DMA enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-CTR DMA: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrOut[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dctr-no-dec", + strlen("dctr-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCtrDma(ctx, aes, 0, ciphertext, + sizeof(ciphertext), ctrOut); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CTR DMA dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* WOLFSSL_AES_COUNTER */ + +#ifdef HAVE_AES_ECB + /* AES-ECB DMA: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t ecbCipher[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"decb-no-enc", + strlen("decb-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesEcbDma(ctx, aes, 1, plaintext, + sizeof(plaintext), ecbCipher); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-ECB DMA enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-ECB DMA: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t ecbOut[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"decb-no-dec", + strlen("decb-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesEcbDma(ctx, aes, 0, ciphertext, + sizeof(ciphertext), ecbOut); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-ECB DMA dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC + /* AES-CBC DMA: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t cbcCipher[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"dcbc-no-enc", + strlen("dcbc-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCbcDma(ctx, aes, 1, plaintext, + sizeof(plaintext), cbcCipher); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CBC DMA enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-CBC DMA: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t cbcOut[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dcbc-no-dec", + strlen("dcbc-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) + ret = wc_AesSetIV(aes, iv); + if (ret == 0) { + ret = wh_Client_AesCbcDma(ctx, aes, 0, ciphertext, + sizeof(ciphertext), cbcOut); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-CBC DMA dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* HAVE_AES_CBC */ + +#ifdef HAVE_AESGCM + /* AES-GCM DMA: encrypt without ENCRYPT flag */ + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmCipher[AES_BLOCK_SIZE] = {0}; + uint8_t gcmTag[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_NONE, + (uint8_t*)"dgcm-no-enc", + strlen("dgcm-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesGcmDma(ctx, aes, 1, plaintext, + sizeof(plaintext), gcmIv, + sizeof(gcmIv), NULL, 0, + NULL, gcmTag, sizeof(gcmTag), + gcmCipher); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-GCM DMA enc without ENCRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } + + /* AES-GCM DMA: decrypt without DECRYPT flag */ + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmOut[AES_BLOCK_SIZE] = {0}; + uint8_t gcmTag[AES_BLOCK_SIZE] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(ctx, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dgcm-no-dec", + strlen("dgcm-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesGcmDma(ctx, aes, 0, ciphertext, + sizeof(ciphertext), gcmIv, + sizeof(gcmIv), NULL, 0, + gcmTag, NULL, sizeof(gcmTag), + gcmOut); + if (ret == WH_ERROR_USAGE) + ret = 0; + else { + WH_ERROR_PRINT( + "AES-GCM DMA dec without DECRYPT flag: expected " + "WH_ERROR_USAGE, got %d\n", + ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(ctx, keyId); + } + } + if (ret != 0) { + goto done; + } +#endif /* HAVE_AESGCM */ +#endif /* WOLFHSM_CFG_DMA */ + +done: + wc_FreeRng(rng); + if (ret == 0) { + WH_TEST_PRINT("AES key usage policies DEVID=0x%X SUCCESS\n", WH_DEV_ID); + } + return ret; +} + int whTest_Crypto_Aes(whClientContext* ctx) { /* AES round-trips dispatch through the cryptocb, so run on every devId to diff --git a/test-refactor/wh_test_list.c b/test-refactor/wh_test_list.c index 0c4dfd4d0..3d1d2b50c 100644 --- a/test-refactor/wh_test_list.c +++ b/test-refactor/wh_test_list.c @@ -43,6 +43,7 @@ WH_TEST_DECL(whTest_CertVerify); WH_TEST_DECL(whTest_NvmOptional); WH_TEST_DECL(whTest_ClientCerts); WH_TEST_DECL(whTest_Crypto_Aes); +WH_TEST_DECL(whTest_CryptoAesKeyUsagePolicies); WH_TEST_DECL(whTest_Crypto_Cmac); WH_TEST_DECL(whTest_Crypto_Curve25519); WH_TEST_DECL(whTest_Crypto_Ecc); @@ -73,6 +74,7 @@ const size_t whTestsServerCount = sizeof(whTestsServer) / sizeof(whTestsServer[0 const whTestCase whTestsClient[] = { { "whTest_ClientCerts", whTest_ClientCerts }, { "whTest_Crypto_Aes", whTest_Crypto_Aes }, + { "whTest_CryptoAesKeyUsagePolicies", whTest_CryptoAesKeyUsagePolicies }, { "whTest_Crypto_Cmac", whTest_Crypto_Cmac }, { "whTest_Crypto_Curve25519", whTest_Crypto_Curve25519 }, { "whTest_Crypto_Ecc", whTest_Crypto_Ecc }, diff --git a/test/wh_test_crypto.c b/test/wh_test_crypto.c index da9434743..b78276981 100644 --- a/test/wh_test_crypto.c +++ b/test/wh_test_crypto.c @@ -13220,8 +13220,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) wh_Client_KeyEvict(client, keyId); } } - if (ret != 0) + if (ret != 0) { return ret; + } /* AES decrypt without DECRYPT flag */ WH_TEST_PRINT(" Testing AES CBC decrypt without DECRYPT flag...\n"); @@ -13294,9 +13295,574 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) } } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* HAVE_AES_CBC */ + +#ifdef WOLFSSL_AES_COUNTER + /* AES-CTR: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES CTR encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrCipher[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"ctr-no-enc", strlen("ctr-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCtr(client, aes, 1, plaintext, + sizeof(plaintext), ctrCipher); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-CTR: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES CTR decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrOut[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"ctr-no-dec", strlen("ctr-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCtr(client, aes, 0, ciphertext, + sizeof(ciphertext), ctrOut); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* WOLFSSL_AES_COUNTER */ + +#ifdef HAVE_AES_ECB + /* AES-ECB: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES ECB encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t ecbCipher[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"ecb-no-enc", strlen("ecb-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesEcbEncrypt(aes, ecbCipher, plaintext, + sizeof(plaintext)); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-ECB: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES ECB decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t ecbOut[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"ecb-no-dec", strlen("ecb-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesEcbDecrypt(aes, ecbOut, ciphertext, + sizeof(ciphertext)); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AESGCM + /* AES-GCM: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES GCM encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmCipher[16] = {0}; + uint8_t gcmTag[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"gcm-no-enc", strlen("gcm-no-enc"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesGcmEncrypt(aes, gcmCipher, plaintext, + sizeof(plaintext), gcmIv, + sizeof(gcmIv), gcmTag, sizeof(gcmTag), + NULL, 0); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-GCM: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES GCM decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmOut[16] = {0}; + uint8_t gcmTag[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"gcm-no-dec", strlen("gcm-no-dec"), + key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesGcmDecrypt(aes, gcmOut, ciphertext, + sizeof(ciphertext), gcmIv, + sizeof(gcmIv), gcmTag, sizeof(gcmTag), + NULL, 0); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* HAVE_AESGCM */ + +#ifdef WOLFHSM_CFG_DMA +#ifdef WOLFSSL_AES_COUNTER + /* AES-CTR DMA: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES CTR DMA encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrCipher[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"dctr-no-enc", + strlen("dctr-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCtrDma(client, aes, 1, plaintext, + sizeof(plaintext), ctrCipher); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-CTR DMA: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES CTR DMA decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t ctrOut[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dctr-no-dec", + strlen("dctr-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCtrDma(client, aes, 0, ciphertext, + sizeof(ciphertext), ctrOut); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* WOLFSSL_AES_COUNTER */ + +#ifdef HAVE_AES_ECB + /* AES-ECB DMA: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES ECB DMA encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t ecbCipher[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"decb-no-enc", + strlen("decb-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesEcbDma(client, aes, 1, plaintext, + sizeof(plaintext), ecbCipher); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-ECB DMA: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES ECB DMA decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t ecbOut[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"decb-no-dec", + strlen("decb-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesEcbDma(client, aes, 0, ciphertext, + sizeof(ciphertext), ecbOut); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* HAVE_AES_ECB */ + +#ifdef HAVE_AES_CBC + /* AES-CBC DMA: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES CBC DMA encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t cbcCipher[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"dcbc-no-enc", + strlen("dcbc-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCbcDma(client, aes, 1, plaintext, + sizeof(plaintext), cbcCipher); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-CBC DMA: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES CBC DMA decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t iv[AES_BLOCK_SIZE] = {0}; + uint8_t cbcOut[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dcbc-no-dec", + strlen("dcbc-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wc_AesSetIV(aes, iv); + } + if (ret == 0) { + ret = wh_Client_AesCbcDma(client, aes, 0, ciphertext, + sizeof(ciphertext), cbcOut); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* HAVE_AES_CBC */ + +#ifdef HAVE_AESGCM + /* AES-GCM DMA: encrypt without ENCRYPT flag */ + WH_TEST_PRINT(" Testing AES GCM DMA encrypt without ENCRYPT flag...\n"); + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmCipher[16] = {0}; + uint8_t gcmTag[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_NONE, + (uint8_t*)"dgcm-no-enc", + strlen("dgcm-no-enc"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + ret = wh_Client_AesGcmDma(client, aes, 1, plaintext, + sizeof(plaintext), gcmIv, + sizeof(gcmIv), NULL, 0, + NULL, gcmTag, sizeof(gcmTag), + gcmCipher); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied encryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } + + /* AES-GCM DMA: decrypt without DECRYPT flag */ + WH_TEST_PRINT(" Testing AES GCM DMA decrypt without DECRYPT flag...\n"); + { + Aes aes[1]; + uint8_t gcmIv[12] = {0}; + uint8_t gcmOut[16] = {0}; + uint8_t gcmTag[16] = {0}; + + keyId = WH_KEYID_ERASED; + ret = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, + (uint8_t*)"dgcm-no-dec", + strlen("dgcm-no-dec"), key, keyLen, &keyId); + if (ret == 0) { + ret = wc_AesInit(aes, NULL, WH_DEV_ID_DMA); + if (ret == 0) { + ret = wh_Client_AesSetKeyId(aes, keyId); + if (ret == 0) { + /* dec_tag must be non-NULL for decrypt direction */ + ret = wh_Client_AesGcmDma(client, aes, 0, ciphertext, + sizeof(ciphertext), gcmIv, + sizeof(gcmIv), NULL, 0, + gcmTag, NULL, sizeof(gcmTag), + gcmOut); + if (ret == WH_ERROR_USAGE) { + WH_TEST_PRINT(" PASS: Correctly denied decryption\n"); + ret = 0; + } + else { + WH_ERROR_PRINT( + " FAIL: Expected WH_ERROR_USAGE, got %d\n", ret); + ret = WH_ERROR_ABORTED; + } + } + wc_AesFree(aes); + } + wh_Client_KeyEvict(client, keyId); + } + } + if (ret != 0) { + return ret; + } +#endif /* HAVE_AESGCM */ +#endif /* WOLFHSM_CFG_DMA */ + #endif /* !NO_AES */ #ifdef HAVE_ECC @@ -13347,8 +13913,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) wh_Client_KeyEvict(client, keyId); } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* HAVE_ECC_SIGN */ #ifdef HAVE_ECC_DHE @@ -13418,8 +13985,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) wh_Client_KeyEvict(client, keyId); } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* HAVE_ECC_DHE */ #endif /* HAVE_ECC */ @@ -13462,8 +14030,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) } } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* HAVE_HKDF */ #if defined(WOLFSSL_CMAC) && !defined(NO_AES) && defined(WOLFSSL_AES_DIRECT) @@ -13512,8 +14081,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) wh_Client_KeyEvict(client, keyId); } } - if (ret != 0) + if (ret != 0) { return ret; + } /* CMAC Verify without VERIFY flag */ WH_TEST_PRINT(" Testing CMAC verify without VERIFY flag...\n"); @@ -13564,8 +14134,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) wh_Client_KeyEvict(client, keyId); } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* WOLFSSL_CMAC && !NO_AES && WOLFSSL_AES_DIRECT */ #ifdef WOLFHSM_CFG_KEYWRAP @@ -13614,8 +14185,9 @@ int whTest_CryptoKeyUsagePolicies(whClientContext* client, WC_RNG* rng) } } } - if (ret != 0) + if (ret != 0) { return ret; + } #endif /* WOLFHSM_CFG_KEYWRAP */ WH_TEST_PRINT("Key Usage Policy Tests PASSED\n");