diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 98de99f4..c955d266 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,9 +18,26 @@ jobs: - name: Update run: sudo apt-get update - name: Install Dependencies - run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat libgcrypt20-dev python3 + run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat python3 - name: Install Python Libraries run: sudo pip install pycryptodome + - name: Install Libgcrypt + run: > + curl + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.50.tar.bz2 + -o /tmp/libgpg-error-1.50.tar.bz2 + && tar -xjf /tmp/libgpg-error-1.50.tar.bz2 -C /tmp/ + && cd /tmp/libgpg-error-1.50 + && sudo ./configure + && sudo make install + && curl + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.bz2 + -o /tmp/libgcrypt-1.11.0.tar.bz2 + && tar -xjf /tmp/libgcrypt-1.11.0.tar.bz2 -C /tmp/ + && cd /tmp/libgcrypt-1.11.0 + && sudo ./configure + && sudo make install + && sudo ldconfig # End Container Setup - name: Minimal Build Script @@ -38,9 +55,26 @@ jobs: - name: Update run: sudo apt-get update - name: Install Dependencies - run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat libgcrypt20-dev python3 + run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat python3 - name: Install Python Libraries run: sudo pip install pycryptodome + - name: Install Libgcrypt + run: > + curl + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.50.tar.bz2 + -o /tmp/libgpg-error-1.50.tar.bz2 + && tar -xjf /tmp/libgpg-error-1.50.tar.bz2 -C /tmp/ + && cd /tmp/libgpg-error-1.50 + && sudo ./configure + && sudo make install + && curl + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.bz2 + -o /tmp/libgcrypt-1.11.0.tar.bz2 + && tar -xjf /tmp/libgcrypt-1.11.0.tar.bz2 -C /tmp/ + && cd /tmp/libgcrypt-1.11.0 + && sudo ./configure + && sudo make install + && sudo ldconfig # End Container Setup - name: Internal Build Script @@ -70,9 +104,26 @@ jobs: - name: Update run: sudo apt-get update - name: Install Dependencies - run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat libgcrypt20-dev python3 + run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat python3 - name: Install Python Libraries run: sudo pip install pycryptodome + - name: Install Libgcrypt + run: > + curl + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.50.tar.bz2 + -o /tmp/libgpg-error-1.50.tar.bz2 + && tar -xjf /tmp/libgpg-error-1.50.tar.bz2 -C /tmp/ + && cd /tmp/libgpg-error-1.50 + && sudo ./configure + && sudo make install + && curl + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.bz2 + -o /tmp/libgcrypt-1.11.0.tar.bz2 + && tar -xjf /tmp/libgcrypt-1.11.0.tar.bz2 -C /tmp/ + && cd /tmp/libgcrypt-1.11.0 + && sudo ./configure + && sudo make install + && sudo ldconfig # End Container Setup - name: KMC Build Script @@ -102,9 +153,26 @@ jobs: - name: Update run: sudo apt-get update - name: Install Dependencies - run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat libgcrypt20-dev python3 autoconf libtool + run: sudo apt-get install -y lcov libcurl4-openssl-dev libmariadb-dev libmariadb-dev-compat python3 autoconf libtool - name: Install Python Libraries run: sudo pip install pycryptodome + - name: Install Libgcrypt + run: > + curl + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.50.tar.bz2 + -o /tmp/libgpg-error-1.50.tar.bz2 + && tar -xjf /tmp/libgpg-error-1.50.tar.bz2 -C /tmp/ + && cd /tmp/libgpg-error-1.50 + && sudo ./configure + && sudo make install + && curl + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.bz2 + -o /tmp/libgcrypt-1.11.0.tar.bz2 + && tar -xjf /tmp/libgcrypt-1.11.0.tar.bz2 -C /tmp/ + && cd /tmp/libgcrypt-1.11.0 + && sudo ./configure + && sudo make install + && sudo ldconfig - name: Clone WolfSSL run: git clone --depth 1 --branch v5.6.0-stable https://github.com/wolfSSL/wolfssl.git /tmp/wolfssl @@ -114,7 +182,7 @@ jobs: #run: cd /tmp/wolfssl/; # sudo chown -R runner /usr/local; # ./autogen.sh; - # ./configure --enable-aesccm --enable-aessiv --enable-cmac; + # sudo ./configure --enable-aesccm --enable-aessiv --enable-cmac; # make; # make install; #sudo chown -R runner /usr/local; @@ -155,21 +223,40 @@ jobs: - name: Update run: yum update -y - name: Install Dependencies - run: yum install -y epel-release python38-devel libcurl-devel libgpg-error-devel libgcrypt-devel git cmake gcc java-11-openjdk-devel openssl wget mariadb-devel mariadb-common mariadb-connector-c mariadb-connector-c-config mariadb-errmsg mariadb-gssapi-server + run: yum install -y epel-release python38-devel libcurl-devel git cmake gcc java-11-openjdk-devel openssl wget bzip2 ldconfig mariadb-devel mariadb-common mariadb-connector-c mariadb-connector-c-config mariadb-errmsg mariadb-gssapi-server # Might want to trim this down, but these dependencies should work for KMC - name: install lcov run: yum install -y --enablerepo=epel lcov - name: Install Python Dependencies run: pip3 install pycryptodome + - name: Install Libgcrypt + run: > + curl + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.50.tar.bz2 + -o /tmp/libgpg-error-1.50.tar.bz2 + && tar -xjf /tmp/libgpg-error-1.50.tar.bz2 -C /tmp/ + && cd /tmp/libgpg-error-1.50 + && ./configure + && make install + && curl + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.bz2 + -o /tmp/libgcrypt-1.11.0.tar.bz2 + && tar -xjf /tmp/libgcrypt-1.11.0.tar.bz2 -C /tmp/ + && cd /tmp/libgcrypt-1.11.0 + && ./configure + && make install + && echo "export LD_LIBRARY_PATH=/usr/local/lib/:/usr/local/include:$LD_LIBRARY_PATH" >> ~/.bashrc + && source ~/.bashrc + && ldconfig # End Container Setup - name: RHEL Build Script working-directory: ${{github.workspace}} - run: bash ${GITHUB_WORKSPACE}/support/scripts/build_rhel.sh + run: source ~/.bashrc && ${GITHUB_WORKSPACE}/support/scripts/build_rhel.sh - name: Code-Coverage working-directory: ${{github.workspace}} - run: make gcov + run: source ~/.bashrc && make gcov - name: Upload uses: codecov/codecov-action@v4 diff --git a/include/crypto_config_structs.h b/include/crypto_config_structs.h index 3ad48826..4d24a048 100644 --- a/include/crypto_config_structs.h +++ b/include/crypto_config_structs.h @@ -190,6 +190,7 @@ typedef enum { CRYPTO_CIPHER_NONE, CRYPTO_CIPHER_AES256_GCM, + CRYPTO_CIPHER_AES256_GCM_SIV, CRYPTO_CIPHER_AES256_CBC, CRYPTO_CIPHER_AES256_CBC_MAC, CRYPTO_CIPHER_AES256_CCM diff --git a/src/core/crypto.c b/src/core/crypto.c index 975aa1fc..43991951 100644 --- a/src/core/crypto.c +++ b/src/core/crypto.c @@ -100,7 +100,7 @@ uint8_t Crypto_Is_AEAD_Algorithm(uint32_t cipher_suite_id) // CryptoLib only supports AES-GCM, which is an AEAD (Authenticated Encryption with Associated Data) algorithm, so // return true/1. // TODO - Add cipher suite mapping to which algorithms are AEAD and which are not. - if ((cipher_suite_id == CRYPTO_CIPHER_AES256_GCM) || (cipher_suite_id == CRYPTO_CIPHER_AES256_CBC_MAC)) + if ((cipher_suite_id == CRYPTO_CIPHER_AES256_GCM) || (cipher_suite_id == CRYPTO_CIPHER_AES256_CBC_MAC) || (cipher_suite_id == CRYPTO_CIPHER_AES256_GCM_SIV)) { #ifdef DEBUG printf(KYEL "CRYPTO IS AEAD? : TRUE\n" RESET); @@ -982,7 +982,7 @@ int32_t Crypto_Check_Anti_Replay(SecurityAssociation_t* sa_ptr, uint8_t* arsn, u } // For GCM specifically, if have a valid IV... - if ((sa_ptr->ecs == CRYPTO_CIPHER_AES256_GCM) && (iv_valid == CRYPTO_TRUE)) + if ((sa_ptr->ecs == CRYPTO_CIPHER_AES256_GCM || sa_ptr->ecs == CRYPTO_CIPHER_AES256_GCM_SIV) && (iv_valid == CRYPTO_TRUE)) { // Using ARSN? Need to be valid to increment both if (sa_ptr->arsn_len > 0 && arsn_valid == CRYPTO_TRUE) @@ -998,7 +998,7 @@ int32_t Crypto_Check_Anti_Replay(SecurityAssociation_t* sa_ptr, uint8_t* arsn, u } // If not GCM, and ARSN is valid - can incrmeent it - if (sa_ptr->ecs != CRYPTO_CIPHER_AES256_GCM && arsn_valid == CRYPTO_TRUE) + if ((sa_ptr->ecs != CRYPTO_CIPHER_AES256_GCM && sa_ptr->ecs != CRYPTO_CIPHER_AES256_GCM_SIV) && arsn_valid == CRYPTO_TRUE) { memcpy(sa_ptr->arsn, arsn, sa_ptr->arsn_len); } @@ -1026,6 +1026,9 @@ int32_t Crypto_Get_ECS_Algo_Keylen(uint8_t algo) case CRYPTO_CIPHER_AES256_GCM: retval = 32; break; + case CRYPTO_CIPHER_AES256_GCM_SIV: + retval = 32; + break; case CRYPTO_CIPHER_AES256_CBC: retval = 32; break; diff --git a/src/crypto/kmc/cryptography_interface_kmc_crypto_service.template.c b/src/crypto/kmc/cryptography_interface_kmc_crypto_service.template.c index 3edaebd0..330ae3ec 100644 --- a/src/crypto/kmc/cryptography_interface_kmc_crypto_service.template.c +++ b/src/crypto/kmc/cryptography_interface_kmc_crypto_service.template.c @@ -2291,6 +2291,8 @@ int32_t cryptography_get_ecs_algo(int8_t algo_enum) return CRYPTO_CIPHER_AES256_GCM; case CRYPTO_CIPHER_AES256_CCM: return CRYPTO_CIPHER_AES256_CCM; + case CRYPTO_CIPHER_AES256_GCM_SIV: + return CRYPTO_CIPHER_AES256_GCM_SIV; default: #ifdef DEBUG diff --git a/src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c b/src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c index 90b467d6..e6655096 100644 --- a/src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c +++ b/src/crypto/libgcrypt/cryptography_interface_libgcrypt.template.c @@ -837,6 +837,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, // Select correct libgcrypt ecs enum int32_t algo = -1; + int32_t mode = -1; if (ecs != NULL) { algo = cryptography_get_ecs_algo(*ecs); @@ -844,6 +845,11 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, { return CRYPTO_LIB_ERR_UNSUPPORTED_ECS; } + mode = cryptography_get_ecs_mode(*ecs); + if (mode == CRYPTO_LIB_ERR_UNSUPPORTED_ECS) + { + return CRYPTO_LIB_ERR_UNSUPPORTED_ECS; + } } else { @@ -858,7 +864,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, return status; } - gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_NONE); + gcry_error = gcry_cipher_open(&(tmp_hd), GCRY_CIPHER_AES256, mode, GCRY_CIPHER_NONE); if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_open error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); @@ -903,6 +909,10 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, if (decrypt_bool == CRYPTO_TRUE) { + if (mode == GCRY_CIPHER_MODE_GCM_SIV || mode == GCRY_CIPHER_MODE_SIV) + { + gcry_cipher_set_decryption_tag(tmp_hd, mac, mac_size); + } gcry_error = gcry_cipher_decrypt(tmp_hd, data_out, // plaintext output len_data_out, // length of data @@ -912,6 +922,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_decrypt error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error)); gcry_cipher_close(tmp_hd); status = CRYPTO_LIB_ERR_DECRYPT_ERROR; return status; @@ -927,6 +938,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_decrypt error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); + printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error)); gcry_cipher_close(tmp_hd); status = CRYPTO_LIB_ERR_DECRYPT_ERROR; return status; @@ -969,7 +981,7 @@ static int32_t cryptography_aead_decrypt(uint8_t* data_out, size_t len_data_out, if ((gcry_error & GPG_ERR_CODE_MASK) != GPG_ERR_NO_ERROR) { printf(KRED "ERROR: gcry_cipher_checktag error code %d\n" RESET, gcry_error & GPG_ERR_CODE_MASK); - fprintf(stderr, "gcry_cipher_decrypt failed: %s\n", gpg_strerror(gcry_error)); + printf(KRED "Failure: %s/%s\n", gcry_strsource(gcry_error), gcry_strerror(gcry_error)); gcry_cipher_close(tmp_hd); status = CRYPTO_LIB_ERR_MAC_VALIDATION_ERROR; return status; @@ -1023,6 +1035,9 @@ int32_t cryptography_get_ecs_algo(int8_t algo_enum) case CRYPTO_CIPHER_AES256_GCM: algo = GCRY_CIPHER_AES256; break; + case CRYPTO_CIPHER_AES256_GCM_SIV: + algo = GCRY_CIPHER_AES256; + break; case CRYPTO_CIPHER_AES256_CBC: algo = GCRY_CIPHER_AES256; break; @@ -1053,6 +1068,9 @@ int32_t cryptography_get_ecs_mode(int8_t algo_enum) case CRYPTO_CIPHER_AES256_GCM: mode = GCRY_CIPHER_MODE_GCM; break; + case CRYPTO_CIPHER_AES256_GCM_SIV: + mode = GCRY_CIPHER_MODE_GCM_SIV; + break; case CRYPTO_CIPHER_AES256_CBC: mode = GCRY_CIPHER_MODE_CBC; break; diff --git a/src/crypto/wolfssl/cryptography_interface_wolfssl.template.c b/src/crypto/wolfssl/cryptography_interface_wolfssl.template.c index b668381d..238f1e4b 100644 --- a/src/crypto/wolfssl/cryptography_interface_wolfssl.template.c +++ b/src/crypto/wolfssl/cryptography_interface_wolfssl.template.c @@ -422,6 +422,7 @@ static int32_t cryptography_encrypt(uint8_t* data_out, size_t len_data_out, } break; + case CRYPTO_CIPHER_AES256_CBC: status = wc_AesSetKey(&enc, key, len_key, iv, AES_ENCRYPTION); if (status == 0) diff --git a/support/Dockerfile b/support/Dockerfile index b92f2856..08b55592 100644 --- a/support/Dockerfile +++ b/support/Dockerfile @@ -5,13 +5,11 @@ # ARG WOLFSSL_VERSION=5.6.0-stable -FROM ubuntu +FROM ubuntu:jammy-20240212 AS CL0 -ARG WOLFSSL_VERSION - -RUN set -eux \ - # install deps - && buildDeps=' \ +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update -y \ + && apt-get install -y \ autoconf \ automake \ ca-certificates \ @@ -26,25 +24,39 @@ RUN set -eux \ libcurl4-openssl-dev \ libmariadb-dev \ libmariadb-dev-compat \ - libgcrypt20-dev \ libtool \ make \ python3-dev \ python3-pip \ unzip \ - ' \ - && apt-get update \ - && apt-get install -y --no-install-recommends $buildDeps \ - && rm -r /var/lib/apt/lists/* \ + && rm -rf /var/lib/apt/lists/* \ + && pip3 install pycryptodome + +FROM CL0 AS CL1 +ARG GPG_ERROR_VERSION=1.50 +ARG GCRYPT_VERSION=1.11.0 +RUN curl \ + -LS https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-${GPG_ERROR_VERSION}.tar.bz2 \ + -o /tmp/libgpg-error-${GPG_ERROR_VERSION}.tar.bz2 \ + && tar -xjf /tmp/libgpg-error-${GPG_ERROR_VERSION}.tar.bz2 -C /tmp/ \ + && cd /tmp/libgpg-error-${GPG_ERROR_VERSION} \ + && ./configure \ + && make install \ + && curl \ + -LS https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-${GCRYPT_VERSION}.tar.bz2 \ + -o /tmp/libgcrypt-${GCRYPT_VERSION}.tar.bz2 \ + && tar -xjf /tmp/libgcrypt-${GCRYPT_VERSION}.tar.bz2 -C /tmp/ \ + && cd /tmp/libgcrypt-${GCRYPT_VERSION} \ + && ./configure \ + && make install - # download source files - && curl \ +FROM CL1 AS CL2 +ARG WOLFSSL_VERSION=5.6.0-stable +RUN curl \ -LS https://github.com/wolfSSL/wolfssl/archive/v${WOLFSSL_VERSION}.zip \ -o v${WOLFSSL_VERSION}.zip \ && unzip v${WOLFSSL_VERSION}.zip \ && rm v${WOLFSSL_VERSION}.zip \ - - # build and install wolfssl && cd wolfssl-${WOLFSSL_VERSION} \ && mkdir -p build \ && cd build \ @@ -52,10 +64,3 @@ RUN set -eux \ && cmake --build . \ && make install \ && ldconfig - - # cleanup - #&& cd .. \ - #&& rm -r wolfssl-${WOLFSSL_VERSION} - #&& apt-get purge -y --auto-remove $buildDeps - -RUN pip3 install pycryptodome diff --git a/support/scripts/build_rhel.sh b/support/scripts/build_rhel.sh index 9f711589..644fa9b3 100755 --- a/support/scripts/build_rhel.sh +++ b/support/scripts/build_rhel.sh @@ -12,3 +12,4 @@ source $SCRIPT_DIR/env.sh rm $BASE_DIR/CMakeCache.txt cmake $BASE_DIR -DCODECOV=1 -DDEBUG=1 -DMC_INTERNAL=1 -DTEST=1 -DTEST_ENC=1 -DSA_FILE=1 && make && make test + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ac9352a8..4973346f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -57,6 +57,12 @@ add_test(NAME UT_TM_PROCESS COMMAND ${PROJECT_BINARY_DIR}/bin/ut_tm_process WORKING_DIRECTORY ${PROJECT_TEST_DIR}) +if(NOT ${CRYPTO_WOLFSSL}) + add_test(NAME UT_AES_GCM_SIV + COMMAND ${PROJECT_BINARY_DIR}/bin/ut_aes_gcm_siv + WORKING_DIRECTORY ${PROJECT_TEST_DIR}) +endif() + if(SA_FILE) add_test(NAME UT_SA_SAVE COMMAND ${PROJECT_BINARY_DIR}/bin/ut_sa_save diff --git a/test/include/ut_aes_gcm_siv.h b/test/include/ut_aes_gcm_siv.h new file mode 100644 index 00000000..99fb7572 --- /dev/null +++ b/test/include/ut_aes_gcm_siv.h @@ -0,0 +1,18 @@ +#ifndef CRYPTOLIB_UT_AES_GCM_SIV_H +#define CRYPTOLIB_UT_AES_GCM_SIV_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "crypto.h" +#include "shared_util.h" +#include +#include "cryptography_interface.h" + +#ifdef __cplusplus +} /* Close scope of 'extern "C"' declaration which encloses file. */ +#endif + +#endif //CRYPTOLIB_UT_AES_GCM_SIV_H \ No newline at end of file diff --git a/test/unit/ut_aes_gcm_siv.c b/test/unit/ut_aes_gcm_siv.c new file mode 100644 index 00000000..8610ffdd --- /dev/null +++ b/test/unit/ut_aes_gcm_siv.c @@ -0,0 +1,474 @@ +// /* Copyright (C) 2009 - 2022 National Aeronautics and Space Admirfcration. +// All Foreign Rights are Reserved to the U.S. Government. + +// This software is provided "as is" without any warranty of any kind, either expressed, implied, or statutory, +// including, but not limited to, any warranty that the software will conform to specifications, any implied warranties +// of merchantability, fitness for a particular purpose, and freedom from infringement, and any warranty that the +// documentation will conform to the program, or any warranty that the software will be error free. + +// In no event shall NASA be liable for any damages, including, but not limited to direct, indirect, special or +// consequential damages, arising out of, resulting from, or in any way connected with the software or its +// documentation, whether or not based upon warranty, contract, tort or otherwise, and whether or not loss was sustained +// from, or arose out of the results of, or use of, the software, documentation or services provided hereunder. + +// ITC Team +// NASA IV&V +// jstar-development-team@mail.nasa.gov +// */ + +#include "ut_aes_gcm_siv.h" +#include "crypto.h" +#include "crypto_error.h" +#include "sa_interface.h" +#include "utest.h" + +/** + * @brief Unit Test: Crypto ECS Get Algorithm key length response for AES-GCM-SIV + **/ +UTEST(AES_GCM_SIV, GET_ECS_ALGO_KEY_LEN_SIV) +{ + remove("sa_save_file.bin"); + int32_t algo_keylen = -1; + uint8_t crypto_algo = CRYPTO_CIPHER_AES256_GCM_SIV; + algo_keylen = Crypto_Get_ACS_Algo_Keylen(crypto_algo); + ASSERT_EQ(algo_keylen, 32); + Crypto_Shutdown(); +} + +/** + * @brief Unit Test: Crypto ECS Get Algorithm response for AES-GCM-SIV + **/ +UTEST(AES_GCM_SIV, GET_ECS_ALGO_SIV) +{ + remove("sa_save_file.bin"); + Crypto_Init_TC_Unit_Test(); + int32_t libgcrypt_algo = -1; + int8_t crypto_algo = CRYPTO_CIPHER_AES256_GCM_SIV; + + libgcrypt_algo = cryptography_if->cryptography_get_ecs_algo(crypto_algo); + ASSERT_EQ(libgcrypt_algo, 9); + Crypto_Shutdown(); +} + +/** + * @brief Validation Test: AEAD_AES_256_GCM_SIV Test Vectors + * Reference: + * https://datatracker.ietf.org/doc/rfc8452/?include_text=1 C.2. Second Example + * Recreated test vectors with https://github.com/line/aes-gcm-siv/tree/master, then input CryptoLib test vectors to generate truth data. + **/ +UTEST(AES_GCM_SIV, AES_GCM_SIV_256_KEY_32_PT_8_ENC_TEST_1) +{ + remove("sa_save_file.bin"); + uint8_t* ptr_enc_frame = NULL; + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + crypto_key_t* ekp = NULL; + + // RFC supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char* buffer_rfc_pt_h = "2003000c000100000000000000"; + char* buffer_rfc_aad_h = ""; + char* buffer_rfc_key_h = "0100000000000000000000000000000000000000000000000000000000000000"; + char* buffer_rfc_nonce_h = "030000000000000000000000"; + char* buffer_rfc_ct_h = "4fa7a4cb7d3434f8a2855b40016daccb62a454551878fc26"; + uint8_t* buffer_rfc_pt_b, *buffer_rfc_aad_b, *buffer_rfc_key_b, *buffer_rfc_nonce_b, *buffer_rfc_ct_b = NULL; + int buffer_rfc_pt_len, buffer_rfc_aad_len, buffer_rfc_key_len, buffer_rfc_nonce_len, buffer_rfc_ct_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t* test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sa_if->sa_get_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sa_if->sa_get_from_spi(9, &test_association); + test_association->arsn_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->ast = 1; + test_association->est = 1; + test_association->ecs_len = 1; + test_association->ecs = CRYPTO_CIPHER_AES256_GCM_SIV; + test_association->acs_len = 1; + test_association->acs = CRYPTO_MAC_CMAC_AES256; + test_association->stmacf_len = 16; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_rfc_key_h, (char**) &buffer_rfc_key_b, &buffer_rfc_key_len); + ekp = key_if->get_key(test_association->ekid); + memcpy(ekp->value, buffer_rfc_key_b, buffer_rfc_key_len); + + // Convert input plaintext + // TODO: Account for length of header and FECF (5+2) + hex_conversion(buffer_rfc_pt_h, (char**) &buffer_rfc_pt_b, &buffer_rfc_pt_len); + // Convert/Set input AAD + hex_conversion(buffer_rfc_aad_h, (char**) &buffer_rfc_aad_b, &buffer_rfc_aad_len); + memcpy(test_association->abm, buffer_rfc_aad_b + 5, buffer_rfc_aad_len); + hex_conversion(buffer_rfc_nonce_h, (char**) &buffer_rfc_nonce_b, &buffer_rfc_nonce_len); + memcpy(test_association->iv, buffer_rfc_nonce_b, buffer_rfc_nonce_len); + // Convert input ciphertext + hex_conversion(buffer_rfc_ct_h, (char**) &buffer_rfc_ct_b, &buffer_rfc_ct_len); + + Crypto_TC_ApplySecurity(buffer_rfc_pt_b, buffer_rfc_pt_len, &ptr_enc_frame, &enc_frame_len); + // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_rfc_ct_len; + Crypto_Shutdown(); + for (int i = 0; i < buffer_rfc_pt_len - 7; i++) + { + printf("[%d]: %02x -> %02x \n", i, *(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + enc_data_idx++; + } + //ASSERT_EQ(1,0); + free(ptr_enc_frame); + free(buffer_rfc_pt_b); + free(buffer_rfc_aad_b); + free(buffer_rfc_nonce_b); + free(buffer_rfc_ct_b); + free(buffer_rfc_key_b); +} + +/** + * @brief Validation Test: AEAD_AES_256_GCM_SIV Test Vectors + * Reference: + * https://datatracker.ietf.org/doc/rfc8452/?include_text=1 C.2. Second Example + * Recreated test vectors with https://github.com/line/aes-gcm-siv/tree/master, then input CryptoLib test vectors to generate truth data. + **/ +UTEST(AES_GCM_SIV, AES_GCM_SIV_256_KEY_32_PT_8_DEC_TEST_1) +{ + remove("sa_save_file.bin"); + uint8_t* ptr_enc_frame = NULL; + + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_FALSE); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + crypto_key_t* ekp = NULL; + + // rfc supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char* buffer_rfc_key_h = "0100000000000000000000000000000000000000000000000000000000000000"; + char* buffer_rfc_pt_h = "2003000c000100000000000000"; + char* buffer_rfc_aad_h = ""; + char* buffer_rfc_nonce_h = "030000000000000000000000"; + char* buffer_rfc_et_h = "2003002a0000090300000000000000000000004fa7a4cb7d3434f8a2855b40016daccb62a454551878fc26"; + uint8_t* buffer_rfc_pt_b, *buffer_rfc_nonce_b, *buffer_rfc_et_b, *buffer_rfc_key_b, *buffer_rfc_aad_b = NULL; + int buffer_rfc_pt_len, buffer_rfc_nonce_len, buffer_rfc_et_len, buffer_rfc_key_len, buffer_rfc_aad_len = 0; + + // Setup Processed Frame For Decryption + TC_t* tc_rfc_processed_frame; + tc_rfc_processed_frame = malloc(sizeof(uint8_t) * TC_SIZE); + + // Expose/setup SAs for testing + SecurityAssociation_t* test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sa_if->sa_get_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sa_if->sa_get_from_spi(9, &test_association); + test_association->arsn_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->ast = 1; + test_association->est = 1; + test_association->ecs_len = 1; + test_association->ecs = CRYPTO_CIPHER_AES256_GCM_SIV; + test_association->stmacf_len = 16; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_rfc_key_h, (char**) &buffer_rfc_key_b, &buffer_rfc_key_len); + ekp = key_if->get_key(test_association->ekid); + memcpy(ekp->value, buffer_rfc_key_b, buffer_rfc_key_len); + + // Convert input plaintext + // TODO: Account for length of header and FECF (5+2) + hex_conversion(buffer_rfc_pt_h, (char**) &buffer_rfc_pt_b, &buffer_rfc_pt_len); + // Convert/Set input nonce + hex_conversion(buffer_rfc_nonce_h, (char**) &buffer_rfc_nonce_b, &buffer_rfc_nonce_len); + memcpy(test_association->iv, buffer_rfc_nonce_b, buffer_rfc_nonce_len); + hex_conversion(buffer_rfc_aad_h, (char**) &buffer_rfc_aad_b, &buffer_rfc_aad_len); + // Convert input encryptedtext + hex_conversion(buffer_rfc_et_h, (char**) &buffer_rfc_et_b, &buffer_rfc_et_len); + + Crypto_TC_ProcessSecurity(buffer_rfc_et_b, &buffer_rfc_et_len, tc_rfc_processed_frame); + + for (int i = 0; i < tc_rfc_processed_frame->tc_pdu_len; i++) + { + + if (buffer_rfc_pt_b[i + 5] != tc_rfc_processed_frame->tc_pdu[i]) + { + printf("[%d]: %02x -> %02x \n", i, buffer_rfc_pt_b[i + 5], tc_rfc_processed_frame->tc_pdu[i]); + } + ASSERT_EQ(buffer_rfc_pt_b[i + 5], tc_rfc_processed_frame->tc_pdu[i]); + } + Crypto_Shutdown(); + free(ptr_enc_frame); + free(buffer_rfc_pt_b); + free(buffer_rfc_nonce_b); + free(buffer_rfc_aad_b); + free(buffer_rfc_et_b); + free(buffer_rfc_key_b); +} + +/** + * @brief Validation Test: AEAD_AES_256_GCM_SIV Test Vectors + * Reference: + * https://datatracker.ietf.org/doc/rfc8452/?include_text=1 C.2. + * Recreated test vectors with https://github.com/line/aes-gcm-siv/tree/master, then input CryptoLib test vectors to generate truth data. + **/ +UTEST(AES_GCM_SIV, AES_GCM_SIV_256_KEY_32_PT_8_ENC_TEST_2) +{ + remove("sa_save_file.bin"); + uint8_t* ptr_enc_frame = NULL; + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_NO_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + crypto_key_t* ekp = NULL; + + // RFC supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char* buffer_rfc_pt_h = "2003001000010000000000000000000000"; + char* buffer_rfc_aad_h = ""; + char* buffer_rfc_key_h = "0100000000000000000000000000000000000000000000000000000000000000"; + char* buffer_rfc_nonce_h = "030000000000000000000000"; + char *buffer_rfc_ct_h = "08fbd140589f067e2772b4a1480eefe49f5ec5c2e65c135e1ad51c58"; + uint8_t* buffer_rfc_pt_b, *buffer_rfc_aad_b, *buffer_rfc_key_b, *buffer_rfc_nonce_b, *buffer_rfc_ct_b = NULL; + int buffer_rfc_pt_len, buffer_rfc_aad_len, buffer_rfc_key_len, buffer_rfc_nonce_len, buffer_rfc_ct_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t* test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sa_if->sa_get_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sa_if->sa_get_from_spi(9, &test_association); + test_association->arsn_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->ast = 1; + test_association->est = 1; + test_association->ecs_len = 1; + test_association->ecs = CRYPTO_CIPHER_AES256_GCM_SIV; + test_association->acs_len = 1; + test_association->acs = CRYPTO_MAC_CMAC_AES256; + test_association->stmacf_len = 16; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_rfc_key_h, (char**) &buffer_rfc_key_b, &buffer_rfc_key_len); + ekp = key_if->get_key(test_association->ekid); + memcpy(ekp->value, buffer_rfc_key_b, buffer_rfc_key_len); + + // Convert input plaintext + // TODO: Account for length of header and FECF (5+2) + hex_conversion(buffer_rfc_pt_h, (char**) &buffer_rfc_pt_b, &buffer_rfc_pt_len); + // Convert/Set input AAD + hex_conversion(buffer_rfc_aad_h, (char**) &buffer_rfc_aad_b, &buffer_rfc_aad_len); + memcpy(test_association->abm, buffer_rfc_aad_b + 5, buffer_rfc_aad_len); + hex_conversion(buffer_rfc_nonce_h, (char**) &buffer_rfc_nonce_b, &buffer_rfc_nonce_len); + memcpy(test_association->iv, buffer_rfc_nonce_b, buffer_rfc_nonce_len); + // Convert input ciphertext + hex_conversion(buffer_rfc_ct_h, (char**) &buffer_rfc_ct_b, &buffer_rfc_ct_len); + + Crypto_TC_ApplySecurity(buffer_rfc_pt_b, buffer_rfc_pt_len, &ptr_enc_frame, &enc_frame_len); + // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_rfc_ct_len; + Crypto_Shutdown(); + for (int i = 0; i < buffer_rfc_pt_len - 7; i++) + { + printf("[%d]: %02x -> %02x \n", i, *(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + enc_data_idx++; + } + free(ptr_enc_frame); + free(buffer_rfc_pt_b); + free(buffer_rfc_aad_b); + free(buffer_rfc_nonce_b); + free(buffer_rfc_ct_b); + free(buffer_rfc_key_b); +} + +/** + * @brief Validation Test: AEAD_AES_256_GCM_SIV Test Vectors + * Reference: + * https://datatracker.ietf.org/doc/rfc8452/?include_text=1 C.2. + * Recreated test vectors with https://github.com/line/aes-gcm-siv/tree/master, then input CryptoLib test vectors to generate truth data. + **/ +UTEST(AES_GCM_SIV, AES_GCM_SIV_256_KEY_32_PT_20_WITH_AAD_ENC_TEST_1) +{ + remove("sa_save_file.bin"); + uint8_t* ptr_enc_frame = NULL; + uint16_t enc_frame_len = 0; + // Setup & Initialize CryptoLib + // Crypto_Init_TC_Unit_Test(); + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_FALSE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_FALSE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_TRUE); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + crypto_key_t* ekp = NULL; + + // RFC8452 supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char* buffer_rfc_pt_h = "20030018000300000000000000000000000000000004000000"; + char* buffer_rfc_aad_h = "010000000000000000000000000000000200"; + char* buffer_rfc_key_h = "0100000000000000000000000000000000000000000000000000000000000000"; + char* buffer_rfc_nonce_h = "030000000000000000000000"; + char* buffer_rfc_ct_h = "e6e883db43a9ef98fa6271cb7d4834139acf479e3b910775e769286f3f59d2e588f69b06"; + uint8_t* buffer_rfc_pt_b, *buffer_rfc_aad_b, *buffer_rfc_key_b, *buffer_rfc_nonce_b, *buffer_rfc_ct_b = NULL; + int buffer_rfc_pt_len, buffer_rfc_aad_len, buffer_rfc_key_len, buffer_rfc_nonce_len, buffer_rfc_ct_len = 0; + + // Expose/setup SAs for testing + SecurityAssociation_t* test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sa_if->sa_get_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sa_if->sa_get_from_spi(9, &test_association); + test_association->arsn_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->ast = 1; + test_association->est = 1; + test_association->ecs_len = 1; + test_association->ecs = CRYPTO_CIPHER_AES256_GCM_SIV; + test_association->acs_len = 1; + test_association->acs = CRYPTO_MAC_CMAC_AES256; + test_association->stmacf_len = 16; + + // Insert key into keyring of SA 9 + hex_conversion(buffer_rfc_key_h, (char**) &buffer_rfc_key_b, &buffer_rfc_key_len); + ekp = key_if->get_key(test_association->ekid); + memcpy(ekp->value, buffer_rfc_key_b, buffer_rfc_key_len); + + // Convert input plaintext + // TODO: Account for length of header and FECF (5+2) + hex_conversion(buffer_rfc_pt_h, (char**) &buffer_rfc_pt_b, &buffer_rfc_pt_len); + // Convert/Set input AAD + hex_conversion(buffer_rfc_aad_h, (char**) &buffer_rfc_aad_b, &buffer_rfc_aad_len); + memcpy(test_association->abm, buffer_rfc_aad_b, buffer_rfc_aad_len); + hex_conversion(buffer_rfc_nonce_h, (char**) &buffer_rfc_nonce_b, &buffer_rfc_nonce_len); + memcpy(test_association->iv, buffer_rfc_nonce_b, buffer_rfc_nonce_len); + // Convert input ciphertext + hex_conversion(buffer_rfc_ct_h, (char**) &buffer_rfc_ct_b, &buffer_rfc_ct_len); + + Crypto_TC_ApplySecurity(buffer_rfc_pt_b, buffer_rfc_pt_len, &ptr_enc_frame, &enc_frame_len); + // Note: For comparison, interested in the TF payload (exclude headers and FECF if present) + // Calc payload index: total length - pt length + uint16_t enc_data_idx = enc_frame_len - buffer_rfc_ct_len; + Crypto_Shutdown(); + for (int i = 0; i < buffer_rfc_pt_len - 7; i++) + { + printf("[%d]: %02x -> %02x \n", i, *(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + ASSERT_EQ(*(ptr_enc_frame + enc_data_idx), buffer_rfc_ct_b[i]); + enc_data_idx++; + } + free(ptr_enc_frame); + free(buffer_rfc_pt_b); + free(buffer_rfc_aad_b); + free(buffer_rfc_nonce_b); + free(buffer_rfc_ct_b); + free(buffer_rfc_key_b); +} + +/** + * @brief Validation Test: AEAD_AES_256_GCM_SIV Test Vectors + * Reference: + * https://datatracker.ietf.org/doc/rfc8452/?include_text=1 C.2. Second Example + * Recreated test vectors with https://github.com/line/aes-gcm-siv/tree/master, then input CryptoLib test vectors to generate truth data. + **/ +UTEST(AES_GCM_SIV, AES_GCM_SIV_256_KEY_32_PT_20_WITH_AAD_DEC_TEST_1) +{ + remove("sa_save_file.bin"); + uint8_t* ptr_enc_frame = NULL; + + // Setup & Initialize CryptoLib + Crypto_Config_CryptoLib(KEY_TYPE_INTERNAL, MC_TYPE_INTERNAL, SA_TYPE_INMEMORY, CRYPTOGRAPHY_TYPE_LIBGCRYPT, + IV_INTERNAL, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR, + TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_FALSE, + TC_CHECK_FECF_TRUE, 0x3F, SA_INCREMENT_NONTRANSMITTED_IV_FALSE); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_NO_FECF, TC_NO_SEGMENT_HDRS, TC_OCF_NA, 1024, AOS_FHEC_NA, AOS_IZ_NA, 0); + Crypto_Init(); + SaInterface sa_if = get_sa_interface_inmemory(); + crypto_key_t* ekp = NULL; + + // rfc supplied vectors + // NOTE: Added Transfer Frame header to the plaintext + char* buffer_rfc_pt_h = "20030018000300000000000000000000000000000004000000"; + char* buffer_rfc_key_h = "0100000000000000000000000000000000000000000000000000000000000000"; + char* buffer_rfc_et_h = "20030036000009030000000000000000000000e6e883db43a9ef98fa6271cb7d4834139acf479e3b910775e769286f3f59d2e588f69b06"; + uint8_t* buffer_rfc_pt_b, *buffer_rfc_et_b, *buffer_rfc_key_b = NULL; + int buffer_rfc_pt_len, buffer_rfc_et_len, buffer_rfc_key_len = 0; + + // Setup Processed Frame For Decryption + TC_t* tc_rfc_processed_frame; + tc_rfc_processed_frame = malloc(sizeof(uint8_t) * TC_SIZE); + + // Expose/setup SAs for testing + SecurityAssociation_t* test_association = NULL; + test_association = malloc(sizeof(SecurityAssociation_t) * sizeof(uint8_t)); + // Deactivate SA 1 + sa_if->sa_get_from_spi(1, &test_association); + test_association->sa_state = SA_NONE; + // Activate SA 9 + sa_if->sa_get_from_spi(9, &test_association); + test_association->arsn_len = 0; + test_association->sa_state = SA_OPERATIONAL; + test_association->ast = 1; + test_association->est = 1; + test_association->ecs_len = 1; + test_association->ecs = CRYPTO_CIPHER_AES256_GCM_SIV; + test_association->stmacf_len = 16; + // Insert key into keyring of SA 9 + hex_conversion(buffer_rfc_key_h, (char**) &buffer_rfc_key_b, &buffer_rfc_key_len); + ekp = key_if->get_key(test_association->ekid); + memcpy(ekp->value, buffer_rfc_key_b, buffer_rfc_key_len); + + // Convert input plaintext + hex_conversion(buffer_rfc_pt_h, (char**) &buffer_rfc_pt_b, &buffer_rfc_pt_len); + // Convert input encryptedtext + hex_conversion(buffer_rfc_et_h, (char**) &buffer_rfc_et_b, &buffer_rfc_et_len); + + Crypto_TC_ProcessSecurity(buffer_rfc_et_b, &buffer_rfc_et_len, tc_rfc_processed_frame); + + for (int i = 0; i < tc_rfc_processed_frame->tc_pdu_len; i++) + { + if (buffer_rfc_pt_b[i + 5] != tc_rfc_processed_frame->tc_pdu[i]) + { + printf("[%d]: %02x -> %02x \n", i, buffer_rfc_pt_b[i + 5], tc_rfc_processed_frame->tc_pdu[i]); + } + ASSERT_EQ(buffer_rfc_pt_b[i + 5], tc_rfc_processed_frame->tc_pdu[i]); + } + + Crypto_Shutdown(); + free(ptr_enc_frame); + free(buffer_rfc_pt_b); + free(buffer_rfc_et_b); + free(buffer_rfc_key_b); +} + +UTEST_MAIN(); \ No newline at end of file diff --git a/test/unit/ut_crypto.c b/test/unit/ut_crypto.c index e4ab24f8..1f1dfe60 100644 --- a/test/unit/ut_crypto.c +++ b/test/unit/ut_crypto.c @@ -274,6 +274,7 @@ UTEST(CRYPTO_C, EXT_PROC_PDU) UTEST(CRYPTO_C, GET_ACS_ALGO) { remove("sa_save_file.bin"); + Crypto_Init_TC_Unit_Test(); int32_t libgcrypt_algo = -1; uint8_t crypto_algo = CRYPTO_MAC_CMAC_AES256; @@ -312,6 +313,7 @@ UTEST(CRYPTO_C, GET_ACS_ALGO_KEY_LEN) UTEST(CRYPTO_C, GET_ECS_ALGO) { remove("sa_save_file.bin"); + Crypto_Init_TC_Unit_Test(); int32_t libgcrypt_algo = -1; int8_t crypto_algo = CRYPTO_CIPHER_AES256_GCM;