diff --git a/tests/api/include.am b/tests/api/include.am index f350400ea..779efe6e8 100644 --- a/tests/api/include.am +++ b/tests/api/include.am @@ -28,6 +28,7 @@ tests_unit_test_SOURCES += tests/api/test_aes.c tests_unit_test_SOURCES += tests/api/test_ascon.c tests_unit_test_SOURCES += tests/api/test_sm4.c tests_unit_test_SOURCES += tests/api/test_wc_encrypt.c +tests_unit_test_SOURCES += tests/api/test_evp.c # Signature Algorithm tests_unit_test_SOURCES += tests/api/test_mlkem.c # TLS Protocol @@ -66,4 +67,5 @@ EXTRA_DIST += tests/api/test_dtls.h EXTRA_DIST += tests/api/test_ocsp.h EXTRA_DIST += tests/api/test_ocsp_test_blobs.h EXTRA_DIST += tests/api/create_ocsp_test_blobs.py +EXTRA_DIST += tests/api/test_evp.h diff --git a/tests/api/test_evp.c b/tests/api/test_evp.c new file mode 100644 index 000000000..40c770fa1 --- /dev/null +++ b/tests/api/test_evp.c @@ -0,0 +1,196 @@ +/* test_evp.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include + +#include +#include + +#ifdef OPENSSL_EXTRA + +/* Test for NULL_CIPHER_TYPE in wolfSSL_EVP_CipherUpdate() */ +static int TestNullCipherUpdate(void) +{ + EXPECT_DECLS; + WOLFSSL_EVP_CIPHER_CTX* ctx; + const char* testData = "Test NULL cipher data"; + unsigned char output[100]; + int outputLen = 0; + int testDataLen = (int)XSTRLEN(testData); + + /* Create and initialize the cipher context */ + ctx = wolfSSL_EVP_CIPHER_CTX_new(); + ExpectNotNull(ctx); + + /* Initialize with NULL cipher */ + ExpectIntEQ(wolfSSL_EVP_CipherInit_ex(ctx, wolfSSL_EVP_enc_null(), + NULL, NULL, NULL, 1), WOLFSSL_SUCCESS); + + /* Test encryption (which should just copy the data) */ + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, output, &outputLen, + (const unsigned char*)testData, + testDataLen), WOLFSSL_SUCCESS); + + /* Verify output length matches input length */ + ExpectIntEQ(outputLen, testDataLen); + + /* Verify output data matches input data (no encryption occurred) */ + ExpectIntEQ(XMEMCMP(output, testData, testDataLen), 0); + + /* Clean up */ + wolfSSL_EVP_CIPHER_CTX_free(ctx); + + return EXPECT_RESULT(); +} + +/* Test for NULL_CIPHER_TYPE with empty data */ +static int TestNullCipherUpdateEmptyData(void) +{ + EXPECT_DECLS; + WOLFSSL_EVP_CIPHER_CTX* ctx; + unsigned char output[100]; + int outputLen = 0; + + /* Create and initialize the cipher context */ + ctx = wolfSSL_EVP_CIPHER_CTX_new(); + ExpectNotNull(ctx); + + /* Initialize with NULL cipher */ + ExpectIntEQ(wolfSSL_EVP_CipherInit_ex(ctx, wolfSSL_EVP_enc_null(), + NULL, NULL, NULL, 1), WOLFSSL_SUCCESS); + + /* Test with empty data */ + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, output, &outputLen, + NULL, 0), WOLFSSL_SUCCESS); + + /* Verify output length is 0 */ + ExpectIntEQ(outputLen, 0); + + /* Clean up */ + wolfSSL_EVP_CIPHER_CTX_free(ctx); + + return EXPECT_RESULT(); +} + +/* Test for NULL_CIPHER_TYPE with large data */ +static int TestNullCipherUpdateLargeData(void) +{ + EXPECT_DECLS; + WOLFSSL_EVP_CIPHER_CTX* ctx; + unsigned char largeData[1024]; + unsigned char output[1024]; + int outputLen = 0; + int i; + + /* Fill large data buffer with pattern */ + for (i = 0; i < 1024; i++) { + largeData[i] = (unsigned char)(i & 0xFF); + } + + /* Create and initialize the cipher context */ + ctx = wolfSSL_EVP_CIPHER_CTX_new(); + ExpectNotNull(ctx); + + /* Initialize with NULL cipher */ + ExpectIntEQ(wolfSSL_EVP_CipherInit_ex(ctx, wolfSSL_EVP_enc_null(), + NULL, NULL, NULL, 1), WOLFSSL_SUCCESS); + + /* Test with large data */ + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, output, &outputLen, + largeData, 1024), WOLFSSL_SUCCESS); + + /* Verify output length matches input length */ + ExpectIntEQ(outputLen, 1024); + + /* Verify output data matches input data */ + ExpectIntEQ(XMEMCMP(output, largeData, 1024), 0); + + /* Clean up */ + wolfSSL_EVP_CIPHER_CTX_free(ctx); + + return EXPECT_RESULT(); +} + +/* Test for NULL_CIPHER_TYPE with multiple updates */ +static int TestNullCipherUpdateMultiple(void) +{ + EXPECT_DECLS; + WOLFSSL_EVP_CIPHER_CTX* ctx; + const char* testData1 = "First part of data"; + const char* testData2 = "Second part of data"; + unsigned char output1[100]; + unsigned char output2[100]; + int outputLen1 = 0; + int outputLen2 = 0; + int testData1Len = (int)XSTRLEN(testData1); + int testData2Len = (int)XSTRLEN(testData2); + + /* Create and initialize the cipher context */ + ctx = wolfSSL_EVP_CIPHER_CTX_new(); + ExpectNotNull(ctx); + + /* Initialize with NULL cipher */ + ExpectIntEQ(wolfSSL_EVP_CipherInit_ex(ctx, wolfSSL_EVP_enc_null(), + NULL, NULL, NULL, 1), WOLFSSL_SUCCESS); + + /* First update */ + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, output1, &outputLen1, + (const unsigned char*)testData1, + testData1Len), WOLFSSL_SUCCESS); + + /* Verify first output */ + ExpectIntEQ(outputLen1, testData1Len); + ExpectIntEQ(XMEMCMP(output1, testData1, testData1Len), 0); + + /* Second update */ + ExpectIntEQ(wolfSSL_EVP_CipherUpdate(ctx, output2, &outputLen2, + (const unsigned char*)testData2, + testData2Len), WOLFSSL_SUCCESS); + + /* Verify second output */ + ExpectIntEQ(outputLen2, testData2Len); + ExpectIntEQ(XMEMCMP(output2, testData2, testData2Len), 0); + + /* Clean up */ + wolfSSL_EVP_CIPHER_CTX_free(ctx); + + return EXPECT_RESULT(); +} + +/* Function to register all EVP tests */ +int TestEvpAll(void) +{ + int ret = 0; + + ret |= TestNullCipherUpdate(); + ret |= TestNullCipherUpdateEmptyData(); + ret |= TestNullCipherUpdateLargeData(); + ret |= TestNullCipherUpdateMultiple(); + + return ret; +} + +#endif /* OPENSSL_EXTRA */ diff --git a/tests/api/test_evp.h b/tests/api/test_evp.h new file mode 100644 index 000000000..90750cbe3 --- /dev/null +++ b/tests/api/test_evp.h @@ -0,0 +1,29 @@ +/* test_evp.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLFSSL_TEST_EVP_H +#define WOLFSSL_TEST_EVP_H + +#ifdef OPENSSL_EXTRA +int TestEvpAll(void); +#endif /* OPENSSL_EXTRA */ + +#endif /* WOLFSSL_TEST_EVP_H */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index d78a0be03..8b06f8d39 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1059,6 +1059,10 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, } switch (ctx->cipherType) { + case NULL_CIPHER_TYPE: + XMEMCPY(out, in, inl); + *outl = inl; + return WOLFSSL_SUCCESS; #if !defined(NO_AES) && defined(HAVE_AESGCM) case WC_AES_128_GCM_TYPE: case WC_AES_192_GCM_TYPE: