From 59a17dd598c8936b6fb331ae28a5576d8760efb1 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 14 Apr 2026 09:53:31 +1000 Subject: [PATCH] Unit testing: Add Monte Carlo testing to ciphers Monte Carlo testing is randomized test data. These new tests have random keys, IVs, nonce, etc and random data to encrypt. 100 sets of random test data are encrypted and decrypted with a check to ensure the input to encrypt is the same as the output of decrypt. Tags are generated and checked in the calls to encrypt and decrypt. --- tests/api/test_aes.c | 454 +++++++++++++++++++++++++++++ tests/api/test_aes.h | 15 +- tests/api/test_arc4.c | 61 ++++ tests/api/test_arc4.h | 8 +- tests/api/test_camellia.c | 67 +++++ tests/api/test_camellia.h | 4 +- tests/api/test_chacha.c | 61 ++++ tests/api/test_chacha.h | 10 +- tests/api/test_chacha20_poly1305.c | 57 ++++ tests/api/test_chacha20_poly1305.h | 8 +- tests/api/test_des3.c | 66 +++++ tests/api/test_des3.h | 4 +- tests/api/test_rc2.c | 58 ++++ tests/api/test_rc2.h | 4 +- tests/api/test_sm4.c | 248 ++++++++++++++++ tests/api/test_sm4.h | 22 +- 16 files changed, 1126 insertions(+), 21 deletions(-) diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index 5cf382de6ff..1b2f21ee35f 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -6297,3 +6297,457 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void) #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_AES_SETKEY && !NO_AES && HAVE_AESGCM */ + +/******************************************************************************* + * Monte Carlo tests for AES modes + ******************************************************************************/ + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_AES_MAX_DATA_SZ 1024 + +/* Monte Carlo test for AES-CBC: random key, IV, and plaintext each iteration */ +int test_wc_AesCbc_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes enc, dec; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; + byte iv[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + /* Length 1..1024, rounded up to AES block size */ + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + plainLen = (plainLen + WC_AES_BLOCK_SIZE - 1) & + ~((word32)WC_AES_BLOCK_SIZE - 1); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_AesSetKey(&enc, key, keyLen, iv, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesCbcEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_AesSetKey(&dec, key, keyLen, iv, AES_DECRYPTION), 0); + ExpectIntEQ(wc_AesCbcDecrypt(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&enc); + wc_AesFree(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} + +/* Monte Carlo test for AES-CTR: random key, IV, and plaintext each iteration */ +int test_wc_AesCtr_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes enc, dec; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; + byte iv[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + /* CTR mode: decrypt is the same operation as encrypt */ + ExpectIntEQ(wc_AesSetKey(&enc, key, keyLen, iv, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesCtrEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_AesSetKey(&dec, key, keyLen, iv, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesCtrEncrypt(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&enc); + wc_AesFree(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} + +/* Monte Carlo test for AES-GCM: random key, nonce, and plaintext each + * iteration */ +int test_wc_AesGcm_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AESGCM) && defined(HAVE_AES_DECRYPT) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes aes; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; + byte nonce[GCM_NONCE_MID_SZ]; + byte tag[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&aes, 0, sizeof(aes)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_AesGcmSetKey(&aes, key, keyLen), 0); + ExpectIntEQ(wc_AesGcmEncrypt(&aes, cipher, plain, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectIntEQ(wc_AesGcmDecrypt(&aes, decrypted, cipher, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&aes); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} + +/* Monte Carlo test for AES-CCM: random key, nonce, and plaintext each + * iteration */ +int test_wc_AesCcm_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(HAVE_AESCCM) && defined(HAVE_AES_DECRYPT) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes aes; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; +#if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS_VERSION) || \ + (HAVE_FIPS_VERSION > 2)) + byte nonce[CCM_NONCE_MAX_SZ]; +#else + byte nonce[13]; +#endif + byte tag[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&aes, 0, sizeof(aes)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&aes, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_AesCcmSetKey(&aes, key, keyLen), 0); + ExpectIntEQ(wc_AesCcmEncrypt(&aes, cipher, plain, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectIntEQ(wc_AesCcmDecrypt(&aes, decrypted, cipher, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&aes); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} + +/* Monte Carlo test for AES-CFB: random key, IV, and plaintext each + * iteration */ +int test_wc_AesCfb_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(WOLFSSL_AES_CFB) && defined(HAVE_AES_DECRYPT) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes enc, dec; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; + byte iv[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_AesSetKey(&enc, key, keyLen, NULL, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesSetIV(&enc, iv), 0); + ExpectIntEQ(wc_AesCfbEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_AesSetKey(&dec, key, keyLen, NULL, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesSetIV(&dec, iv), 0); + ExpectIntEQ(wc_AesCfbDecrypt(&dec, decrypted, cipher, plainLen), 0); + if (XMEMCMP(decrypted, plain, plainLen) != 0) { + PRINT_DATA("Key", key, keyLen); + PRINT_DATA("IV", iv, sizeof(iv)); + PRINT_DATA("Plain", plain, plainLen); + PRINT_DATA("Decrypted", decrypted, plainLen); + } + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&enc); + wc_AesFree(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} + +/* Monte Carlo test for AES-OFB: random key, IV, and plaintext each + * iteration */ +int test_wc_AesOfb_MonteCarlo(void) +{ + EXPECT_DECLS; +#if !defined(NO_AES) && defined(WOLFSSL_AES_OFB) && defined(HAVE_AES_DECRYPT) + static const word32 keySizes[] = { +#ifdef WOLFSSL_AES_128 + 16, +#endif +#ifdef WOLFSSL_AES_192 + 24, +#endif +#ifdef WOLFSSL_AES_256 + 32, +#endif + }; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + Aes enc, dec; + WC_RNG rng; + byte key[AES_256_KEY_SIZE]; + byte iv[WC_AES_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_AES_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_AES_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_AesInit(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_AesInit(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_AES_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_AesSetKey(&enc, key, keyLen, NULL, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesSetIV(&enc, iv), 0); + ExpectIntEQ(wc_AesOfbEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_AesSetKey(&dec, key, keyLen, NULL, AES_ENCRYPTION), 0); + ExpectIntEQ(wc_AesSetIV(&dec, iv), 0); + ExpectIntEQ(wc_AesOfbDecrypt(&dec, decrypted, cipher, plainLen), 0); + if (XMEMCMP(decrypted, plain, plainLen) != 0) { + PRINT_DATA("Key", key, keyLen); + PRINT_DATA("IV", iv, sizeof(iv)); + PRINT_DATA("Plain", plain, plainLen); + PRINT_DATA("Decrypted", decrypted, plainLen); + } + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_AesFree(&enc); + wc_AesFree(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_aes.h b/tests/api/test_aes.h index 671b7e51ca9..e70cbc195dc 100644 --- a/tests/api/test_aes.h +++ b/tests/api/test_aes.h @@ -55,6 +55,13 @@ int test_wc_AesEaxStream(void); int test_wc_AesSivEncryptDecrypt(void); #endif +int test_wc_AesCbc_MonteCarlo(void); +int test_wc_AesCtr_MonteCarlo(void); +int test_wc_AesGcm_MonteCarlo(void); +int test_wc_AesCcm_MonteCarlo(void); +int test_wc_AesCfb_MonteCarlo(void); +int test_wc_AesOfb_MonteCarlo(void); + int test_wc_GmacSetKey(void); int test_wc_GmacUpdate(void); #if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_AES_SETKEY) && \ @@ -91,7 +98,13 @@ int test_wc_CryptoCb_AesGcm_EncryptDecrypt(void); TEST_DECL_GROUP("aes", test_wc_AesCcmEncryptDecrypt), \ TEST_DECL_GROUP("aes", test_wc_AesXtsSetKey), \ TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt_Sizes), \ - TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt) \ + TEST_DECL_GROUP("aes", test_wc_AesXtsEncryptDecrypt), \ + TEST_DECL_GROUP("aes", test_wc_AesCbc_MonteCarlo), \ + TEST_DECL_GROUP("aes", test_wc_AesCtr_MonteCarlo), \ + TEST_DECL_GROUP("aes", test_wc_AesGcm_MonteCarlo), \ + TEST_DECL_GROUP("aes", test_wc_AesCcm_MonteCarlo), \ + TEST_DECL_GROUP("aes", test_wc_AesCfb_MonteCarlo), \ + TEST_DECL_GROUP("aes", test_wc_AesOfb_MonteCarlo) \ TEST_CRYPTOCB_AES_SETKEY_DECL #if defined(WOLFSSL_AES_EAX) && defined(WOLFSSL_AES_256) && \ diff --git a/tests/api/test_arc4.c b/tests/api/test_arc4.c index 512b1880a56..11bd20d671f 100644 --- a/tests/api/test_arc4.c +++ b/tests/api/test_arc4.c @@ -104,3 +104,64 @@ int test_wc_Arc4Process(void) } /* END test_wc_Arc4Process */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_ARC4_MAX_DATA_SZ 1024 +#define MC_ARC4_KEY_SZ 16 /* fixed 128-bit key */ + +/* Monte Carlo test for ARC4: random key and plaintext each iteration */ +int test_wc_Arc4_MonteCarlo(void) +{ + EXPECT_DECLS; +#ifndef NO_RC4 + Arc4 enc, dec; + WC_RNG rng; + byte key[MC_ARC4_KEY_SZ]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_ARC4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_ARC4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_ARC4_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_ARC4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_ARC4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_ARC4_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Arc4Init(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Arc4Init(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_ARC4_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Arc4SetKey(&enc, key, sizeof(key)), 0); + ExpectIntEQ(wc_Arc4SetKey(&dec, key, sizeof(key)), 0); + ExpectIntEQ(wc_Arc4Process(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Arc4Process(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Arc4Free(&enc); + wc_Arc4Free(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_arc4.h b/tests/api/test_arc4.h index bd53f666538..f79104d9c6e 100644 --- a/tests/api/test_arc4.h +++ b/tests/api/test_arc4.h @@ -26,9 +26,11 @@ int test_wc_Arc4SetKey(void); int test_wc_Arc4Process(void); +int test_wc_Arc4_MonteCarlo(void); -#define TEST_ARC4_DECLS \ - TEST_DECL_GROUP("arc4", test_wc_Arc4SetKey), \ - TEST_DECL_GROUP("arc4", test_wc_Arc4Process) +#define TEST_ARC4_DECLS \ + TEST_DECL_GROUP("arc4", test_wc_Arc4SetKey), \ + TEST_DECL_GROUP("arc4", test_wc_Arc4Process), \ + TEST_DECL_GROUP("arc4", test_wc_Arc4_MonteCarlo) #endif /* WOLFCRYPT_TEST_ARC4_H */ diff --git a/tests/api/test_camellia.c b/tests/api/test_camellia.c index cf557d50bd9..4bb7408f16f 100644 --- a/tests/api/test_camellia.c +++ b/tests/api/test_camellia.c @@ -214,3 +214,70 @@ int test_wc_CamelliaCbcEncryptDecrypt(void) return EXPECT_RESULT(); } /* END test_wc_CamelliaCbcEncryptDecrypt */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_CAMELLIA_MAX_DATA_SZ 1024 + +/* Monte Carlo test for Camellia-CBC: random key, IV, and plaintext each + * iteration */ +int test_wc_CamelliaCbc_MonteCarlo(void) +{ + EXPECT_DECLS; +#ifdef HAVE_CAMELLIA + static const word32 keySizes[] = {16, 24, 32}; + int numKeySizes = (int)(sizeof(keySizes) / sizeof(keySizes[0])); + wc_Camellia camellia; + WC_RNG rng; + byte key[32]; + byte iv[WC_CAMELLIA_BLOCK_SIZE]; + word32 plainLen = 0, keyLen; + int i; + WC_DECLARE_VAR(plain, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_CAMELLIA_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&camellia, 0, sizeof(camellia)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + keyLen = keySizes[i % numKeySizes]; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + /* Length 1..1024, rounded up to Camellia block size */ + plainLen = (plainLen % MC_CAMELLIA_MAX_DATA_SZ) + 1; + plainLen = (plainLen + WC_CAMELLIA_BLOCK_SIZE - 1) & + ~((word32)WC_CAMELLIA_BLOCK_SIZE - 1); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_CamelliaSetKey(&camellia, key, keyLen, iv), 0); + ExpectIntEQ(wc_CamelliaCbcEncrypt(&camellia, cipher, plain, + plainLen), 0); + /* Reset IV by calling SetKey again before decrypt */ + ExpectIntEQ(wc_CamelliaSetKey(&camellia, key, keyLen, iv), 0); + ExpectIntEQ(wc_CamelliaCbcDecrypt(&camellia, decrypted, cipher, + plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_camellia.h b/tests/api/test_camellia.h index 77d063a3390..f978bb0a2b9 100644 --- a/tests/api/test_camellia.h +++ b/tests/api/test_camellia.h @@ -28,11 +28,13 @@ int test_wc_CamelliaSetKey(void); int test_wc_CamelliaSetIV(void); int test_wc_CamelliaEncryptDecryptDirect(void); int test_wc_CamelliaCbcEncryptDecrypt(void); +int test_wc_CamelliaCbc_MonteCarlo(void); #define TEST_CAMELLIA_DECLS \ TEST_DECL_GROUP("camellia", test_wc_CamelliaSetKey), \ TEST_DECL_GROUP("camellia", test_wc_CamelliaSetIV), \ TEST_DECL_GROUP("camellia", test_wc_CamelliaEncryptDecryptDirect), \ - TEST_DECL_GROUP("camellia", test_wc_CamelliaCbcEncryptDecrypt) + TEST_DECL_GROUP("camellia", test_wc_CamelliaCbcEncryptDecrypt), \ + TEST_DECL_GROUP("camellia", test_wc_CamelliaCbc_MonteCarlo) #endif /* WOLFCRYPT_TEST_CAMELLIA_H */ diff --git a/tests/api/test_chacha.c b/tests/api/test_chacha.c index 6b79867876c..974386a4853 100644 --- a/tests/api/test_chacha.c +++ b/tests/api/test_chacha.c @@ -372,3 +372,64 @@ int test_wc_Chacha_Process_Chunking(void) } /* END test_wc_Chacha_Process */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_CHACHA_MAX_DATA_SZ 1024 + +/* Monte Carlo test for ChaCha20: random key, IV, and plaintext each + * iteration */ +int test_wc_Chacha_MonteCarlo(void) +{ + EXPECT_DECLS; +#ifdef HAVE_CHACHA + ChaCha enc, dec; + WC_RNG rng; + byte key[CHACHA_MAX_KEY_SZ]; + byte nonce[CHACHA_IV_BYTES]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_CHACHA_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_CHACHA_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_CHACHA_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_CHACHA_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_CHACHA_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_CHACHA_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_CHACHA_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Chacha_SetKey(&enc, key, sizeof(key)), 0); + ExpectIntEQ(wc_Chacha_SetKey(&dec, key, sizeof(key)), 0); + ExpectIntEQ(wc_Chacha_SetIV(&enc, nonce, 0), 0); + ExpectIntEQ(wc_Chacha_SetIV(&dec, nonce, 0), 0); + ExpectIntEQ(wc_Chacha_Process(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Chacha_Process(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_chacha.h b/tests/api/test_chacha.h index ba80accc141..4e418f55f5d 100644 --- a/tests/api/test_chacha.h +++ b/tests/api/test_chacha.h @@ -27,10 +27,12 @@ int test_wc_Chacha_SetKey(void); int test_wc_Chacha_Process(void); int test_wc_Chacha_Process_Chunking(void); +int test_wc_Chacha_MonteCarlo(void); -#define TEST_CHACHA_DECLS \ - TEST_DECL_GROUP("chacha", test_wc_Chacha_SetKey), \ - TEST_DECL_GROUP("chacha", test_wc_Chacha_Process), \ - TEST_DECL_GROUP("chacha", test_wc_Chacha_Process_Chunking) +#define TEST_CHACHA_DECLS \ + TEST_DECL_GROUP("chacha", test_wc_Chacha_SetKey), \ + TEST_DECL_GROUP("chacha", test_wc_Chacha_Process), \ + TEST_DECL_GROUP("chacha", test_wc_Chacha_Process_Chunking), \ + TEST_DECL_GROUP("chacha", test_wc_Chacha_MonteCarlo) #endif /* WOLFCRYPT_TEST_CHACHA_H */ diff --git a/tests/api/test_chacha20_poly1305.c b/tests/api/test_chacha20_poly1305.c index c3d37711452..e3f57adbe11 100644 --- a/tests/api/test_chacha20_poly1305.c +++ b/tests/api/test_chacha20_poly1305.c @@ -283,3 +283,60 @@ int test_wc_XChaCha20Poly1305_aead(void) #endif return EXPECT_RESULT(); } /* END test_wc_XChaCha20Poly1305_aead */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_CHACHA20P1305_MAX_SZ 1024 + +/* Monte Carlo test for ChaCha20-Poly1305: random key, nonce, and plaintext + * each iteration */ +int test_wc_ChaCha20Poly1305_MonteCarlo(void) +{ + EXPECT_DECLS; +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + WC_RNG rng; + byte key[CHACHA20_POLY1305_AEAD_KEYSIZE]; + byte nonce[CHACHA20_POLY1305_AEAD_IV_SIZE]; + byte tag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_CHACHA20P1305_MAX_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_CHACHA20P1305_MAX_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_CHACHA20P1305_MAX_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_CHACHA20P1305_MAX_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_CHACHA20P1305_MAX_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_CHACHA20P1305_MAX_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_CHACHA20P1305_MAX_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_ChaCha20Poly1305_Encrypt(key, nonce, NULL, 0, + plain, plainLen, cipher, tag), 0); + ExpectIntEQ(wc_ChaCha20Poly1305_Decrypt(key, nonce, NULL, 0, + cipher, plainLen, tag, decrypted), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_chacha20_poly1305.h b/tests/api/test_chacha20_poly1305.h index 4bcf47f93c1..88b924fadca 100644 --- a/tests/api/test_chacha20_poly1305.h +++ b/tests/api/test_chacha20_poly1305.h @@ -26,9 +26,11 @@ int test_wc_ChaCha20Poly1305_aead(void); int test_wc_XChaCha20Poly1305_aead(void); +int test_wc_ChaCha20Poly1305_MonteCarlo(void); -#define TEST_CHACHA20_POLY1305_DECLS \ - TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_aead), \ - TEST_DECL_GROUP("xchacha20-poly1305", test_wc_XChaCha20Poly1305_aead) +#define TEST_CHACHA20_POLY1305_DECLS \ + TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_aead), \ + TEST_DECL_GROUP("xchacha20-poly1305", test_wc_XChaCha20Poly1305_aead), \ + TEST_DECL_GROUP("chacha20-poly1305", test_wc_ChaCha20Poly1305_MonteCarlo) #endif /* WOLFCRYPT_TEST_CHACHA20_POLY1305_H */ diff --git a/tests/api/test_des3.c b/tests/api/test_des3.c index 541a1089423..f01a58cfe01 100644 --- a/tests/api/test_des3.c +++ b/tests/api/test_des3.c @@ -221,3 +221,69 @@ int test_wc_Des3_EcbEncrypt(void) return EXPECT_RESULT(); } /* END test_wc_Des3_EcbEncrypt */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_DES3_MAX_DATA_SZ 1024 + +/* Monte Carlo test for 3DES-CBC: random key, IV, and plaintext each + * iteration */ +int test_wc_Des3Cbc_MonteCarlo(void) +{ + EXPECT_DECLS; +#ifndef NO_DES3 + Des3 enc, dec; + WC_RNG rng; + byte key[DES3_KEYLEN]; + byte iv[DES_IVLEN]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_DES3_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_DES3_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_DES3_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_DES3_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_DES3_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_DES3_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Des3Init(&enc, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_Des3Init(&dec, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + /* Length 1..1024, rounded up to DES block size */ + plainLen = (plainLen % MC_DES3_MAX_DATA_SZ) + 1; + plainLen = (plainLen + DES_BLOCK_SIZE - 1) & + ~((word32)DES_BLOCK_SIZE - 1); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Des3_SetKey(&enc, key, iv, DES_ENCRYPTION), 0); + ExpectIntEQ(wc_Des3_CbcEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Des3_SetKey(&dec, key, iv, DES_DECRYPTION), 0); + ExpectIntEQ(wc_Des3_CbcDecrypt(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Des3Free(&enc); + wc_Des3Free(&dec); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_des3.h b/tests/api/test_des3.h index b48366a2969..9f530f7e292 100644 --- a/tests/api/test_des3.h +++ b/tests/api/test_des3.h @@ -28,11 +28,13 @@ int test_wc_Des3_SetIV(void); int test_wc_Des3_SetKey(void); int test_wc_Des3_CbcEncryptDecrypt(void); int test_wc_Des3_EcbEncrypt(void); +int test_wc_Des3Cbc_MonteCarlo(void); #define TEST_DES3_DECLS \ TEST_DECL_GROUP("des3", test_wc_Des3_SetIV), \ TEST_DECL_GROUP("des3", test_wc_Des3_SetKey), \ TEST_DECL_GROUP("des3", test_wc_Des3_CbcEncryptDecrypt), \ - TEST_DECL_GROUP("des3", test_wc_Des3_CbcEncryptDecrypt) + TEST_DECL_GROUP("des3", test_wc_Des3_EcbEncrypt), \ + TEST_DECL_GROUP("des3", test_wc_Des3Cbc_MonteCarlo) #endif /* WOLFCRYPT_TEST_DES3_H */ diff --git a/tests/api/test_rc2.c b/tests/api/test_rc2.c index 5b5089a2e0b..495975fa7a4 100644 --- a/tests/api/test_rc2.c +++ b/tests/api/test_rc2.c @@ -29,6 +29,7 @@ #endif #include +#include #include #include #include @@ -220,3 +221,60 @@ int test_wc_Rc2CbcEncryptDecrypt(void) return EXPECT_RESULT(); } /* END test_wc_Rc2CbcEncryptDecrypt */ + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_RC2_MAX_DATA_SZ 1024 + +int test_wc_Rc2Cbc_MonteCarlo(void) +{ + EXPECT_DECLS; +#ifdef WC_RC2 + Rc2 enc, dec; + WC_RNG rng; + byte key[RC2_MAX_KEY_SIZE]; + byte iv[RC2_BLOCK_SIZE]; + word32 plainLen = 0; + int effectiveBits; + int i; + WC_DECLARE_VAR(plain, byte, MC_RC2_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_RC2_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_RC2_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(plain, byte, MC_RC2_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_RC2_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_RC2_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + XMEMSET(&enc, 0, sizeof(enc)); + XMEMSET(&dec, 0, sizeof(dec)); + XMEMSET(&rng, 0, sizeof(rng)); + ExpectIntEQ(wc_InitRng(&rng), 0); + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + word32 keyLen = 0; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&keyLen, sizeof(keyLen)), + 0); + keyLen = (keyLen % (RC2_MAX_KEY_SIZE - 1)) + 1; + effectiveBits = (int)(keyLen * 8); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, keyLen), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_RC2_MAX_DATA_SZ) + 1; + plainLen = (plainLen + RC2_BLOCK_SIZE - 1) & + ~((word32)RC2_BLOCK_SIZE - 1); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + ExpectIntEQ(wc_Rc2SetKey(&enc, key, keyLen, iv, effectiveBits), 0); + ExpectIntEQ(wc_Rc2CbcEncrypt(&enc, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Rc2SetKey(&dec, key, keyLen, iv, effectiveBits), 0); + ExpectIntEQ(wc_Rc2CbcDecrypt(&dec, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); +#endif + return EXPECT_RESULT(); +} diff --git a/tests/api/test_rc2.h b/tests/api/test_rc2.h index f4cda804339..124adbbc2e6 100644 --- a/tests/api/test_rc2.h +++ b/tests/api/test_rc2.h @@ -28,11 +28,13 @@ int test_wc_Rc2SetKey(void); int test_wc_Rc2SetIV(void); int test_wc_Rc2EcbEncryptDecrypt(void); int test_wc_Rc2CbcEncryptDecrypt(void); +int test_wc_Rc2Cbc_MonteCarlo(void); #define TEST_RC2_DECLS \ TEST_DECL_GROUP("rc2", test_wc_Rc2SetKey), \ TEST_DECL_GROUP("rc2", test_wc_Rc2SetIV), \ TEST_DECL_GROUP("rc2", test_wc_Rc2EcbEncryptDecrypt), \ - TEST_DECL_GROUP("rc2", test_wc_Rc2CbcEncryptDecrypt) + TEST_DECL_GROUP("rc2", test_wc_Rc2CbcEncryptDecrypt), \ + TEST_DECL_GROUP("rc2", test_wc_Rc2Cbc_MonteCarlo) #endif /* WOLFCRYPT_TEST_RC2_H */ diff --git a/tests/api/test_sm4.c b/tests/api/test_sm4.c index b17b8f5afff..d826d2ac47b 100644 --- a/tests/api/test_sm4.c +++ b/tests/api/test_sm4.c @@ -785,3 +785,251 @@ int test_wc_Sm4Ccm(void) return res; } /* END test_wc_Sm4Ccm */ + +#include + +#define MC_CIPHER_TEST_COUNT 100 +#define MC_SM4_MAX_DATA_SZ 1024 + +/* Monte Carlo test for SM4-CBC: random key, IV, and plaintext each + * iteration */ +int test_wc_Sm4Cbc_MonteCarlo(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CBC + EXPECT_DECLS; + wc_Sm4 sm4; + WC_RNG rng; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_IV_SIZE]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&sm4, 0, sizeof(sm4)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + /* Length 1..1024, rounded up to SM4 block size */ + plainLen = (plainLen % MC_SM4_MAX_DATA_SZ) + 1; + plainLen = (plainLen + SM4_BLOCK_SIZE - 1) & + ~((word32)SM4_BLOCK_SIZE - 1); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcEncrypt(&sm4, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CbcDecrypt(&sm4, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Sm4Free(&sm4); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* Monte Carlo test for SM4-CTR: random key, IV, and plaintext each + * iteration */ +int test_wc_Sm4Ctr_MonteCarlo(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CTR + EXPECT_DECLS; + wc_Sm4 sm4; + WC_RNG rng; + byte key[SM4_KEY_SIZE]; + byte iv[SM4_IV_SIZE]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&sm4, 0, sizeof(sm4)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_SM4_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + /* CTR mode: decrypt by re-encrypting with same key/IV */ + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, cipher, plain, plainLen), 0); + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4SetIV(&sm4, iv), 0); + ExpectIntEQ(wc_Sm4CtrEncrypt(&sm4, decrypted, cipher, plainLen), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Sm4Free(&sm4); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* Monte Carlo test for SM4-GCM: random key, nonce, and plaintext each + * iteration */ +int test_wc_Sm4Gcm_MonteCarlo(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_GCM + EXPECT_DECLS; + wc_Sm4 sm4; + WC_RNG rng; + byte key[SM4_KEY_SIZE]; + byte nonce[GCM_NONCE_MID_SZ]; + byte tag[SM4_BLOCK_SIZE]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&sm4, 0, sizeof(sm4)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_SM4_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Sm4GcmSetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4GcmEncrypt(&sm4, cipher, plain, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectIntEQ(wc_Sm4GcmDecrypt(&sm4, decrypted, cipher, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Sm4Free(&sm4); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); + + res = EXPECT_RESULT(); +#endif + return res; +} + +/* Monte Carlo test for SM4-CCM: random key, nonce, and plaintext each + * iteration */ +int test_wc_Sm4Ccm_MonteCarlo(void) +{ + int res = TEST_SKIPPED; +#ifdef WOLFSSL_SM4_CCM + EXPECT_DECLS; + wc_Sm4 sm4; + WC_RNG rng; + byte key[SM4_KEY_SIZE]; + byte nonce[CCM_NONCE_MAX_SZ]; + byte tag[SM4_BLOCK_SIZE]; + word32 plainLen = 0; + int i; + WC_DECLARE_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_DECLARE_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); + + WC_ALLOC_VAR(plain, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(cipher, byte, MC_SM4_MAX_DATA_SZ, NULL); + WC_ALLOC_VAR(decrypted, byte, MC_SM4_MAX_DATA_SZ, NULL); +#ifdef WC_DECLARE_VAR_IS_HEAP_ALLOC + ExpectNotNull(plain); + ExpectNotNull(cipher); + ExpectNotNull(decrypted); +#endif + + XMEMSET(&sm4, 0, sizeof(sm4)); + XMEMSET(&rng, 0, sizeof(rng)); + + ExpectIntEQ(wc_Sm4Init(&sm4, NULL, INVALID_DEVID), 0); + ExpectIntEQ(wc_InitRng(&rng), 0); + + for (i = 0; i < MC_CIPHER_TEST_COUNT && EXPECT_SUCCESS(); i++) { + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, key, sizeof(key)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, nonce, sizeof(nonce)), 0); + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, (byte*)&plainLen, + sizeof(plainLen)), 0); + plainLen = (plainLen % MC_SM4_MAX_DATA_SZ) + 1; + ExpectIntEQ(wc_RNG_GenerateBlock(&rng, plain, plainLen), 0); + + ExpectIntEQ(wc_Sm4SetKey(&sm4, key, SM4_KEY_SIZE), 0); + ExpectIntEQ(wc_Sm4CcmEncrypt(&sm4, cipher, plain, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectIntEQ(wc_Sm4CcmDecrypt(&sm4, decrypted, cipher, plainLen, + nonce, sizeof(nonce), tag, sizeof(tag), NULL, 0), 0); + ExpectBufEQ(decrypted, plain, plainLen); + } + + wc_Sm4Free(&sm4); + wc_FreeRng(&rng); + WC_FREE_VAR(plain, NULL); + WC_FREE_VAR(cipher, NULL); + WC_FREE_VAR(decrypted, NULL); + + res = EXPECT_RESULT(); +#endif + return res; +} diff --git a/tests/api/test_sm4.h b/tests/api/test_sm4.h index d11317b7597..e418c2a42e7 100644 --- a/tests/api/test_sm4.h +++ b/tests/api/test_sm4.h @@ -30,13 +30,21 @@ int test_wc_Sm4Cbc(void); int test_wc_Sm4Ctr(void); int test_wc_Sm4Gcm(void); int test_wc_Sm4Ccm(void); +int test_wc_Sm4Cbc_MonteCarlo(void); +int test_wc_Sm4Ctr_MonteCarlo(void); +int test_wc_Sm4Gcm_MonteCarlo(void); +int test_wc_Sm4Ccm_MonteCarlo(void); -#define TEST_SM4_DECLS \ - TEST_DECL_GROUP("sm4", test_wc_Sm4), \ - TEST_DECL_GROUP("sm4", test_wc_Sm4Ecb), \ - TEST_DECL_GROUP("sm4", test_wc_Sm4Cbc), \ - TEST_DECL_GROUP("sm4", test_wc_Sm4Ctr), \ - TEST_DECL_GROUP("sm4", test_wc_Sm4Gcm), \ - TEST_DECL_GROUP("sm4", test_wc_Sm4Ccm) +#define TEST_SM4_DECLS \ + TEST_DECL_GROUP("sm4", test_wc_Sm4), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Ecb), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Cbc), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Ctr), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Gcm), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Ccm), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Cbc_MonteCarlo), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Ctr_MonteCarlo), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Gcm_MonteCarlo), \ + TEST_DECL_GROUP("sm4", test_wc_Sm4Ccm_MonteCarlo) #endif /* WOLFCRYPT_TEST_SM4_H */