diff --git a/test/src/wh_test_client_crypto.c b/test/src/wh_test_client_crypto.c new file mode 100644 index 0000000..200891b --- /dev/null +++ b/test/src/wh_test_client_crypto.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfHSM. + * + * wolfHSM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfHSM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wolfHSM. If not, see . + */ + +#include +#include + +#include "wh_test_common.h" +#include "wh_test_client_crypto.h" +#include "wolfhsm/wh_client.h" +#include "wolfhsm/wh_client_crypto.h" +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_transport_mem.h" +#include "wolfhsm/wh_comm.h" +#include "wolfhsm/wh_server.h" + +#include "wolfssl/wolfcrypt/settings.h" +#include "wolfssl/wolfcrypt/rsa.h" +#include "wolfssl/wolfcrypt/ecc.h" +#include "wolfssl/wolfcrypt/aes.h" +#include "wolfssl/wolfcrypt/cmac.h" + +static int whTest_ClientCryptoRsa(whClientContext* client) +{ + int ret; + RsaKey key; + WC_RNG rng; + byte plaintext[] = "Test RSA encryption"; + byte ciphertext[256]; + byte decrypted[256]; + word32 outLen; + whKeyId keyId = WH_KEYID_ERASED; + + printf("Testing RSA operations...\n"); + + /* Initialize RNG */ + ret = wc_InitRng(&rng); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test invalid parameters */ + ret = wc_InitRsaKey_ex(NULL, NULL, INVALID_DEVID); + WH_TEST_ASSERT_RETURN(ret != 0); + + ret = wc_InitRsaKey_ex(&key, NULL, WH_DEV_ID_HSM); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test key generation with invalid parameters */ + ret = wc_MakeRsaKey(&key, 1024, WC_RSA_EXPONENT, NULL); + WH_TEST_ASSERT_RETURN(ret != 0); + + /* Test valid key generation */ + ret = wc_MakeRsaKey(&key, 2048, WC_RSA_EXPONENT, &rng); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test encryption/decryption with invalid parameters */ + outLen = sizeof(ciphertext); + ret = wc_RsaPublicEncrypt(NULL, sizeof(plaintext), ciphertext, outLen, &key, &rng); + WH_TEST_ASSERT_RETURN(ret != 0); + + ret = wc_RsaPublicEncrypt(plaintext, sizeof(plaintext), NULL, outLen, &key, &rng); + WH_TEST_ASSERT_RETURN(ret != 0); + + /* Test valid encryption/decryption */ + outLen = sizeof(ciphertext); + ret = wc_RsaPublicEncrypt(plaintext, sizeof(plaintext), ciphertext, outLen, &key, &rng); + WH_TEST_ASSERT_RETURN(ret >= 0); + if (ret > 0) { + word32 encLen = (word32)ret; + outLen = sizeof(decrypted); + ret = wc_RsaPrivateDecrypt(ciphertext, encLen, decrypted, outLen, &key); + WH_TEST_ASSERT_RETURN(ret >= 0); + } + WH_TEST_ASSERT_RETURN(memcmp(plaintext, decrypted, sizeof(plaintext)) == 0); + + /* Test key cache operations */ + ret = wh_Client_RsaMakeCacheKey(client, 2048, WC_RSA_EXPONENT, &keyId, + WH_NVM_FLAGS_NONE, 0, NULL); + WH_TEST_ASSERT_RETURN(ret == 0); + + ret = wh_Client_RsaSetKeyId(&key, keyId); + WH_TEST_ASSERT_RETURN(ret == 0); + + ret = wh_Client_KeyEvict(client, keyId); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Cleanup */ + wc_FreeRsaKey(&key); + wc_FreeRng(&rng); + + printf("RSA tests passed\n"); + return 0; +} + +static int whTest_ClientCryptoAes(whClientContext* client) +{ + int ret; + Aes aes; + WC_RNG rng; + byte key[32]; + byte iv[16]; + byte plaintext[] = "Test AES encryption"; + byte ciphertext[32]; + byte decrypted[32]; + + printf("Testing AES operations...\n"); + + /* Initialize RNG */ + ret = wc_InitRng(&rng); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Generate random key and IV */ + ret = wc_RNG_GenerateBlock(&rng, key, sizeof(key)); + WH_TEST_ASSERT_RETURN(ret == 0); + + ret = wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test invalid parameters */ + ret = wc_AesInit(NULL, NULL, INVALID_DEVID); + WH_TEST_ASSERT_RETURN(ret != 0); + + /* Test valid initialization */ + ret = wc_AesInit(&aes, NULL, INVALID_DEVID); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test key setting */ + ret = wc_AesSetKey(&aes, key, sizeof(key), iv, AES_ENCRYPTION); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test encryption */ + ret = wc_AesCbcEncrypt(&aes, ciphertext, plaintext, sizeof(plaintext)); + WH_TEST_ASSERT_RETURN(ret == 0); + + /* Test decryption */ + ret = wc_AesSetKey(&aes, key, sizeof(key), iv, AES_DECRYPTION); + WH_TEST_ASSERT_RETURN(ret == 0); + + ret = wc_AesCbcDecrypt(&aes, decrypted, ciphertext, sizeof(plaintext)); + WH_TEST_ASSERT_RETURN(ret == 0); + + WH_TEST_ASSERT_RETURN(memcmp(plaintext, decrypted, sizeof(plaintext)) == 0); + + /* Cleanup */ + wc_AesFree(&aes); + wc_FreeRng(&rng); + + printf("AES tests passed\n"); + return 0; +} + +int whTest_ClientCrypto(void) +{ + int ret; + whClientContext client = {0}; + whServerContext server = {0}; + static uint8_t req_buffer[4096]; + static uint8_t resp_buffer[4096]; + static whTransportMemConfig transportCfg = { + .req = req_buffer, + .req_size = sizeof(req_buffer), + .resp = resp_buffer, + .resp_size = sizeof(resp_buffer), + }; + static const whTransportClientCb transportClientCb = WH_TRANSPORT_MEM_CLIENT_CB; + static const whTransportServerCb transportServerCb = WH_TRANSPORT_MEM_SERVER_CB; + static whTransportMemClientContext transportClientCtx = {0}; + static whTransportMemServerContext transportServerCtx = {0}; + whClientConfig clientCfg = {0}; + whServerConfig serverCfg = {0}; + whServerCryptoContext cryptoCtx = { + .devId = WH_DEV_ID_HSM, + }; + whCommClientConfig commClientCfg = { + .transport_cb = &transportClientCb, + .transport_context = &transportClientCtx, + .transport_config = &transportCfg, + .client_id = 1, + }; + whCommServerConfig commServerCfg = { + .transport_cb = &transportServerCb, + .transport_context = &transportServerCtx, + .transport_config = &transportCfg, + .server_id = 1, + }; + clientCfg.comm = &commClientCfg; + serverCfg.comm_config = &commServerCfg; + serverCfg.crypto = &cryptoCtx; + + printf("Testing client crypto...\n"); + + /* Initialize server crypto */ + ret = wc_InitRng(cryptoCtx.rng); + if (ret != 0) { + WH_ERROR_PRINT("Server RNG init failed: %d\n", ret); + return ret; + } + + /* Initialize server */ + ret = wh_Server_Init(&server, &serverCfg); + if (ret != 0) { + WH_ERROR_PRINT("Server init failed: %d\n", ret); + wc_FreeRng(cryptoCtx.rng); + return ret; + } + + /* Initialize client */ + ret = wh_Client_Init(&client, &clientCfg); + if (ret != 0) { + WH_ERROR_PRINT("Client init failed: %d\n", ret); + return ret; + } + + /* Run crypto tests */ + ret = whTest_ClientCryptoRsa(&client); + if (ret != 0) { + WH_ERROR_PRINT("RSA tests failed: %d\n", ret); + goto cleanup; + } + + ret = whTest_ClientCryptoAes(&client); + if (ret != 0) { + WH_ERROR_PRINT("AES tests failed: %d\n", ret); + goto cleanup; + } + + printf("All crypto tests passed\n"); + +cleanup: + wh_Client_Cleanup(&client); + wh_Server_Cleanup(&server); + wc_FreeRng(cryptoCtx.rng); + return ret; +} diff --git a/test/wh_test_client_crypto.h b/test/wh_test_client_crypto.h new file mode 100644 index 0000000..3871eb4 --- /dev/null +++ b/test/wh_test_client_crypto.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfHSM. + * + * wolfHSM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfHSM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wolfHSM. If not, see . + */ + +#ifndef WOLFHSM_WH_TEST_CLIENT_CRYPTO_H_ +#define WOLFHSM_WH_TEST_CLIENT_CRYPTO_H_ + +#include "wh_test_common.h" + +int whTest_ClientCrypto(void); + +#endif /* WOLFHSM_WH_TEST_CLIENT_CRYPTO_H_ */