From 9a022d689b3df557bf6d04ffa4c884885c67b14c Mon Sep 17 00:00:00 2001 From: Maxim Sharabayko Date: Mon, 10 Oct 2022 15:23:44 +0200 Subject: [PATCH] [tests] Added AES GCM unit test for CCryptoControl. --- CMakeLists.txt | 5 +- scripts/googletest-download.cmake | 2 +- test/filelist.maf | 3 +- test/test_crypto.cpp | 112 ++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 test/test_crypto.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c126fb3d..b1074f5f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1355,10 +1355,11 @@ if (ENABLE_UNITTESTS AND ENABLE_CXX11) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Version ranges are only supported with CMake 3.19 or later. + # Need GTest v1.10 or higher to support GTEST_SKIP. if (${CMAKE_VERSION} VERSION_LESS "3.19.0") - find_package(GTest 1.8) + find_package(GTest 1.10) else() - find_package(GTest 1.8...1.12) + find_package(GTest 1.10...1.12) endif() if (NOT GTEST_FOUND) message(STATUS "GTEST not found! Fetching from git.") diff --git a/scripts/googletest-download.cmake b/scripts/googletest-download.cmake index 55f2c5a55..7469f4f7b 100644 --- a/scripts/googletest-download.cmake +++ b/scripts/googletest-download.cmake @@ -11,7 +11,7 @@ ExternalProject_Add( BINARY_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-build" GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.8.1 + GIT_TAG release-1.10.0 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" diff --git a/test/filelist.maf b/test/filelist.maf index b1e58a88c..c986ef56f 100644 --- a/test/filelist.maf +++ b/test/filelist.maf @@ -6,7 +6,7 @@ test_buffer_rcv.cpp test_bonding.cpp test_common.cpp test_connection_timeout.cpp -test_many_connections.cpp +test_crypto.cpp test_cryspr.cpp test_enforced_encryption.cpp test_epoll.cpp @@ -16,6 +16,7 @@ test_ipv6.cpp test_listen_callback.cpp test_losslist_rcv.cpp test_losslist_snd.cpp +test_many_connections.cpp test_muxer.cpp test_seqno.cpp test_socket_options.cpp diff --git a/test/test_crypto.cpp b/test/test_crypto.cpp new file mode 100644 index 000000000..75386bcb9 --- /dev/null +++ b/test/test_crypto.cpp @@ -0,0 +1,112 @@ +#include +#include + +#include "gtest/gtest.h" + +#ifdef SRT_ENABLE_ENCRYPTION +#include "crypto.h" +#include "hcrypt.h" // Imports the CRYSPR_HAS_AESGCM definition. +#include "socketconfig.h" + + +namespace srt +{ + + class Crypto + : public ::testing::Test + { + protected: + Crypto() + : m_crypt(0) + { + // initialization code here + } + + virtual ~Crypto() + { + // cleanup any pending stuff, but no exceptions allowed + } + + protected: + // SetUp() is run immediately before a test starts. + void SetUp() override + { + CSrtConfig cfg; + + memset(&cfg.CryptoSecret, 0, sizeof(cfg.CryptoSecret)); + cfg.CryptoSecret.typ = HAICRYPT_SECTYP_PASSPHRASE; + cfg.CryptoSecret.len = (m_pwd.size() <= (int)sizeof(cfg.CryptoSecret.str) ? m_pwd.size() : (int)sizeof(cfg.CryptoSecret.str)); + memcpy((cfg.CryptoSecret.str), m_pwd.c_str(), m_pwd.size()); + + m_crypt.setCryptoSecret(cfg.CryptoSecret); + + // 2 = 128, 3 = 192, 4 = 256 + cfg.iSndCryptoKeyLen = SrtHSRequest::SRT_PBKEYLEN_BITS::wrap(4); + m_crypt.setCryptoKeylen(cfg.iSndCryptoKeyLen); + + cfg.iCryptoMode = CSrtConfig::CIPHER_MODE_AES_GCM; + EXPECT_EQ(m_crypt.init(HSD_INITIATOR, cfg, true), HaiCrypt_IsAESGCM_Supported() != 0); + + const unsigned char* kmmsg = m_crypt.getKmMsg_data(0); + const size_t km_len = m_crypt.getKmMsg_size(0); + uint32_t kmout[72]; + size_t kmout_len = 72; + + std::array km_nworder; + NtoHLA(km_nworder.data(), reinterpret_cast(kmmsg), km_len); + m_crypt.processSrtMsg_KMREQ(km_nworder.data(), km_len, 5, kmout, kmout_len); + } + + void TearDown() override + { + } + + protected: + + srt::CCryptoControl m_crypt; + const std::string m_pwd = "abcdefghijk"; + }; + + + // Check that destroying the buffer also frees memory units. + TEST_F(Crypto, GCM) + { + if (HaiCrypt_IsAESGCM_Supported() == 0) + GTEST_SKIP() << "The crypto service provider does not support AES GCM."; + + const size_t mtu_size = 1500; + const size_t pld_size = 1316; + const size_t tag_len = 16; + + CPacket pkt; + pkt.allocate(mtu_size); + + const int seqno = 1; + const int msgno = 1; + const int inorder = 1; + const int kflg = m_crypt.getSndCryptoFlags(); + + pkt.m_iSeqNo = seqno; + pkt.m_iMsgNo = msgno | inorder | PacketBoundaryBits(PB_SOLO) | MSGNO_ENCKEYSPEC::wrap(kflg);; + pkt.m_iTimeStamp = 356; + + std::iota(pkt.data(), pkt.data() + pld_size, '0'); + pkt.setLength(pld_size); + + EXPECT_EQ(m_crypt.encrypt(pkt), ENCS_CLEAR); + EXPECT_EQ(pkt.getLength(), pld_size + tag_len); + + auto pkt_enc = std::unique_ptr(pkt.clone()); + + EXPECT_EQ(m_crypt.decrypt(pkt), ENCS_CLEAR); + EXPECT_EQ(pkt.getLength(), pld_size); + + // Modify the payload and expect auth to fail. + pkt_enc->data()[10] = '5'; + EXPECT_EQ(m_crypt.decrypt(*pkt_enc.get()), ENCS_FAILED); + + } + +} // namespace srt + +#endif //SRT_ENABLE_ENCRYPTION