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 */