Skip to content

Commit

Permalink
initial nDPId UDP crypto [WiP!]
Browse files Browse the repository at this point in the history
Signed-off-by: Toni Uhlig <[email protected]>
  • Loading branch information
utoni committed Nov 19, 2024
1 parent 442900b commit ea6b08a
Show file tree
Hide file tree
Showing 8 changed files with 971 additions and 12 deletions.
22 changes: 17 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ option(ENABLE_SANITIZER_THREAD "Enable TSAN (does not work together with ASAN)."
option(ENABLE_MEMORY_PROFILING "Enable dynamic memory tracking." OFF)
option(ENABLE_ZLIB "Enable zlib support for nDPId (experimental)." OFF)
option(ENABLE_SYSTEMD "Install systemd components." OFF)
option(ENABLE_CRYPTO "Enable OpenSSL cryptographic support in nDPId/nDPIsrvd." OFF)
option(BUILD_EXAMPLES "Build C examples." ON)
if(BUILD_EXAMPLES)
option(ENABLE_DBUS "Build DBus notification example." OFF)
Expand Down Expand Up @@ -196,7 +197,10 @@ endif()
if(ENABLE_PFRING)
set(NDPID_PFRING_SRCS npfring.c)
endif()
add_executable(nDPId nDPId.c ${NDPID_PFRING_SRCS} nio.c utils.c)
if(ENABLE_CRYPTO)
set(CRYPTO_SRCS ncrypt.c)
endif()
add_executable(nDPId nDPId.c ${NDPID_PFRING_SRCS} ${CRYPTO_SRCS} nio.c utils.c)
add_executable(nDPIsrvd nDPIsrvd.c nio.c utils.c)
add_executable(nDPId-test nDPId-test.c ${NDPID_PFRING_SRCS})

Expand Down Expand Up @@ -374,6 +378,12 @@ if(BUILD_NDPI)
add_dependencies(nDPId-test libnDPI)
endif()

if(ENABLE_CRYPTO)
find_package(OpenSSL REQUIRED)
set(OSSL_DEFS "-DENABLE_CRYPTO=1")
set(OSSL_LIBRARY "${OPENSSL_CRYPTO_LIBRARY}")
endif()

if(STATIC_LIBNDPI_INSTALLDIR OR BUILD_NDPI OR NDPI_NO_PKGCONFIG)
if(NDPI_WITH_GCRYPT)
find_package(GCRYPT "1.4.2" REQUIRED)
Expand Down Expand Up @@ -437,25 +447,26 @@ if(NOT pkgcfg_lib_PCAP_pcap)
endif()

target_compile_options(nDPId PRIVATE "-pthread")
target_compile_definitions(nDPId PRIVATE -D_GNU_SOURCE=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\" ${NDPID_DEFS} ${EPOLL_DEFS} ${ZLIB_DEFS} ${PFRING_DEFS})
target_compile_definitions(nDPId PRIVATE -D_GNU_SOURCE=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\"
${NDPID_DEFS} ${EPOLL_DEFS} ${ZLIB_DEFS} ${PFRING_DEFS} ${OSSL_DEFS})
target_include_directories(nDPId PRIVATE "${STATIC_LIBNDPI_INC}" "${DEFAULT_NDPI_INCLUDE}" ${NDPID_DEPS_INC} ${PFRING_KERNEL_INC} ${PFRING_INC})
target_link_libraries(nDPId "${STATIC_LIBNDPI_LIB}" "${STATIC_PFRING_LIB}" "${pkgcfg_lib_PCAP_pcap}" "${pkgcfg_lib_NDPI_ndpi}"
"${pkgcfg_lib_PCRE_pcre2-8}" "${pkgcfg_lib_MAXMINDDB_maxminddb}" "${pkgcfg_lib_ZLIB_z}"
"${GCRYPT_LIBRARY}" "${GCRYPT_ERROR_LIBRARY}" "${PCAP_LIBRARY}" "${LIBM_LIB}" "${PF_RING_LIB}"
"-pthread")
"${OSSL_LIBRARY}" "-pthread")

target_compile_definitions(nDPIsrvd PRIVATE -D_GNU_SOURCE=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\" ${NDPID_DEFS} ${EPOLL_DEFS})
target_include_directories(nDPIsrvd PRIVATE ${NDPID_DEPS_INC})

target_compile_options(nDPId-test PRIVATE "-Wno-unused-function" "-pthread")
target_compile_definitions(nDPId-test PRIVATE -D_GNU_SOURCE=1 -DNO_MAIN=1 -DPKG_VERSION=\"${PKG_VERSION}\" -DGIT_VERSION=\"${GIT_VERSION}\"
${NDPID_DEFS} ${EPOLL_DEFS} ${ZLIB_DEFS} ${PFRING_DEFS} ${NDPID_TEST_MPROF_DEFS})
${NDPID_DEFS} ${EPOLL_DEFS} ${ZLIB_DEFS} ${PFRING_DEFS} ${OSSL_DEFS} ${NDPID_TEST_MPROF_DEFS})
target_include_directories(nDPId-test PRIVATE
"${STATIC_LIBNDPI_INC}" "${DEFAULT_NDPI_INCLUDE}" ${NDPID_DEPS_INC} ${PFRING_KERNEL_INC} ${PFRING_INC})
target_link_libraries(nDPId-test "${STATIC_LIBNDPI_LIB}" "${STATIC_PFRING_LIB}" "${pkgcfg_lib_PCAP_pcap}" "${pkgcfg_lib_NDPI_ndpi}"
"${pkgcfg_lib_PCRE_pcre2-8}" "${pkgcfg_lib_MAXMINDDB_maxminddb}" "${pkgcfg_lib_ZLIB_z}"
"${GCRYPT_LIBRARY}" "${GCRYPT_ERROR_LIBRARY}" "${PCAP_LIBRARY}" "${LIBM_LIB}" "${PF_RING_LIB}"
"-pthread")
"${OSSL_LIBRARY}" "-pthread")

if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_executable(fuzz_ndpi_process_packet test/fuzz_ndpi_process_packet.c)
Expand Down Expand Up @@ -604,6 +615,7 @@ message(STATUS "ENABLE_PFRING............: ${ENABLE_PFRING}")
if(ENABLE_PFRING)
message(STATUS "PFRING_LINK_STATIC.......: ${PFRING_LINK_STATIC}")
endif()
message(STATUS "ENABLE_CRYPTO............: ${ENABLE_CRYPTO}")
message(STATUS "ENABLE_COVERAGE..........: ${ENABLE_COVERAGE}")
message(STATUS "ENABLE_SANITIZER.........: ${ENABLE_SANITIZER}")
message(STATUS "ENABLE_SANITIZER_THREAD..: ${ENABLE_SANITIZER_THREAD}")
Expand Down
212 changes: 211 additions & 1 deletion nDPId-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ extern void nDPIsrvd_memprof_log_free(size_t free_size);
// #define VERBOSE_MEMORY_PROFILING 1
#define NO_MAIN 1
#include "utils.c"
#ifdef ENABLE_CRYPTO
#include "ncrypt.c"
#endif
#include "nio.c"
#include "nDPIsrvd.c"
#include "nDPId.c"
Expand Down Expand Up @@ -1638,6 +1641,210 @@ static int nio_selftest()
return 1;
}

#ifdef ENABLE_CRYPTO
static int ncrypt_selftest()
{
int ret = 0;
struct ncrypt nc_peer1 = {};
struct ncrypt nc_peer2 = {};
unsigned char peer1_priv_key[NCRYPT_X25519_KEYLEN];
unsigned char peer2_priv_key[NCRYPT_X25519_KEYLEN];
unsigned char peer1_pub_key[NCRYPT_X25519_KEYLEN];
unsigned char peer2_pub_key[NCRYPT_X25519_KEYLEN];
unsigned char iv[NCRYPT_AES_IVLEN];

if (ncrypt_keygen(peer1_priv_key, peer1_pub_key) != 0)
{
ret++;
}
if (ncrypt_keygen(peer2_priv_key, peer2_pub_key) != 0)
{
ret++;
}
if (ncrypt_init(&nc_peer1, peer1_priv_key, peer2_pub_key) != 0)
{
ret++;
}
if (ncrypt_init(&nc_peer2, peer2_priv_key, peer1_pub_key) != 0)
{
ret++;
}
if (ncrypt_init_encrypt(&nc_peer1) != 0)
{
ret++;
}
if (ncrypt_init_decrypt(&nc_peer2, nc_peer1.iv) != 0)
{
ret++;
}
if (memcmp(nc_peer1.shared_secret, nc_peer2.shared_secret, NCRYPT_X25519_KEYLEN) != 0)
{
ret++;
}
if (memcmp(nc_peer1.iv, nc_peer2.iv, NCRYPT_AES_IVLEN) != 0)
{
ret++;
}

memcpy(iv, nc_peer1.iv, NCRYPT_AES_IVLEN);
unsigned char plaintext[] = "Secret Message";
unsigned char encrypted1[NCRYPT_BUFFER_SIZE];
unsigned char tag1[NCRYPT_TAG_SIZE];
unsigned char encrypted2[NCRYPT_BUFFER_SIZE];
unsigned char tag2[NCRYPT_TAG_SIZE];
unsigned char tmp1[NETWORK_BUFFER_MAX_SIZE];
unsigned char tmp2[NETWORK_BUFFER_MAX_SIZE];

memset(encrypted1, 0xFF, sizeof(encrypted1));
memset(encrypted2, 0xFF, sizeof(encrypted2));
memset(tag1, 0xFF, sizeof(tag1));
memset(tag2, 0xFF, sizeof(tag2));

int enc_bytes;
int dec_bytes;

enc_bytes = ncrypt_encrypt(&nc_peer1, plaintext, sizeof(plaintext), encrypted1, tag1);
dec_bytes = ncrypt_decrypt(&nc_peer2, encrypted1, enc_bytes, tag1, tmp1);

if (enc_bytes != dec_bytes)
{
ret++;
}
if (memcmp(plaintext, tmp1, dec_bytes) != 0)
{
ret++;
}
memset(tmp1, 0xFF, sizeof(tmp1));

enc_bytes = ncrypt_encrypt(&nc_peer1, plaintext, sizeof(plaintext), encrypted2, tag2);
dec_bytes = ncrypt_decrypt(&nc_peer2, encrypted2, enc_bytes, tag2, tmp1);

if (enc_bytes != dec_bytes)
{
ret++;
}
if (memcmp(plaintext, tmp1, dec_bytes) != 0)
{
ret++;
}

if (memcmp(tag1, tag2, NCRYPT_TAG_SIZE) == 0)
{
ret++;
}
if (memcmp(encrypted1, encrypted2, enc_bytes) == 0)
{
ret++;
}

if (memcmp(iv, nc_peer1.iv, NCRYPT_AES_IVLEN) == 0)
{
ret++;
}

memset(encrypted1, 0xFF, sizeof(encrypted1));
memset(tag1, 0xFF, sizeof(tag1));
memset(tmp1, 0x41, sizeof(tmp1));
enc_bytes = ncrypt_encrypt(&nc_peer1, tmp1, sizeof(tmp1), encrypted1, tag1);
dec_bytes = ncrypt_decrypt(&nc_peer2, encrypted1, enc_bytes, tag1, tmp2);
if (enc_bytes != sizeof(tmp1) || dec_bytes != sizeof(tmp2))
{
ret++;
}
if (memcmp(tmp1, tmp2, sizeof(tmp1)) != 0)
{
ret++;
}

enc_bytes = ncrypt_encrypt(&nc_peer1, tmp1, sizeof(tmp1), encrypted2, tag2);
dec_bytes = ncrypt_decrypt(&nc_peer2, encrypted2, enc_bytes, tag2, tmp2);
if (enc_bytes != sizeof(tmp1) || dec_bytes != sizeof(tmp2))
{
ret++;
}
if (memcmp(tmp1, tmp2, sizeof(tmp1)) != 0)
{
ret++;
}

if (enc_bytes != dec_bytes)
{
ret++;
}
if (memcmp(tmp2, encrypted1, dec_bytes) == 0)
{
ret++;
}
if (memcmp(tag1, tag2, NCRYPT_TAG_SIZE) == 0)
{
ret++;
}
if (memcmp(encrypted1, encrypted2, enc_bytes) == 0)
{
ret++;
}
if (memcmp(iv, nc_peer1.iv, NCRYPT_AES_IVLEN) == 0)
{
ret++;
}
if (memcmp(nc_peer1.iv, nc_peer2.iv, NCRYPT_AES_IVLEN) != 0)
{
ret++;
}

int pipefds[2] = {-1, -1};
if (pipe2(pipefds, O_DIRECT) != 0)
{
ret++;
}

struct ncrypt_buffer encrypted_buf = {};
struct ncrypt_buffer decrypted_buf = {};
memcpy(encrypted_buf.plaintext.data, plaintext, sizeof(plaintext));
encrypted_buf.data_used = sizeof(plaintext);

int sent;
sent = ncrypt_encrypt_send(&nc_peer1, pipefds[1], &encrypted_buf);
if (sent < 0)
{
ret++;
}

int received = ncrypt_decrypt_recv(&nc_peer2, pipefds[0], &decrypted_buf);
if (received < 0)
{
ret++;
}

if (received != sent)
{
ret++;
}

sent = ncrypt_encrypt_send(&nc_peer1, pipefds[1], &encrypted_buf);
int sent2 = ncrypt_encrypt_send(&nc_peer1, pipefds[1], &encrypted_buf);
if (sent < 0 || sent != sent2)
{
ret++;
}

received = ncrypt_decrypt_recv(&nc_peer2, pipefds[0], &decrypted_buf);
int received2 = ncrypt_decrypt_recv(&nc_peer2, pipefds[0], &decrypted_buf);
if (received < 0 || received != received2)
{
ret++;
}

close(pipefds[0]);
close(pipefds[1]);

ncrypt_free(&nc_peer2);
ncrypt_free(&nc_peer1);

return ret;
}
#endif

#define THREADS_RETURNED_ERROR() \
(nDPId_return.thread_return_value.val != 0 || nDPIsrvd_return.val != 0 || \
distributor_return.thread_return_value.val != 0)
Expand Down Expand Up @@ -1671,8 +1878,11 @@ int main(int argc, char ** argv)

retval += base64_selftest();
retval += nio_selftest();
#ifdef ENABLE_CRYPTO
retval += ncrypt_selftest();
#endif

logger(1, "Selftest returned: %d", retval);
logger(1, "Selftest returned: %d%s", retval, (retval == 0 ? " (OK)" : ""));
return retval;
}

Expand Down
Loading

0 comments on commit ea6b08a

Please sign in to comment.