diff --git a/CMakeLists.txt b/CMakeLists.txt index b584e49207..116b8a55d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,27 +83,6 @@ else() include_directories(${OPENPGM_INCLUDE_DIRS}) endif() -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - pkg_search_module(XPM xpm) if(NOT ${XPM_FOUND}) message("PACKAGE xpm not found: some targets will fail") @@ -847,12 +826,17 @@ set(SECU_OSA_SRC ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eea.c ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c - ) -add_library(SECU_OSA ${SECU_OSA_SRC}) -target_link_libraries(SECU_OSA ${NETTLE_LIBRARIES}) + ) +add_library(SECU_OSA ${SECU_OSA_SRC} $ ) + +target_include_directories(SECU_OSA PRIVATE ${OPENAIR_DIR}/common/utils/ds/) set(SECU_CN_SRC + ${OPENAIR3_DIR}/SECU/secu_defs.c ${OPENAIR3_DIR}/SECU/kdf.c + ${OPENAIR3_DIR}/SECU/aes_128_ctr.c + ${OPENAIR3_DIR}/SECU/aes_128_cbc_cmac.c + ${OPENAIR3_DIR}/SECU/sha_256_hmac.c ${OPENAIR3_DIR}/SECU/rijndael.c ${OPENAIR3_DIR}/SECU/snow3g.c ${OPENAIR3_DIR}/SECU/key_nas_deriver.c @@ -861,9 +845,9 @@ set(SECU_CN_SRC ${OPENAIR3_DIR}/SECU/nas_stream_eea2.c ${OPENAIR3_DIR}/SECU/nas_stream_eia2.c ) -add_library(SECU_CN ${SECU_CN_SRC}) -target_link_libraries(SECU_CN ${NETTLE_LIBRARIES}) +add_library(SECU_CN ${SECU_CN_SRC} $) +target_include_directories(SECU_CN PRIVATE ${OPENAIR_DIR}/common/utils/ds/) # Physical Channel Procedures Scheduling ################################" @@ -1995,8 +1979,13 @@ add_library(LIB_NAS_SIMUE ${libnas_ue_esm_sap_OBJS} ${libnrnas_emm_msg_OBJS} ${libnrnas_ies_OBJS} + $ ) +target_include_directories(LIB_NAS_SIMUE PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_NAS_SIMUE PRIVATE lte_rrc) + + + set(NAS_SIM_LIB LIB_NAS_SIMUE) target_link_libraries(LIB_NAS_SIMUE PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2016,7 +2005,9 @@ add_library(LIB_NAS_UE ${libnas_ue_emm_sap_OBJS} ${libnas_ue_esm_OBJS} ${libnas_ue_esm_sap_OBJS} + $ ) +target_include_directories(LIB_NAS_UE PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_NAS_UE PRIVATE lte_rrc) set(NAS_UE_LIB LIB_NAS_UE) target_link_libraries(LIB_NAS_UE PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2048,6 +2039,8 @@ add_library(LIB_5GNAS_GNB ${NAS_SRC}/NR_UE/ue_process_nas.c ${OPENAIR3_DIR}//UICC/usim_interface.c ) + +target_include_directories(LIB_5GNAS_GNB PRIVATE ${OPENAIR_DIR}/common/utils/ds/) target_link_libraries(LIB_5GNAS_GNB PRIVATE SECU_CN ${CRYPTO_LIBRARIES}) target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2417,7 +2410,7 @@ add_executable(nr-cuup target_link_libraries(nr-cuup PRIVATE CONFIG_LIB ITTI SCTP_CLIENT GTPV1U e1ap e1_pdcp_if f1ap - SECU_OSA ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) + SECU_OSA SECU_CN ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc asn1_nr_rrc) # nr-uesoftmodem is UE implementation @@ -2676,8 +2669,7 @@ endforeach(myExe) foreach(myExe s1ap secu_knas_encrypt_eia1 secu_kenb - aes128_ctr_encrypt - aes128_ctr_decrypt + aes128_ctr secu_knas_encrypt_eea2 secu_knas secu_knas_encrypt_eea1 kdf @@ -2807,6 +2799,7 @@ include (common/utils/telnetsrv/telnetsrv_CMakeLists.txt) include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt) include (${OPENAIR_DIR}/common/utils/websrv/websrv_CMakeLists.txt) +add_subdirectory(common) add_subdirectory(doc) add_subdirectory(openair2) add_subdirectory(openair3) diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index a8f5932045..d2d5db704e 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -86,49 +86,8 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototype set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2") -##This is to detect nettle version changes between Ubuntu 14.04/16.04 -#set ( nettle_cmd "nettle-hash" ) -#set ( nettle_arg "-V" ) -#execute_process(COMMAND ${nettle_cmd} ${nettle_arg} RESULT_VARIABLE rv OUTPUT_VARIABLE ov ERROR_VARIABLE ev) -# -#string(REGEX MATCH "[+-]?[0-9]+([.][0-9]+)?" nv ${ov}) -# -#message("NETTLE_VERSION = ${nv}") -# -## we need to remove decimal as floating point arithematic does not work properly with C preprocessor -#STRING(REGEX REPLACE "[.]" "" nv ${nv}) -# -#if ("${nv}" STREQUAL "") -# message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -#endif() -# -#set (NETTLE_VERSION "${nv}") -#add_definitions("-DNETTLE_VERSION=${NETTLE_VERSION}") - include(FindPkgConfig) -pkg_search_module(NETTLE nettle) -if(NOT ${NETTLE_FOUND}) - message( FATAL_ERROR "PACKAGE nettle not found: some targets will fail. Run build_oai -I again!") -else() - include_directories(${NETTLE_INCLUDE_DIRS}) -endif() - -message ("NETTLE VERSION_INSTALLED = ${NETTLE_VERSION}") - -string(REGEX REPLACE "([0-9]+).*" "\\1" NETTLE_VERSION_MAJOR ${NETTLE_VERSION}) -string(REGEX REPLACE "[0-9]+\\.([0-9]+).*" "\\1" NETTLE_VERSION_MINOR ${NETTLE_VERSION}) -message ("NETTLE_VERSION_MAJOR = ${NETTLE_VERSION_MAJOR}") -message ("NETTLE_VERSION_MINOR = ${NETTLE_VERSION_MINOR}") - -if ("${NETTLE_VERSION_MAJOR}" STREQUAL "" OR "${NETTLE_VERSION_MINOR}" STREQUAL "") - message( FATAL_ERROR "The nettle version not detected properly. Try to run build_oai -I again" ) -endif() - -add_definitions("-DNETTLE_VERSION_MAJOR=${NETTLE_VERSION_MAJOR}") -add_definitions("-DNETTLE_VERSION_MINOR=${NETTLE_VERSION_MINOR}") - - pkg_search_module(OPENSSL openssl REQUIRED) include_directories(${OPENSSL_INCLUDE_DIRS}) @@ -159,6 +118,9 @@ add_boolean_option(NAS_MME False "NAS_UE and NAS_MME are incompa # SECU LIB ################################################################################ set(secu_cn_SRC + ${OPENAIR3_DIR}/SECU/aes_128_ctr.c + ${OPENAIR3_DIR}/SECU/aes_128_cbc_cmac.c + ${OPENAIR3_DIR}/SECU/sha_256_hmac.c ${OPENAIR3_DIR}/SECU/kdf.c ${OPENAIR3_DIR}/SECU/rijndael.c ${OPENAIR3_DIR}/SECU/snow3g.c @@ -719,7 +681,6 @@ target_link_libraries (at_nas_ue -Wl,-whole-archive api_network api_user api_usim emm esm ies util secu_cn -Wl,-no-whole-archive - ${NETTLE_LIBRARIES} ${OPENSSL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} m ) diff --git a/cmake_targets/tools/MODULES/FindNettle.cmake b/cmake_targets/tools/MODULES/FindNettle.cmake deleted file mode 100755 index 4602e74997..0000000000 --- a/cmake_targets/tools/MODULES/FindNettle.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# Find the native Nettle includes, library, and flags -# -# NETTLE_INCLUDE_DIR - where to find nettle.h, etc. -# NETTLE_LIBRARIES - List of libraries when using Nettle. -# NETTLE_FOUND - True if Nettle found. -IF (NETTLE_INCLUDE_DIR) -# Already in cache, be silent - SET(NETTLE_FIND_QUIETLY TRUE) -ENDIF (NETTLE_INCLUDE_DIR) -FIND_PATH(NETTLE_INCLUDE_DIR nettle/nettle-meta.h) -SET(NETTLE_NAMES nettle) -FIND_LIBRARY(NETTLE_LIBRARY NAMES ${NETTLE_NAMES} ) -# handle the QUIETLY and REQUIRED arguments and set NETTLE_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(NETTLE DEFAULT_MSG NETTLE_LIBRARY NETTLE_INCLUDE_DIR) -IF(NETTLE_FOUND) - SET(NETTLE_LIBRARIES ${NETTLE_LIBRARY}) -ELSE(NETTLE_FOUND) - SET(NETTLE_LIBRARIES ) -ENDIF(NETTLE_FOUND) -MARK_AS_ADVANCED(NETTLE_LIBRARY NETTLE_INCLUDE_DIR) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 3efac9da50..5af626b182 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -617,7 +617,6 @@ check_install_oai_software() { openssl \ xxd - $SUDO apt-get install -y nettle-dev nettle-bin elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then if rpm -q epel-release > /dev/null; then @@ -642,16 +641,15 @@ check_install_oai_software() { libgcrypt-devel \ lksctp-tools \ lksctp-tools-devel \ - openssl-devel \ libtasn1 \ libtool \ libxslt-devel \ ninja-build \ make \ openssl \ + openssl-devel \ patch \ readline-devel \ - nettle-devel \ gnutls-devel \ lapack \ lapack-devel \ diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000000..512d2b1553 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(utils) diff --git a/common/utils/CMakeLists.txt b/common/utils/CMakeLists.txt new file mode 100644 index 0000000000..eb6a119968 --- /dev/null +++ b/common/utils/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(ds) diff --git a/common/utils/ds/CMakeLists.txt b/common/utils/ds/CMakeLists.txt new file mode 100644 index 0000000000..400d34ad06 --- /dev/null +++ b/common/utils/ds/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(ds OBJECT + byte_array.c +) + +target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/common/utils/ds/byte_array.c b/common/utils/ds/byte_array.c new file mode 100644 index 0000000000..04a2af0c5d --- /dev/null +++ b/common/utils/ds/byte_array.c @@ -0,0 +1,58 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "byte_array.h" + +#include "common/utils/assertions.h" +#include + +byte_array_t copy_byte_array(byte_array_t src) +{ + byte_array_t dst = {0}; + dst.buf = malloc(src.len); + DevAssert(dst.buf != NULL && "Memory exhausted"); + memcpy(dst.buf, src.buf, src.len); + dst.len = src.len; + return dst; +} + +void free_byte_array(byte_array_t ba) +{ + free(ba.buf); +} + +bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1) +{ + if (m0 == m1) + return true; + + if (m0 == NULL || m1 == NULL) + return false; + + if (m0->len != m1->len) + return false; + + const int rc = memcmp(m0->buf, m1->buf, m0->len); + if (rc != 0) + return false; + + return true; +} diff --git a/common/utils/ds/byte_array.h b/common/utils/ds/byte_array.h new file mode 100644 index 0000000000..f16fd7c01d --- /dev/null +++ b/common/utils/ds/byte_array.h @@ -0,0 +1,42 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef BYTE_ARRAY_H_OAI +#define BYTE_ARRAY_H_OAI + +#include +#include +#include + +typedef struct { + size_t len; + uint8_t* buf; +} byte_array_t; + +typedef struct { + uint8_t buf[32]; +} byte_array_32_t; + +byte_array_t copy_byte_array(byte_array_t src); +void free_byte_array(byte_array_t ba); +bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1); + +#endif diff --git a/common/utils/websrv/DOC/websrvuse.md b/common/utils/websrv/DOC/websrvuse.md index aac9a40ed4..9ba2c8ade1 100644 --- a/common/utils/websrv/DOC/websrvuse.md +++ b/common/utils/websrv/DOC/websrvuse.md @@ -15,9 +15,6 @@ OPENAIR_DIR = /usr/local/oai/oai-develop/openairinterface5g FreeDiameter prefix not found, install freeDiameter if EPC, HSS 3. building the compilation directives ... running cmake ../../.. -NETTLE VERSION_INSTALLED = 3.5.1 -NETTLE_VERSION_MAJOR = 3 -NETTLE_VERSION_MINOR = 5 cuda include /usr/include cuda library -- CMAKE_BUILD_TYPE is RelWithDebInfo @@ -61,9 +58,6 @@ Call Stack (most recent call first): FreeDiameter prefix not found, install freeDiameter if EPC, HSS 3. building the compilation directives ... running cmake ../../.. - NETTLE VERSION_INSTALLED = 3.5.1 - NETTLE_VERSION_MAJOR = 3 - NETTLE_VERSION_MINOR = 5 cuda include /usr/include cuda library -- CMAKE_BUILD_TYPE is RelWithDebInfo @@ -209,4 +203,4 @@ The interface should be intuitive enough, keeping in mind the following restrict Some front-end objects, which usage are less intuitive provide a tooltip to help interface usage. -[oai web serverinterface home](websrv.md) \ No newline at end of file +[oai web serverinterface home](websrv.md) diff --git a/docker/Dockerfile.eNB.rhel8.2 b/docker/Dockerfile.eNB.rhel8.2 index 38c5d8ae49..8d9f3098d5 100644 --- a/docker/Dockerfile.eNB.rhel8.2 +++ b/docker/Dockerfile.eNB.rhel8.2 @@ -39,7 +39,6 @@ ENV TZ=Europe/Paris RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ - nettle \ tzdata \ procps-ng \ atlas \ diff --git a/docker/Dockerfile.eNB.ubuntu18 b/docker/Dockerfile.eNB.ubuntu18 index f2a6ee16ee..1c85eb1232 100644 --- a/docker/Dockerfile.eNB.ubuntu18 +++ b/docker/Dockerfile.eNB.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ tzdata \ procps \ libsctp1 \ - libnettle6 \ libblas3 \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.gNB.aw2s.rhel8.2 b/docker/Dockerfile.gNB.aw2s.rhel8.2 index 0f0c7f9c5c..bc86223130 100644 --- a/docker/Dockerfile.gNB.aw2s.rhel8.2 +++ b/docker/Dockerfile.gNB.aw2s.rhel8.2 @@ -52,7 +52,6 @@ RUN yum repolist --disablerepo=* && \ libX11 \ atlas \ lksctp-tools \ - nettle \ tzdata \ net-tools \ iputils \ diff --git a/docker/Dockerfile.gNB.rhel8.2 b/docker/Dockerfile.gNB.rhel8.2 index 33dc30bd8a..bb034dc099 100644 --- a/docker/Dockerfile.gNB.rhel8.2 +++ b/docker/Dockerfile.gNB.rhel8.2 @@ -44,7 +44,6 @@ RUN yum repolist --disablerepo=* && \ libX11 \ atlas \ lksctp-tools \ - nettle \ tzdata \ gdb \ python3 \ diff --git a/docker/Dockerfile.gNB.ubuntu18 b/docker/Dockerfile.gNB.ubuntu18 index 4ed4929891..681dd9d3d7 100644 --- a/docker/Dockerfile.gNB.ubuntu18 +++ b/docker/Dockerfile.gNB.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ procps \ libsctp1 \ tzdata \ - libnettle6 \ libblas3 \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index de4a315ce4..e86d3d97b8 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -41,7 +41,6 @@ RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ procps-ng \ - nettle \ tzdata \ atlas \ gdb \ diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index 7f1b30c2c7..4175bab297 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -45,7 +45,6 @@ RUN apt-get update && \ tzdata \ procps \ libsctp1 \ - libnettle6 \ liblapacke \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.nrUE.rhel8.2 b/docker/Dockerfile.nrUE.rhel8.2 index 46281b687f..9fc3826a6d 100644 --- a/docker/Dockerfile.nrUE.rhel8.2 +++ b/docker/Dockerfile.nrUE.rhel8.2 @@ -41,7 +41,6 @@ RUN yum update -y && \ lksctp-tools \ procps-ng \ tzdata \ - nettle \ net-tools \ iputils \ iproute \ diff --git a/docker/Dockerfile.nrUE.ubuntu18 b/docker/Dockerfile.nrUE.ubuntu18 index 25379803c0..5fdf41ef2d 100644 --- a/docker/Dockerfile.nrUE.ubuntu18 +++ b/docker/Dockerfile.nrUE.ubuntu18 @@ -44,7 +44,6 @@ RUN apt-get update && \ libsctp1 \ procps \ tzdata \ - libnettle6 \ liblapacke \ libatlas3-base \ libconfig9 \ diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2 index 62378bf7dd..6abbd52832 100644 --- a/docker/Dockerfile.phySim.rhel8.2 +++ b/docker/Dockerfile.phySim.rhel8.2 @@ -46,7 +46,6 @@ FROM registry.access.redhat.com/ubi8/ubi:latest as oai-physim RUN yum update -y && \ yum install -y --enablerepo="ubi-8-codeready-builder" \ lksctp-tools \ - nettle \ tzdata \ atlas \ hostname \ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c index 86f0558611..eb8c7ee98e 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c @@ -21,62 +21,61 @@ #include "nr_pdcp_integrity_nia2.h" +#include #include #include #include -#include -void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key) +#include "common/utils/assertions.h" +#include "openair3/SECU/aes_128.h" +#include "openair3/SECU/aes_128_cbc_cmac.h" + +void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]) { - CMAC_CTX *ctx; - - ctx = CMAC_CTX_new(); - if (ctx == NULL) abort(); - - CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL); + // This is a hack. Reduce the 3 functions to just cipher? + // No. The overhead is x8 times more. Don't change before measuring + // return integrity_key; + cbc_cmac_ctx_t* ctx = calloc(1, sizeof(cbc_cmac_ctx_t)); + DevAssert(ctx != NULL && "Memory exhausted"); + *ctx = init_aes_128_cbc_cmac(integrity_key); return ctx; } -static void compute_t(unsigned char *t, uint32_t count, int bearer, - int direction) +void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, unsigned char *buffer, int length, int bearer, int count, int direction) { - t[0] = (count >> 24) & 255; - t[1] = (count >> 16) & 255; - t[2] = (count >> 8) & 255; - t[3] = (count ) & 255; - t[4] = ((bearer-1) << 3) | (direction << 2); - memset(&t[5], 0, 8-5); -} + DevAssert(integrity_context != NULL); + DevAssert(out != NULL); + DevAssert(buffer != NULL); + DevAssert(length > -1); + // Strange range: [1-32] instead of [0-31] + DevAssert(bearer > 0 && bearer < 33); + DevAssert(count > -1); -void nr_pdcp_integrity_nia2_integrity(void *integrity_context, - unsigned char *out, - unsigned char *buffer, int length, - int bearer, int count, int direction) -{ - CMAC_CTX *ctx = integrity_context; - unsigned char t[8]; - unsigned char mac[16]; - size_t maclen; + cbc_cmac_ctx_t* ctx = (cbc_cmac_ctx_t*)integrity_context; - /* see 33.401 B.2.3 for the input to 128-EIA2 - * (which is identical to 128-NIA2, see 33.501 D.3.1.3) */ - compute_t(t, count, bearer, direction); + aes_128_t k_iv = {0}; + memcpy(&k_iv.key, ctx->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; + k_iv.iv8.d.bearer = bearer -1; + k_iv.iv8.d.direction = direction; + k_iv.iv8.d.count = htonl(count); - CMAC_Init(ctx, NULL, 0, NULL, NULL); - CMAC_Update(ctx, t, 8); - CMAC_Update(ctx, buffer, length); - CMAC_Final(ctx, mac, &maclen); + uint8_t result[16] = {0}; + byte_array_t msg = {.buf = buffer, .len = length}; + + cipher_aes_128_cbc_cmac((cbc_cmac_ctx_t*)integrity_context, &k_iv, msg, sizeof(result), result); + //aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); - /* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of - * 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant - * bit first (so seems to say 33.401 B.2.3) - */ - memcpy(out, mac, 4); + // AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of + // 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant + // bit first (so seems to say 33.401 B.2.3) + // Precondition: out should have enough space... + memcpy(out, result, 4); } void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context) { - CMAC_CTX *ctx = integrity_context; - CMAC_CTX_free(ctx); + free( ( cbc_cmac_ctx_t*) integrity_context); } + diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h index 9593a2825c..53f117aafb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h @@ -22,7 +22,9 @@ #ifndef _NR_PDCP_INTEGRITY_NIA2_H_ #define _NR_PDCP_INTEGRITY_NIA2_H_ -void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key); +#include + +void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]); void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *out, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c index a7479a5032..c46a9d59fe 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c @@ -19,55 +19,50 @@ * contact@openairinterface.org */ +#include "openair3/SECU/aes_128_ctr.h" +#include "common/utils/assertions.h" + #include "nr_pdcp_security_nea2.h" +#include +#include #include #include -#include -#include -#include - -#ifndef NETTLE_VERSION_MAJOR -/* hack: include bignum.h, not version.h because version.h does not exist - * in old versions and bignum.h includes version.h (as of today). - * May completely fail to work... maybe we should skip support of old - * versions of nettle. - */ -#include -#endif void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key) { - void *ctx = calloc(1, nettle_aes128.context_size); - if (ctx == NULL) exit(1); - -#if !defined(NETTLE_VERSION_MAJOR) || NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key); -#else - nettle_aes128.set_encrypt_key(ctx, ciphering_key); -#endif - - return ctx; + // This is a hack, IMO init, cipher and free functions should be reduced to cipher. + // Test show a ~10% more processing time + return ciphering_key; } -void nr_pdcp_security_nea2_cipher(void *security_context, - unsigned char *buffer, int length, - int bearer, int count, int direction) +void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer, int length, int bearer, int count, int direction) { - unsigned char t[16] = {0}; + DevAssert(security_context != NULL); + DevAssert(buffer != NULL); + DevAssert(length > 0); + DevAssert(bearer > -1 && bearer < 32); + DevAssert(direction > -1 && direction < 2); + DevAssert(count > -1); - t[0] = (count >> 24) & 255; - t[1] = (count >> 16) & 255; - t[2] = (count >> 8) & 255; - t[3] = (count ) & 255; - t[4] = ((bearer-1) << 3) | (direction << 2); + aes_128_t p = {0}; + const uint8_t *ciphering_key = (uint8_t const *)security_context; + memcpy(p.key, ciphering_key, 16); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = ntohl(count); + p.iv16.d.bearer = bearer; + p.iv16.d.direction = direction; - nettle_ctr_crypt(security_context, nettle_aes128.encrypt, - nettle_aes128.block_size, t, - length, buffer, buffer); + uint8_t out[length]; + memset(out, 0, length); + + byte_array_t msg = {.buf = buffer, .len = length};; + aes_128_ctr(&p, msg, length, out); + + memcpy(buffer, out, length); } void nr_pdcp_security_nea2_free_security(void *security_context) { - free(security_context); + (void)security_context; } diff --git a/openair2/UTIL/ALG_DS/CMakeLists.txt b/openair2/UTIL/ALG_DS/CMakeLists.txt new file mode 100644 index 0000000000..2b16a1b9c9 --- /dev/null +++ b/openair2/UTIL/ALG_DS/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(DS) + diff --git a/openair2/UTIL/ALG_DS/README.md b/openair2/UTIL/ALG_DS/README.md new file mode 100644 index 0000000000..dd9403dad3 --- /dev/null +++ b/openair2/UTIL/ALG_DS/README.md @@ -0,0 +1,2 @@ +Algorithms and Data Structures in C for common usage + diff --git a/openair2/UTIL/CMakeLists.txt b/openair2/UTIL/CMakeLists.txt new file mode 100644 index 0000000000..7ba707d9da --- /dev/null +++ b/openair2/UTIL/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(ALG_DS) + diff --git a/openair2/UTIL/OSA/README b/openair2/UTIL/OSA/README index 1e54944308..c605ebf379 100644 --- a/openair2/UTIL/OSA/README +++ b/openair2/UTIL/OSA/README @@ -1,7 +1,6 @@ OAISIM Security Algorithms v0.1 Dependencies: -- nettle >= 2.5 - openssl >= 1.0.1 Compilation: diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index 84cdf4aac3..c175f10c84 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -22,7 +22,7 @@ /*! * \file secu_defs.h * \brief Openair security algorithms functions implementing 3GPP TS 33.401 - * \note HMAC computations are done by nettle/openssl library + * \note HMAC computations are done by openssl library * \author Sebastien ROUX * \date 2013 * \version 0.1 diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index a685eec729..06c0a3f9b2 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -19,31 +19,15 @@ * contact@openairinterface.org */ -#include +#include "../../../openair3/SECU/kdf.h" -#include +#include +#include #include "osa_defs.h" #include "osa_internal.h" #include "common/utils/LOG/log.h" -static inline -void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, - const uint32_t key_length, uint8_t **out, uint32_t out_length) -{ - struct hmac_sha256_ctx ctx; - - uint8_t *buffer; - - buffer = malloc(sizeof(uint8_t) * out_length); - - hmac_sha256_set_key(&ctx, key_length, key); - hmac_sha256_update(&ctx, s_length, s); - hmac_sha256_digest(&ctx, out_length, buffer); - - *out = buffer; -} - /*! * @brief Derive the keys from key and perform truncate on the generated key to * reduce his size to 128 bits. Definition of the derivation function can @@ -58,10 +42,9 @@ void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, * @param[out] out Pointer to reference where output of KDF will be stored. * NOTE: knas is dynamically allocated by the KDF function */ -int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { - uint8_t string[7]; + uint8_t string[7] = {0}; /* FC */ string[0] = FC_ALG_KEY_DER; @@ -84,7 +67,7 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, { int i; char payload[6 * sizeof(string) + 1]; - int index = 0; + int index = 0; for (i = 0; i < sizeof(string); i++) index += sprintf(&payload[index], "0x%02x ", string[i]); @@ -93,13 +76,17 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, } #endif - kdf(string, 7, key, 32, out, 32); + byte_array_t data = {.buf = string, .len = 7}; + if (*out == NULL) { + *out = malloc(sizeof(uint8_t) * 32); + DevAssert(*out != NULL && "Memory exhausted"); + } + kdf(key, data, 32, *out); return 0; } -int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out) { uint8_t string[7]; @@ -120,17 +107,23 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, string[5] = 0x00; string[6] = 0x01; - kdf(string, 7, key, 32, out, 32); + byte_array_t data = {.buf = string, .len = 7}; + + if (*out == NULL) { + *out = malloc(sizeof(uint8_t) * 32); + DevAssert(*out != NULL && "Memory exhausted"); + } + kdf(key, data, 32, *out); + // in NR, we use the last 16 bytes, ignoring the first 16 ones - memcpy(*out, *out+16, 16); + memcpy(*out, *out + 16, 16); return 0; } int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - uint8_t *out; - uint8_t s[10]; + uint8_t s[10] = {0}; /* FC */ s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; @@ -152,18 +145,17 @@ int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t s[8] = 0x00; s[9] = 0x03; - kdf(s, 10, key, 32, &out, 32); - memcpy(key_ng_ran_star, out, 32); - free(out); + byte_array_t data = {.buf = s, .len = 10}; + const uint32_t len_key = 32; + kdf(key, data, len_key, key_ng_ran_star); return 0; } int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) { - uint8_t *out; - uint8_t s[5]; + uint8_t s[5] = {0}; /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ s[0] = 0x1c; @@ -176,10 +168,8 @@ int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) s[3] = 0x00; s[4] = 0x02; - kdf(s, 5, keNB, 32, &out, 32); - - memcpy(skgNB, out, 32); - free(out); + byte_array_t data = {.buf = s, .len = 5}; + kdf(keNB, data, 32, skgNB); return 0; } diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c index 03e95008ca..61f003bc32 100644 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ b/openair2/UTIL/OSA/osa_stream_eea.c @@ -19,16 +19,15 @@ * contact@openairinterface.org */ +#include #include #include #include #include -#include -#include -#include - #include "common/utils/LOG/log.h" +#include "byte_array.h" +#include "openair3//SECU//aes_128_ctr.h" #include "assertions.h" #include "osa_defs.h" @@ -44,10 +43,13 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) DevAssert(stream_cipher != NULL); DevAssert(out != NULL); - LOG_D(OSA, "Entering stream_encrypt_eea0, bits length %u, bearer %u, " - "count %u, direction %s\n", stream_cipher->blength, - stream_cipher->bearer, stream_cipher->count, stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? - "Downlink" : "Uplink"); + LOG_D(OSA, + "Entering stream_encrypt_eea0, bits length %u, bearer %u, " + "count %u, direction %s\n", + stream_cipher->blength, + stream_cipher->bearer, + stream_cipher->count, + stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"); byte_length = (stream_cipher->blength + 7) >> 3; @@ -59,7 +61,7 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) data = *out; } - memcpy (data, stream_cipher->message, byte_length); + memcpy(data, stream_cipher->message, byte_length); return 0; } @@ -67,32 +69,32 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) { osa_snow_3g_context_t snow_3g_context; - int n ; - int i = 0; - uint32_t zero_bit = 0; + int n; + int i = 0; + uint32_t zero_bit = 0; uint32_t *KS; - uint32_t K[4],IV[4]; + uint32_t K[4], IV[4]; DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->key != NULL); DevAssert(stream_cipher->key_length == 16); DevAssert(out != NULL); - n = ( stream_cipher->blength + 31 ) / 32; + n = (stream_cipher->blength + 31) / 32; zero_bit = stream_cipher->blength & 0x7; memset(&snow_3g_context, 0, sizeof(snow_3g_context)); /*Initialisation*/ /* Load the confidentiality key for SNOW 3G initialization as in section 3.4. */ - memcpy(K+3,stream_cipher->key+0,4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K+2,stream_cipher->key+4,4); /*K[2] = key[1];*/ - memcpy(K+1,stream_cipher->key+8,4); /*K[1] = key[2];*/ - memcpy(K+0,stream_cipher->key+12,4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ + memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume + K[3]=key[0]||key[1]||...||key[31] , with key[0] the + * most important bit of key*/ + memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ + memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ + memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume + K[0]=key[96]||key[97]||...||key[127] , with key[127] the + * least important bit of key*/ K[3] = hton_int32(K[3]); K[2] = hton_int32(K[2]); K[1] = hton_int32(K[1]); @@ -106,26 +108,25 @@ int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) /* Run SNOW 3G algorithm to generate sequence of key stream bits KS*/ osa_snow3g_initialize(K, IV, &snow_3g_context); - KS = (uint32_t *)malloc(4*n); - osa_snow3g_generate_key_stream(n,(uint32_t*)KS, &snow_3g_context); + KS = (uint32_t *)malloc(4 * n); + osa_snow3g_generate_key_stream(n, (uint32_t *)KS, &snow_3g_context); if (zero_bit > 0) { - KS[n - 1] = KS[n - 1] & (uint32_t)(0xFFFFFFFF << (8 - zero_bit)); } - for (i=0; imessage[i] ^= *(((uint8_t*)KS)+i); + for (i = 0; i < n * 4; i++) { + stream_cipher->message[i] ^= *(((uint8_t *)KS) + i); } if (zero_bit > 0) { - int ceil_index = (stream_cipher->blength+7) >> 3; + int ceil_index = (stream_cipher->blength + 7) >> 3; stream_cipher->message[ceil_index - 1] = stream_cipher->message[ceil_index - 1] & (uint8_t)(0xFF << (8 - zero_bit)); } @@ -136,91 +137,32 @@ int stream_encrypt_eea1(stream_cipher_t *stream_cipher, uint8_t **out) int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) { - uint8_t m[16]; - uint32_t local_count; - - void *ctx; - uint8_t *data = NULL; - - uint32_t zero_bit = 0; - uint32_t byte_length; - DevAssert(stream_cipher != NULL); - DevAssert(out != NULL); - - LOG_D(OSA, "Entering stream_encrypt_eea2, bits length %u, bearer %u, " - "count %u, direction %s\n", stream_cipher->blength, - stream_cipher->bearer, stream_cipher->count, stream_cipher->direction == SECU_DIRECTION_DOWNLINK ? - "Downlink" : "Uplink"); - - zero_bit = stream_cipher->blength & 0x7; - - byte_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - byte_length += 1; - - ctx = malloc(nettle_aes128.context_size); + DevAssert(stream_cipher->key != NULL); + DevAssert(stream_cipher->key_length == 32); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->blength > 7); if (*out == NULL) { - /* User provided output buffer */ - data = malloc(byte_length); - *out = data; - } else { - data = *out; + *out = calloc(1, (stream_cipher->blength >> 3) + 1); + DevAssert(*out != NULL && "Memory exhausted"); } - local_count = hton_int32(stream_cipher->count); - - memset(m, 0, sizeof(m)); - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | - ((stream_cipher->direction & 0x01) << 2); - /* Other bits are 0 */ - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * byte_length + 1]; - int index = 0; - - for (i = 0; i < byte_length; i++) - index += sprintf(&payload[index], "0x%02x ", stream_cipher->message[i]); - - LOG_D(OSA, "Original message: %s\n", payload); - } -#endif - -#if NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, - stream_cipher->key); -#else - nettle_aes128.set_encrypt_key(ctx, - stream_cipher->key); -#endif - - nettle_ctr_crypt(ctx, nettle_aes128.encrypt, - nettle_aes128.block_size, m, - byte_length, data, stream_cipher->message); - - if (zero_bit > 0) - data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit)); - - free(ctx); - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * byte_length + 1]; - int index = 0; - - for (i = 0; i < byte_length; i++) - index += sprintf(&payload[index], "0x%02x ", data[i]); - - LOG_D(OSA, "Encrypted message: %s\n", payload); - } -#endif + aes_128_t p = {0}; + memcpy(p.key, stream_cipher->key, stream_cipher->key_length); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = htonl(stream_cipher->count); + p.iv16.d.bearer = stream_cipher->bearer; + p.iv16.d.direction = stream_cipher->direction; + DevAssert((stream_cipher->blength & 0x07) == 0 && "Cipher length must be multiple of one octet"); + const uint32_t byte_lenght = stream_cipher->blength >> 3; + // Precondition: out must have enough space, at least as much as the input + const size_t len_out = byte_lenght; + byte_array_t msg = {.buf = stream_cipher->message, .len =byte_lenght}; + aes_128_ctr(&p, msg, len_out, *out); return 0; } diff --git a/openair2/UTIL/OSA/osa_stream_eia.c b/openair2/UTIL/OSA/osa_stream_eia.c index 980a4ae3c1..da4fd23e18 100644 --- a/openair2/UTIL/OSA/osa_stream_eia.c +++ b/openair2/UTIL/OSA/osa_stream_eia.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include #include #include #include @@ -26,12 +27,9 @@ #include #include "assertions.h" +#include "common/utils/LOG/log.h" -#include -#include -#include - -#include "common/utils//LOG/log.h" +#include "openair3/SECU/aes_128_cbc_cmac.h" #include "osa_defs.h" #include "osa_snow3g.h" @@ -49,7 +47,7 @@ */ uint64_t OSA_MUL64x(uint64_t V, uint64_t c) { - if ( V & 0x8000000000000000 ) + if (V & 0x8000000000000000) return (V << 1) ^ c; else return V << 1; @@ -65,10 +63,10 @@ function. */ uint64_t OSA_MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) { - if ( i == 0) + if (i == 0) return V; else - return OSA_MUL64x( OSA_MUL64xPOW(V,i-1,c) , c); + return OSA_MUL64x(OSA_MUL64xPOW(V, i - 1, c), c); } /* OSA_MUL64. * Input V: a 64-bit input. @@ -84,33 +82,32 @@ uint64_t OSA_MUL64(uint64_t V, uint64_t P, uint64_t c) uint64_t result = 0; int i = 0; - for ( i=0; i<64; i++) { - if( ( P>>i ) & 0x1 ) - result ^= OSA_MUL64xPOW(V,i,c); + for (i = 0; i < 64; i++) { + if ((P >> i) & 0x1) + result ^= OSA_MUL64xPOW(V, i, c); } return result; } /* osa_mask32bit. -* Input n: an integer in 1-32. -* Output : a 32 bit mask. -* Prepares a 32 bit mask with required number of 1 bits on the MSB side. -*/ + * Input n: an integer in 1-32. + * Output : a 32 bit mask. + * Prepares a 32 bit mask with required number of 1 bits on the MSB side. + */ uint32_t osa_mask32bit(int n) { - uint32_t mask=0x0; + uint32_t mask = 0x0; - if ( n%32 == 0 ) + if (n % 32 == 0) return 0xffffffff; while (n--) - mask = (mask>>1) ^ 0x80000000; + mask = (mask >> 1) ^ 0x80000000; return mask; } - /*! * @brief Create integrity cmac t for a given message. * @param[in] stream_cipher Structure containing various variables to setup encoding @@ -119,29 +116,29 @@ uint32_t osa_mask32bit(int n) int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]) { osa_snow_3g_context_t snow_3g_context; - uint32_t K[4],IV[4], z[5]; - int i=0,D; - uint32_t MAC_I = 0; - uint64_t EVAL; - uint64_t V; - uint64_t P; - uint64_t Q; - uint64_t c; - uint64_t M_D_2; - int rem_bits; - uint32_t mask = 0; - uint32_t *message; + uint32_t K[4], IV[4], z[5]; + int i = 0, D; + uint32_t MAC_I = 0; + uint64_t EVAL; + uint64_t V; + uint64_t P; + uint64_t Q; + uint64_t c; + uint64_t M_D_2; + int rem_bits; + uint32_t mask = 0; + uint32_t *message; - message = (uint32_t*)stream_cipher->message; /* To operate 32 bit message internally. */ + message = (uint32_t *)stream_cipher->message; /* To operate 32 bit message internally. */ /* Load the Integrity Key for SNOW3G initialization as in section 4.4. */ - memcpy(K+3,stream_cipher->key+0,4); /*K[3] = key[0]; we assume - K[3]=key[0]||key[1]||...||key[31] , with key[0] the - * most important bit of key*/ - memcpy(K+2,stream_cipher->key+4,4); /*K[2] = key[1];*/ - memcpy(K+1,stream_cipher->key+8,4); /*K[1] = key[2];*/ - memcpy(K+0,stream_cipher->key+12,4); /*K[0] = key[3]; we assume - K[0]=key[96]||key[97]||...||key[127] , with key[127] the - * least important bit of key*/ + memcpy(K + 3, stream_cipher->key + 0, 4); /*K[3] = key[0]; we assume + K[3]=key[0]||key[1]||...||key[31] , with key[0] the + * most important bit of key*/ + memcpy(K + 2, stream_cipher->key + 4, 4); /*K[2] = key[1];*/ + memcpy(K + 1, stream_cipher->key + 8, 4); /*K[1] = key[2];*/ + memcpy(K + 0, stream_cipher->key + 12, 4); /*K[0] = key[3]; we assume + K[0]=key[96]||key[97]||...||key[127] , with key[127] the + * least important bit of key*/ K[3] = hton_int32(K[3]); K[2] = hton_int32(K[2]); K[1] = hton_int32(K[1]); @@ -150,45 +147,45 @@ int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4] section 4.4. */ IV[3] = (uint32_t)stream_cipher->count; IV[2] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27); - IV[1] = (uint32_t)(stream_cipher->count) ^ ( (uint32_t)(stream_cipher->direction) << 31 ) ; + IV[1] = (uint32_t)(stream_cipher->count) ^ ((uint32_t)(stream_cipher->direction) << 31); IV[0] = ((((uint32_t)stream_cipher->bearer) & 0x0000001F) << 27) ^ ((uint32_t)(stream_cipher->direction & 0x00000001) << 15); - //printf ("K:\n"); - //hexprint(K, 16); - //printf ("K[0]:%08X\n",K[0]); - //printf ("K[1]:%08X\n",K[1]); - //printf ("K[2]:%08X\n",K[2]); - //printf ("K[3]:%08X\n",K[3]); + // printf ("K:\n"); + // hexprint(K, 16); + // printf ("K[0]:%08X\n",K[0]); + // printf ("K[1]:%08X\n",K[1]); + // printf ("K[2]:%08X\n",K[2]); + // printf ("K[3]:%08X\n",K[3]); - //printf ("IV:\n"); - //hexprint(IV, 16); - //printf ("IV[0]:%08X\n",IV[0]); - //printf ("IV[1]:%08X\n",IV[1]); - //printf ("IV[2]:%08X\n",IV[2]); - //printf ("IV[3]:%08X\n",IV[3]); + // printf ("IV:\n"); + // hexprint(IV, 16); + // printf ("IV[0]:%08X\n",IV[0]); + // printf ("IV[1]:%08X\n",IV[1]); + // printf ("IV[2]:%08X\n",IV[2]); + // printf ("IV[3]:%08X\n",IV[3]); z[0] = z[1] = z[2] = z[3] = z[4] = 0; /* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */ osa_snow3g_initialize(K, IV, &snow_3g_context); osa_snow3g_generate_key_stream(5, z, &snow_3g_context); - //printf ("z[0]:%08X\n",z[0]); - //printf ("z[1]:%08X\n",z[1]); - //printf ("z[2]:%08X\n",z[2]); - //printf ("z[3]:%08X\n",z[3]); - //printf ("z[4]:%08X\n",z[4]); + // printf ("z[0]:%08X\n",z[0]); + // printf ("z[1]:%08X\n",z[1]); + // printf ("z[2]:%08X\n",z[2]); + // printf ("z[3]:%08X\n",z[3]); + // printf ("z[4]:%08X\n",z[4]); P = ((uint64_t)z[0] << 32) | (uint64_t)z[1]; Q = ((uint64_t)z[2] << 32) | (uint64_t)z[3]; - //printf ("P:%16lX\n",P); - //printf ("Q:%16lX\n",Q); + // printf ("P:%16lX\n",P); + // printf ("Q:%16lX\n",Q); /* Calculation */ - D = ceil( stream_cipher->blength / 64.0 ) + 1; - //printf ("D:%d\n",D); + D = ceil(stream_cipher->blength / 64.0) + 1; + // printf ("D:%d\n",D); EVAL = 0; c = 0x1b; /* for 0 <= i <= D-3 */ - for (i=0; i 32) { - M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) << 32 ) | - (uint64_t) (hton_int32(message[2*(D-2)+1]) & mask); + M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) << 32) | (uint64_t)(hton_int32(message[2 * (D - 2) + 1]) & mask); } else { - M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) & mask) << 32 ; + M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) & mask) << 32; } V = EVAL ^ M_D_2; - EVAL = OSA_MUL64(V,P,c); + EVAL = OSA_MUL64(V, P, c); /* for D-1 */ EVAL ^= stream_cipher->blength; /* Multiply by Q */ - EVAL = OSA_MUL64(EVAL,Q,c); + EVAL = OSA_MUL64(EVAL, Q, c); MAC_I = (uint32_t)(EVAL >> 32) ^ z[4]; - //printf ("MAC_I:%16X\n",MAC_I); + // printf ("MAC_I:%16X\n",MAC_I); MAC_I = hton_int32(MAC_I); memcpy(out, &MAC_I, 4); return 0; @@ -221,65 +217,28 @@ int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4] int stream_compute_integrity_eia2(stream_cipher_t *stream_cipher, uint8_t out[4]) { - uint8_t *m; - uint32_t local_count; - size_t size = 4; - - uint8_t data[16]; - - CMAC_CTX *cmac_ctx; - - uint32_t zero_bit = 0; - uint32_t m_length; - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); + ; + DevAssert((stream_cipher->blength & 0x7) == 0); + DevAssert(stream_cipher->key_length == 16 && "k_iv.key and stream_cipher mismatch"); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); - memset(data, 0, 16); + aes_128_t k_iv = {0}; + memcpy(k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; - zero_bit = stream_cipher->blength & 0x7; + k_iv.iv8.d.bearer = stream_cipher->bearer; + k_iv.iv8.d.direction = stream_cipher->direction; + k_iv.iv8.d.count = htonl(stream_cipher->count); - m_length = stream_cipher->blength >> 3; + const size_t m_length = stream_cipher->blength >> 3; - if (zero_bit > 0) - m_length += 1; - - local_count = hton_int32(stream_cipher->count); - - m = calloc(m_length + 8, sizeof(uint8_t)); - - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2); - - memcpy(&m[8], stream_cipher->message, m_length); - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * sizeof(m) + 1]; - int index = 0; - LOG_T(OSA, "Blength: %u, Zero bits: %u\n", - stream_cipher->blength, zero_bit); - - for (i = 0; i < sizeof(m); i++) - index += sprintf(&payload[index], "0x%02x ", m[i]); - - LOG_D(OSA, "Payload: %s\n", payload); - } -#endif - - cmac_ctx = CMAC_CTX_new(); - - CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, EVP_aes_128_cbc(), NULL); - CMAC_Update(cmac_ctx, m, m_length + 8); - - CMAC_Final(cmac_ctx, data, &size); - - CMAC_CTX_free(cmac_ctx); - - memcpy(out, data, 4); - free(m); + uint8_t result[16] = {0}; + byte_array_t msg = {.len = m_length, .buf = stream_cipher->message }; + aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); + memcpy(out, result, 4); return 0; } @@ -307,10 +266,18 @@ int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, ui } if (memcmp(result, expected, 4) != 0) { - LOG_E(OSA, "Mismatch found in integrity for algorithm %u,\n" + LOG_E(OSA, + "Mismatch found in integrity for algorithm %u,\n" "\tgot %02x.%02x.%02x.%02x, expecting %02x.%02x.%02x.%02x\n", - algorithm, result[0], result[1], result[2], result[3], expected[0], - expected[1], expected[2], expected[3]); + algorithm, + result[0], + result[1], + result[2], + result[3], + expected[0], + expected[1], + expected[2], + expected[3]); return -1; } } diff --git a/openair3/DOCS/Latex/EPC/EPC.pdf b/openair3/DOCS/Latex/EPC/EPC.pdf deleted file mode 100644 index 598796e128..0000000000 Binary files a/openair3/DOCS/Latex/EPC/EPC.pdf and /dev/null differ diff --git a/openair3/DOCS/Latex/EPC/EPC.tex b/openair3/DOCS/Latex/EPC/EPC.tex index f1df0a6a37..97e4f52565 100644 --- a/openair3/DOCS/Latex/EPC/EPC.tex +++ b/openair3/DOCS/Latex/EPC/EPC.tex @@ -544,7 +544,6 @@ Before compiling the core EPC, some packages should be installed on the platform \item flex and bison \item openssl-dev \item asn1c (see section \ref{sec:asn1c}) - \item libnettle (see section \ref{sec:libnettle}) \item freediameter (see section \ref{sec:freediameter}) and gnutls 3.1.0 (see section \ref{sec:gnutls}) \end{itemize} @@ -562,28 +561,6 @@ openssl-dev -y \subsection{ASN1c} \label{sec:asn1c} -\subsection{libnettle} -\label{sec:libnettle} - -The nettle library is used by freediameter for certificate encryption and by core -EPC for key derivation. -\begin{lstlisting} -wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz -gunzip nettle-2.5.tar.gz -tar -xvf nettle-2.5.tar -cd nettle-2.5/ -./configure --disable-openssl --enable-shared -make -make check -sudo make install -\end{lstlisting} -The commands provided above will download the required packages sources, configure -and install them on the system. -Note that any packages which is not in the Ubuntu repository is installed by default -in /usr/local instead of /usr. -This behaviour can be overriden at configuration time by providing --prefix=/usr to -the configuration script (configure). - \subsection{gnutls} \label{sec:gnutls} diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c index 736d75f6cc..590ccf65ae 100644 --- a/openair3/NAS/COMMON/nr_common.c +++ b/openair3/NAS/COMMON/nr_common.c @@ -23,6 +23,7 @@ #include #include +#include void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) { //SNN-network-identifier in TS 24.501 @@ -59,8 +60,12 @@ int resToresStar(uint8_t *msg, uicc_t* uicc) { uint8_t ckik[sizeof(uicc->ck) +sizeof(uicc->ik)]; memcpy(ckik, uicc->ck, sizeof(uicc->ck)); memcpy(ckik+sizeof(uicc->ck),uicc->ik, sizeof(uicc->ik)); - uint8_t out[32]; - kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + uint8_t out[32] = {0}; + assert(ptr-S == 32); + //kdf(S, ptr-S, ckik, 32, out, sizeof(out)); + byte_array_t data = {.buf = ckik, .len = 32}; + kdf(S, data, 32, out); + memcpy(msg, out+16, 16); return 16; } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 8a600e0cf9..b24359a232 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -37,6 +37,7 @@ #include "nr_nas_msg_sim.h" #include "aka_functions.h" #include "secu_defs.h" +#include "kdf.h" #include "PduSessionEstablishRequest.h" #include "PduSessionEstablishmentAccept.h" #include "intertask_interface.h" @@ -188,18 +189,20 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 oldS[33] = 0x08; - uint8_t key[32]; + uint8_t key[32] = {0}; memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); //KEY - uint8_t out[32]; - kdf(key, 32, S, 31 + netNamesize, out, 32); - for (int i = 0; i < 16; i++) - output[i] = out[16 + i]; + uint8_t out[32] = {0}; + + byte_array_t data = {.buf = S, .len = 31 + netNamesize}; + kdf(key, data, 32, out); + + memcpy(output, out + 16, 16); } void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) { uint8_t S[100]={0}; - uint8_t key[32]; + uint8_t key[32] = {0}; memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); //KEY @@ -213,7 +216,9 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[ } S[9 + netNamesize] = 0x00; S[10 + netNamesize] = 0x06; - kdf(key, 32, S, 11 + netNamesize, kausf, 32); + + byte_array_t data = {.buf = S, .len = 11 + netNamesize}; + kdf(key, data, 32, kausf); } void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { @@ -223,12 +228,14 @@ void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { int netNamesize = strlen((char*)S+1); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); - kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32); + + byte_array_t data = {.buf = S , .len = 3 + netNamesize}; + kdf(kausf, data, 32, kseaf); } void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { int imsiLen = strlen(uicc->imsiStr); - uint8_t S[100]; + uint8_t S[100] = {0}; S[0] = 0x6D; //FC = 0x6D memcpy(&S[1], uicc->imsiStr, imsiLen ); S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8); @@ -237,12 +244,14 @@ void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { S[4 + imsiLen] = (abba & 0xff00) >> 8; S[5 + imsiLen] = 0x00; S[6 + imsiLen] = 0x02; - kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32); + + byte_array_t data = {.buf = S, .len = 7 + imsiLen}; + kdf(kseaf, data, 32, kamf); } //------------------------------------------------------------------------------ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) { - uint8_t S[20]; + uint8_t S[20] = {0}; uint8_t out[32] = { 0 }; S[0] = 0x69; //FC S[1] = (uint8_t)(nas_alg_type & 0xFF); @@ -251,19 +260,20 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t S[4] = nas_alg_id; S[5] = 0x00; S[6] = 0x01; - kdf(kamf, 32, S, 7, out, 32); - for (int i = 0; i < 16; i++) - knas_int[i] = out[16 + i]; + + byte_array_t data = {.buf = S, .len = 7}; + kdf(kamf, data, 32, out); + + memcpy(knas_int, out+16, 16); } void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ /* Compute the KDF input parameter * S = FC(0x6E) || UL NAS Count || 0x00 0x04 || 0x01 || 0x00 0x01 */ - uint8_t input[32]; + uint8_t input[32] = {0}; // uint16_t length = 4; // int offset = 0; - uint8_t out[32] = { 0 }; LOG_TRACE(INFO, "%s with count= %d", __FUNCTION__, count); memset(input, 0, 32); @@ -282,9 +292,9 @@ void derive_kgnb(uint8_t kamf[32], uint32_t count, uint8_t *kgnb){ input[8] = 0; input[9] = 1; - kdf(kamf, 32, input, 10, out, 32); - for (int i = 0; i < 32; i++) - kgnb[i] = out[i]; + byte_array_t data = {.buf = input, .len = 10}; + kdf(kamf, data, 32, kgnb); + printf("kgnb : "); for(int pp=0;pp<32;pp++) printf("%02x ",kgnb[pp]); diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index a387580b60..55b269f413 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -67,6 +67,7 @@ Description Defines the authentication EMM procedure executed by the #include "usim_api.h" #include "secu_defs.h" +#include "kdf.h" #include "Authentication.h" #include "executables/lte-softmodem.h" @@ -982,14 +983,10 @@ static int _authentication_kasme(const OctetString *autn, input_s[4],input_s[5],input_s[6],input_s[7], input_s[8],input_s[9],input_s[10],input_s[11], input_s[12],input_s[13]); - /* TODO !!! Compute the Kasme key */ - // todo_hmac_256(key, input_s, kasme->value); - kdf(key, - ck->length + ik->length , /*key_length*/ - input_s, - offset, - kasme->value, - kasme->length); + + assert(ck->length + ik->length == 32); + byte_array_t data = {.len = offset, .buf = input_s}; + kdf(key, data, kasme->length, kasme->value); LOG_TRACE(INFO,"EMM-PROC KASME (l=%d)%s", kasme->length, diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index fd3332669b..3386499663 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -63,6 +63,7 @@ Description Defines the security mode control EMM procedure executed by the # include "assertions.h" #include "secu_defs.h" +#include "kdf.h" #include "SecurityModeControl.h" #if defined(NAS_BUILT_IN_UE) @@ -484,7 +485,9 @@ static int _security_kenb(const OctetString *kasme, OctetString *kenb, input[5] = 0; input[6] = 4; - kdf(kasme->value, 32, input, 7, kenb->value, 32); + byte_array_t data = {.len = 7, .buf = input}; + kdf(kasme->value, data, 32, kenb->value); + kenb->length = 32; return (RETURNok); } @@ -536,8 +539,12 @@ static int _security_kdf(const OctetString *kasme, OctetString *key, input[5] = 0x00; input[6] = 0x01; + assert(kasme->length == 32); + byte_array_t data = {.len = 7, .buf=input}; /* Compute the derived key */ - kdf(kasme->value, kasme->length, input, 7, output, 32); + kdf(kasme->value, data, 32, output); + + memcpy(key->value, &output[31 - key->length + 1], key->length); return (RETURNok); } diff --git a/openair3/SECU/aes_128.h b/openair3/SECU/aes_128.h new file mode 100644 index 0000000000..7f7e550419 --- /dev/null +++ b/openair3/SECU/aes_128.h @@ -0,0 +1,88 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef AES_128_OAI_H +#define AES_128_OAI_H + +#include +#include +#include + +// see 33.401 B.2.3 for the input to 128-EIA2 +// (which is identical to 128-NIA2, see 33.501 D.3.1.3) + +typedef struct { + uint32_t count; + uint8_t padding: 2; + uint8_t direction: 1; + uint8_t bearer: 5; + uint8_t pad_8; + uint16_t pad_16; + uint64_t pad_64; +} data_iv16_t; + +typedef struct{ + union{ + data_iv16_t d; + uint8_t iv[16]; + }; +} iv16_t; + +typedef struct { + uint32_t count; + uint8_t padding: 2; + uint8_t direction: 1; + uint8_t bearer: 5; + uint8_t pad_8; + uint16_t pad_16; +} data_iv8_t; + +typedef struct{ + union{ + data_iv8_t d; + uint8_t iv[8]; + }; +} iv8_t; + +typedef enum{ + AES_INITIALIZATION_VECTOR_8, + AES_INITIALIZATION_VECTOR_16, + + AES_INITIALIZATION_VECTOR_END, +} iv_e; + +#if __BYTE_ORDER == __BIG_ENDIAN +static_assert(0 != 0, "The struct iv_t needs little endianness"); +#endif + +// static_assert((16 == sizeof(iv_t)) , "Initialization Vector needs to have an AES_BLOCK_SIZE" ); + +typedef struct { + uint8_t key[16]; + iv_e type; + union{ + iv8_t iv8; + iv16_t iv16; + }; +} aes_128_t; + +#endif + diff --git a/openair3/SECU/aes_128_cbc_cmac.c b/openair3/SECU/aes_128_cbc_cmac.c new file mode 100644 index 0000000000..6b02f1673a --- /dev/null +++ b/openair3/SECU/aes_128_cbc_cmac.c @@ -0,0 +1,254 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "aes_128_cbc_cmac.h" + +#include "common/utils/assertions.h" +#include + +#if OPENSSL_VERSION_MAJOR >= 3 +// code for version 3.0 or greater +#include + +static +const char *propq = NULL; + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + /* Fetch the CMAC implementation */ + EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq); + DevAssert(mac != NULL); + + /* Create a context for the CMAC operation */ + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac); + DevAssert(mctx != NULL); + + // The underlying cipher to be used + char cipher_name[] = "aes128"; + + OSSL_PARAM params[2] = {0}; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name, + sizeof(cipher_name)); + params[1] = OSSL_PARAM_construct_end(); + + /* Initialise the CMAC operation */ + int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params); + DevAssert(rc != 0); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, iv, sz_iv); + DevAssert(rc != 0); + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, msg.buf, msg.len); + DevAssert(rc != 0); + + /* Make a call to the final with a NULL buffer to get the length of the MAC */ + size_t out_len = 0; + rc = EVP_MAC_final(mctx, out, &out_len, len_out); + DevAssert(rc != 0); + + EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(library_context); +} + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]) +{ + DevAssert(key != NULL); + + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + /* Fetch the CMAC implementation */ + EVP_MAC* mac = EVP_MAC_fetch(library_context, "CMAC", propq); + DevAssert(mac != NULL); + + cbc_cmac_ctx_t ctx = {.lib_ctx = library_context, .mac = mac }; + + assert(16 == sizeof(ctx.key)); + memcpy(ctx.key, key, 16); + + return ctx; +} + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(ctx != NULL); + DevAssert(k_iv != NULL); + /* Create a context for the CMAC operation */ + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(ctx->mac); + DevAssert(mctx != NULL); + + // The underlying cipher to be used + char cipher_name[] = "aes128"; + + OSSL_PARAM params[2] = {0}; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, cipher_name, + sizeof(cipher_name)); + params[1] = OSSL_PARAM_construct_end(); + + /* Initialise the CMAC operation */ + int rc = EVP_MAC_init(mctx, k_iv->key, sizeof(k_iv->key), params); + DevAssert(rc != 0); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, iv, sz_iv); + DevAssert(rc != 0); + + /* Make one or more calls to process the data to be authenticated */ + rc = EVP_MAC_update(mctx, msg.buf, msg.len); + DevAssert(rc != 0); + + /* Make a call to the final with a NULL buffer to get the length of the MAC */ + size_t out_len = 0; + rc = EVP_MAC_final(mctx, out, &out_len, len_out); + DevAssert(rc != 0); + + EVP_MAC_CTX_free(mctx); +} + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx) +{ + DevAssert(ctx != NULL); + EVP_MAC_free(ctx->mac); + OSSL_LIB_CTX_free(ctx->lib_ctx); +} + +#else +// code for 1.1.x or lower + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + + CMAC_CTX *ctx = CMAC_CTX_new(); + DevAssert(ctx != NULL); + + CMAC_Init(ctx, k_iv->key, sizeof(k_iv->key), EVP_aes_128_cbc(), NULL); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + CMAC_Update(ctx, iv, sz_iv); + + CMAC_Update(ctx, msg.buf, msg.len); + size_t len_res = 0; + CMAC_Final(ctx, out, &len_res); + DevAssert(len_res <= len_out); + + CMAC_CTX_free(ctx); +} + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]) +{ + DevAssert(key != NULL); + cbc_cmac_ctx_t ctx = {.lib_ctx = NULL, .mac = NULL }; + + ctx.mac = CMAC_CTX_new(); + DevAssert(ctx.mac != NULL); + + //assert(16 == sizeof(ctx.key)); + memcpy(ctx.key, key, 16); //sizeof(ctx.key)); + + CMAC_Init(ctx.mac, ctx.key, 16, EVP_aes_128_cbc(), NULL); + return ctx; +} + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(ctx != NULL); + DevAssert(k_iv != NULL); + + //From https://man.openbsd.org/CMAC_Init.3 + //If ctx is already initialized, CMAC_Init() can be called again with key, + //cipher, and impl all set to NULL and key_len set to 0. In that case, any + //data already processed is discarded and ctx is re-initialized to start + //reading data anew. + CMAC_Init(ctx->mac, NULL, 0, NULL, NULL); + + size_t sz_iv = 0; + uint8_t* iv = NULL; + if(k_iv->type == AES_INITIALIZATION_VECTOR_8){ + sz_iv = 8; + iv = (uint8_t*)k_iv->iv8.iv; + } else if(k_iv->type == AES_INITIALIZATION_VECTOR_16) { + sz_iv = 16; + iv = (uint8_t*)k_iv->iv16.iv; + } else { + DevAssert(0!=0 && "Unknwon Initialization vector"); + } + + CMAC_Update(ctx->mac, iv, sz_iv); + + CMAC_Update(ctx->mac, msg.buf, msg.len); + size_t len_res = 0; + CMAC_Final(ctx->mac, out, &len_res); + DevAssert(len_res <= len_out); +} + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx) +{ + DevAssert(ctx != NULL); + CMAC_CTX_free(ctx->mac); +} + +#endif + diff --git a/openair3/SECU/aes_128_cbc_cmac.h b/openair3/SECU/aes_128_cbc_cmac.h new file mode 100644 index 0000000000..b5118118c3 --- /dev/null +++ b/openair3/SECU/aes_128_cbc_cmac.h @@ -0,0 +1,48 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#ifndef AES_128_CBC_CMAC_H +#define AES_128_CBC_CMAC_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" + + +#include +#include + +typedef struct { + void* lib_ctx; + void* mac; + uint8_t key[16]; +} cbc_cmac_ctx_t ; + +void aes_128_cbc_cmac(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +cbc_cmac_ctx_t init_aes_128_cbc_cmac(uint8_t key[16]); + +void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +void free_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx); + +#endif + diff --git a/openair3/SECU/aes_128_ctr.c b/openair3/SECU/aes_128_ctr.c new file mode 100644 index 0000000000..4caf6ee3cf --- /dev/null +++ b/openair3/SECU/aes_128_ctr.c @@ -0,0 +1,62 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// TS 133 401 pag. 88 + +#include "aes_128_ctr.h" +#include "common/utils/assertions.h" +#include +#include +#include + +void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + + DevAssert(sizeof(iv16_t) == AES_BLOCK_SIZE); + DevAssert(k_iv->type == AES_INITIALIZATION_VECTOR_16); + + // Create and initialise the context + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + DevAssert(ctx != NULL); + + // Set IV length if default 12 bytes (96 bits) is not appropriate + // int rc = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CTR_SET_IVLEN, 16, NULL)) + + // Initialise the encryption operation. + int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, k_iv->key, k_iv->iv16.iv); + DevAssert(rc == 1); + + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == AES_BLOCK_SIZE); + + int len_ev = 0; + rc = EVP_EncryptUpdate(ctx, out, &len_ev, msg.buf, msg.len); + DevAssert(!(len_ev > len_out) && "Buffer overflow"); + + // Finalise the encryption. Normally ciphertext bytes may be written at + // this stage, but this does not occur in GCM mode + rc = EVP_EncryptFinal_ex(ctx, out + len_ev, &len_ev); + DevAssert(rc == 1); + + // Get the tag + // rc == EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + EVP_CIPHER_CTX_free(ctx); +} diff --git a/openair3/SECU/aes_128_ctr.h b/openair3/SECU/aes_128_ctr.h new file mode 100644 index 0000000000..24bad85664 --- /dev/null +++ b/openair3/SECU/aes_128_ctr.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef AES_128_CTR_OAI_H +#define AES_128_CTR_OAI_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" +#include +#include +#include + +void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +#endif diff --git a/openair3/SECU/kdf.c b/openair3/SECU/kdf.c index 1073df8ebe..8bead9158d 100644 --- a/openair3/SECU/kdf.c +++ b/openair3/SECU/kdf.c @@ -19,87 +19,18 @@ * contact@openairinterface.org */ +#include "common/utils/assertions.h" +#include "openair3/SECU/sha_256_hmac.h" #include #include #include -#include -#include "security_types.h" -#include "secu_defs.h" +#include "kdf.h" -void kdf(const uint8_t *key, uint16_t key_len, uint8_t *s, uint16_t s_len, uint8_t *out, - uint16_t out_len) +void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) { - struct hmac_sha256_ctx ctx; - - memset(&ctx, 0, sizeof(ctx)); - - hmac_sha256_set_key(&ctx, key_len, key); - hmac_sha256_update(&ctx, s_len, s); - hmac_sha256_digest(&ctx, out_len, out); + // Do we still need kdf function? + sha_256_hmac(key, data, len, out); } -#ifndef NAS_UE -int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) -{ - uint8_t s[7]; - - // FC - s[0] = FC_KENB; - // P0 = Uplink NAS count - s[1] = (nas_count & 0xff000000) >> 24; - s[2] = (nas_count & 0x00ff0000) >> 16; - s[3] = (nas_count & 0x0000ff00) >> 8; - s[4] = (nas_count & 0x000000ff); - - // Length of NAS count - s[5] = 0x00; - s[6] = 0x04; - - kdf(kasme, 32, s, 7, keNB, 32); - - return 0; -} -#endif - -int derive_keNB_star( - const uint8_t *kenb_32, - const uint16_t pci, - const uint32_t earfcn_dl, - const bool is_rel8_only, - uint8_t *kenb_star) -{ - // see 33.401 section A.5 KeNB* derivation function - uint8_t s[10] = {0}; - - // FC = 0x13 - s[0] = FC_KENB_STAR; - // P0 = PCI (target physical cell id) - s[1] = (pci & 0x0000ff00) >> 8; - s[2] = (pci & 0x000000ff); - // L0 = length of PCI (i.e. 0x00 0x02) - s[3] = 0x00; - s[4] = 0x02; - // P1 = EARFCN-DL (target physical cell downlink frequency) - if (is_rel8_only) { - s[5] = (earfcn_dl & 0x0000ff00) >> 8; - s[6] = (earfcn_dl & 0x000000ff); - s[7] = 0x00; - s[8] = 0x02; - kdf (kenb_32, 32, s, 9, kenb_star, 32); - } else { - s[5] = (earfcn_dl & 0x00ff0000) >> 16; - s[6] = (earfcn_dl & 0x0000ff00) >> 8; - s[7] = (earfcn_dl & 0x000000ff); - s[8] = 0x00; - s[9] = 0x03; - kdf (kenb_32, 32, s, 10, kenb_star, 32); - } - // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) - // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 - // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This - // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the - // EARFCN-DL. - return 0; -} diff --git a/openair3/SECU/kdf.h b/openair3/SECU/kdf.h new file mode 100644 index 0000000000..9567296bd2 --- /dev/null +++ b/openair3/SECU/kdf.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef KEY_DERIVATION_FUNCTION_OSA_H +#define KEY_DERIVATION_FUNCTION_OSA_H + +#include +#include +#include "byte_array.h" + +void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]); + +#endif + + + diff --git a/openair3/SECU/key_nas_deriver.c b/openair3/SECU/key_nas_deriver.c index 59546be081..18cdb3d000 100644 --- a/openair3/SECU/key_nas_deriver.c +++ b/openair3/SECU/key_nas_deriver.c @@ -26,6 +26,7 @@ #include "security_types.h" #include "secu_defs.h" +#include "kdf.h" #define SECU_DEBUG 1 /*! @@ -79,7 +80,9 @@ int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, printf("\n"); #endif - kdf(kasme, 32, s, 7, out, 32); + //kdf(kasme, 32, s, 7, out, 32); + byte_array_t data = {.len = 7, .buf = s}; + kdf(kasme, data, 32, out); memcpy(knas, &out[31-16+1], 16); diff --git a/openair3/SECU/nas_stream_eea1.c b/openair3/SECU/nas_stream_eea1.c index efe924851f..e70d49ea2c 100644 --- a/openair3/SECU/nas_stream_eea1.c +++ b/openair3/SECU/nas_stream_eea1.c @@ -24,10 +24,6 @@ #include #include -#include -#include -#include - #include "assertions.h" #include "conversions.h" #include "secu_defs.h" diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 0cd3d91761..4eeb24b775 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -19,84 +19,40 @@ * contact@openairinterface.org */ +#include #include #include #include #include -#include -#include -#include - +#include "aes_128_ctr.h" #include "assertions.h" #include "conversions.h" #include "secu_defs.h" -// #define SECU_DEBUG - int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) { - uint8_t m[16]; - uint32_t local_count; - - void *ctx; - uint8_t *data; - - uint32_t zero_bit = 0; - uint32_t byte_length; - DevAssert(stream_cipher != NULL); - DevAssert(out != NULL); + DevAssert(stream_cipher->key != NULL); + DevAssert(stream_cipher->key_length == 32); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->direction < 2); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->blength > 7); - zero_bit = stream_cipher->blength & 0x7; + aes_128_t p = {0}; + memcpy(p.key, stream_cipher->key, stream_cipher->key_length); + p.type = AES_INITIALIZATION_VECTOR_16; + p.iv16.d.count = htonl(stream_cipher->count); + p.iv16.d.bearer = stream_cipher->bearer; + p.iv16.d.direction = stream_cipher->direction; - byte_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - byte_length += 1; - - ctx = malloc(nettle_aes128.context_size); - data = malloc(byte_length); - - local_count = hton_int32(stream_cipher->count); - - memset(m, 0, sizeof(m)); - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | - ((stream_cipher->direction & 0x01) << 2); - /* Other bits are 0 */ - -#if defined(SECU_DEBUG) - { - int i; - printf("Blength: %u, Zero bits: %u\n", stream_cipher->blength, zero_bit); - - for (i = 0; i < sizeof(m); i++) - printf("0x%02x ", m[i]); - - printf("\n"); - } -#endif - -#if NETTLE_VERSION_MAJOR < 3 - nettle_aes128.set_encrypt_key(ctx, stream_cipher->key_length, - stream_cipher->key); -#else - nettle_aes128.set_encrypt_key(ctx, - stream_cipher->key); -#endif - - nettle_ctr_crypt(ctx, nettle_aes128.encrypt, - nettle_aes128.block_size, m, - byte_length, data, stream_cipher->message); - - if (zero_bit > 0) - data[byte_length - 1] = data[byte_length - 1] & (uint8_t)(0xFF << (8 - zero_bit)); - - - memcpy(out, data, byte_length); - free(data); - free(ctx); + DevAssert((stream_cipher->blength & 0x07) == 0); + const uint32_t byte_lenght = stream_cipher->blength >> 3; + // Precondition: out must have enough space, at least as much as the input + const size_t len_out = byte_lenght; + byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght}; + aes_128_ctr(&p, msg, len_out, out); return 0; } diff --git a/openair3/SECU/nas_stream_eia2.c b/openair3/SECU/nas_stream_eia2.c index a2ec6a6dd4..4c7951a0f5 100644 --- a/openair3/SECU/nas_stream_eia2.c +++ b/openair3/SECU/nas_stream_eia2.c @@ -19,6 +19,7 @@ * contact@openairinterface.org */ +#include #include #include #include @@ -26,15 +27,8 @@ #include "secu_defs.h" -#include -#include -#include - -// test -#include -#include -#include - +#include +#include "aes_128_cbc_cmac.h" #include "assertions.h" #include "conversions.h" @@ -45,84 +39,28 @@ * @param[in] stream_cipher Structure containing various variables to setup encoding * @param[out] out For EIA2 the output string is 32 bits long */ + int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) { - uint8_t *m = NULL; - uint32_t local_count; - size_t size = 4; - uint8_t data[16]; - CMAC_CTX *cmac_ctx = NULL; - const EVP_CIPHER *cipher = EVP_aes_128_cbc(); - uint32_t zero_bit = 0; - uint32_t m_length; - int ret; - DevAssert(stream_cipher != NULL); - DevAssert(stream_cipher->key != NULL); - DevAssert(stream_cipher->key_length > 0); - DevAssert(out != NULL); + DevAssert(stream_cipher->message != NULL); + DevAssert(stream_cipher->bearer < 32); + DevAssert(stream_cipher->key_length == 16); + DevAssert((stream_cipher->blength & 0x7) == 0); - memset(data, 0, 16); - - zero_bit = stream_cipher->blength & 0x7; - - m_length = stream_cipher->blength >> 3; - - if (zero_bit > 0) - m_length += 1; - - local_count = hton_int32(stream_cipher->count); - - m = calloc(m_length + 8, sizeof(uint8_t)); - - memcpy(&m[0], &local_count, 4); - m[4] = ((stream_cipher->bearer & 0x1F) << 3) | ((stream_cipher->direction & 0x01) << 2); - - memcpy(&m[8], stream_cipher->message, m_length); - -#if defined(SECU_DEBUG) - { - int i; - printf("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit); - - for (i = 0; i < m_length + 8; i++) - printf("%02x", m[i]); - - printf("\nKey:"); - - for (i = 0; i < stream_cipher->key_length; i++) - printf("%02x", stream_cipher->key[i]); - - printf("\nMessage:"); - - for (i = 0; i < m_length; i++) - printf("%02x", stream_cipher->message[i]); - - printf("\n"); - } -#endif - - cmac_ctx = CMAC_CTX_new(); - ret = CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL); - ret = CMAC_Update(cmac_ctx, m, m_length + 8); - (void)ret; /* avoid gcc warning "set but not used" */ - CMAC_Final(cmac_ctx, data, &size); - CMAC_CTX_free(cmac_ctx); - -#if defined(SECU_DEBUG) - { - int i; - printf("out: "); - - for (i = 0; i < size; i++) - printf("%02x", data[i]); - - printf("\n"); - } -#endif - - memcpy(out, data, 4); - free(m); + aes_128_t k_iv = {0}; + memcpy(&k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + k_iv.type = AES_INITIALIZATION_VECTOR_8; + k_iv.iv8.d.bearer = stream_cipher->bearer; + k_iv.iv8.d.direction = stream_cipher->direction; + k_iv.iv8.d.count = htonl(stream_cipher->count); + size_t const m_length = stream_cipher->blength >> 3; + uint8_t result[16] = {0}; + byte_array_t msg = {.buf = stream_cipher->message, .len = m_length }; + aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); + + memcpy(out, result, 4); return 0; } + diff --git a/openair3/SECU/secu_defs.c b/openair3/SECU/secu_defs.c new file mode 100644 index 0000000000..00cf23187e --- /dev/null +++ b/openair3/SECU/secu_defs.c @@ -0,0 +1,96 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#include "secu_defs.h" +#include "kdf.h" + +#ifndef NAS_UE +int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) +{ + uint8_t s[7] = {0}; + + // FC + s[0] = FC_KENB; + // P0 = Uplink NAS count + s[1] = (nas_count & 0xff000000) >> 24; + s[2] = (nas_count & 0x00ff0000) >> 16; + s[3] = (nas_count & 0x0000ff00) >> 8; + s[4] = (nas_count & 0x000000ff); + + // Length of NAS count + s[5] = 0x00; + s[6] = 0x04; + + // kdf(kasme, 32, s, 7, keNB, 32); + byte_array_t data = {.buf = s, .len = 7}; + kdf(kasme, data, 32, keNB); + + return 0; +} +#endif + +int derive_keNB_star( + const uint8_t *kenb_32, + const uint16_t pci, + const uint32_t earfcn_dl, + const bool is_rel8_only, + uint8_t *kenb_star) +{ + // see 33.401 section A.5 KeNB* derivation function + uint8_t s[10] = {0}; + byte_array_t data = {.buf = s}; + // FC = 0x13 + s[0] = FC_KENB_STAR; + // P0 = PCI (target physical cell id) + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); + // L0 = length of PCI (i.e. 0x00 0x02) + s[3] = 0x00; + s[4] = 0x02; + // P1 = EARFCN-DL (target physical cell downlink frequency) + if (is_rel8_only) { + s[5] = (earfcn_dl & 0x0000ff00) >> 8; + s[6] = (earfcn_dl & 0x000000ff); + s[7] = 0x00; + s[8] = 0x02; +// kdf (kenb_32, 32, s, 9, kenb_star, 32); + data.len = 9; + } else { + s[5] = (earfcn_dl & 0x00ff0000) >> 16; + s[6] = (earfcn_dl & 0x0000ff00) >> 8; + s[7] = (earfcn_dl & 0x000000ff); + s[8] = 0x00; + s[9] = 0x03; + //kdf (kenb_32, 32, s, 10, kenb_star, 32); + data.len = 10; + } + + kdf (kenb_32, data, 32, kenb_star); + + // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) + // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 + // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This + // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the + // EARFCN-DL. + return 0; +} + diff --git a/openair3/SECU/secu_defs.h b/openair3/SECU/secu_defs.h index 8ec05f3daf..7817db30d3 100644 --- a/openair3/SECU/secu_defs.h +++ b/openair3/SECU/secu_defs.h @@ -24,6 +24,7 @@ #include "security_types.h" #include +#include #define EIA0_ALG_ID 0x00 #define EIA1_128_ALG_ID 0x01 @@ -36,13 +37,6 @@ #define SECU_DIRECTION_UPLINK 0 #define SECU_DIRECTION_DOWNLINK 1 -void kdf(const uint8_t *key, - uint16_t key_len, - uint8_t *s, - uint16_t s_len, - uint8_t *out, - uint16_t out_len); - int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl, diff --git a/openair3/SECU/sha_256_hmac.c b/openair3/SECU/sha_256_hmac.c new file mode 100644 index 0000000000..ae49b1d1a2 --- /dev/null +++ b/openair3/SECU/sha_256_hmac.c @@ -0,0 +1,95 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "common/utils/assertions.h" +#include "sha_256_hmac.h" + +#include + +#if OPENSSL_VERSION_MAJOR >= 3 +// code for version 3.0 or greater + +#include + +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) +{ + DevAssert(key != NULL); + DevAssert(data.buf != NULL); + DevAssert(data.len != 0); + DevAssert(len != 0); + + OSSL_LIB_CTX* library_context = OSSL_LIB_CTX_new(); + DevAssert(library_context != NULL); + + // A property query used for selecting the MAC implementation. + const char* propq = NULL; + // Fetch the HMAC implementation + EVP_MAC* mac = EVP_MAC_fetch(library_context, "HMAC", propq); + DevAssert(mac != NULL); + + // Create a context for the HMAC operation + EVP_MAC_CTX* mctx = EVP_MAC_CTX_new(mac); + DevAssert(mctx != NULL); + + // The underlying digest to be used + OSSL_PARAM params[2] = {0}; + char digest_name[] = "SHA2-256"; + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, digest_name, sizeof(digest_name)); + params[1] = OSSL_PARAM_construct_end(); + + // Initialise the HMAC operation + int rc = EVP_MAC_init(mctx, key, 32, params); + DevAssert(rc == 1); + + // Make one or more calls to process the data to be authenticated + rc = EVP_MAC_update(mctx, data.buf, data.len); + DevAssert(rc == 1); + + // Make one call to the final to get the MAC + rc = EVP_MAC_final(mctx, out, &len, len); + DevAssert(rc == 1); + + // OpenSSL free functions will ignore NULL arguments + EVP_MAC_CTX_free(mctx); + EVP_MAC_free(mac); + OSSL_LIB_CTX_free(library_context); +} +#else +// code for 1.1.x or lower +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]) +{ + DevAssert(key != NULL); + DevAssert(data.buf != NULL); + DevAssert(data.len != 0); + DevAssert(len != 0); + + HMAC_CTX* ctx = HMAC_CTX_new(); + + HMAC_Init_ex(ctx, key, 32, EVP_sha256(), NULL); + + HMAC_Update(ctx, data.buf, data.len); + + HMAC_Final(ctx, out, (uint32_t*)&len); + + HMAC_CTX_free(ctx); +} + +#endif diff --git a/openair3/SECU/sha_256_hmac.h b/openair3/SECU/sha_256_hmac.h new file mode 100644 index 0000000000..79413763ea --- /dev/null +++ b/openair3/SECU/sha_256_hmac.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef SHA_256_HMAC_OAI_H +#define SHA_256_HMAC_OAI_H + +#include +#include + +#include "byte_array.h" + +void sha_256_hmac(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]); + +#endif + diff --git a/openair3/TEST/Makefile.am b/openair3/TEST/Makefile.am index 211c7e62f2..1c00d33420 100644 --- a/openair3/TEST/Makefile.am +++ b/openair3/TEST/Makefile.am @@ -43,8 +43,7 @@ if HAVE_CHECK TESTS = \ test_kdf \ test_aes128_cmac_encrypt \ - test_aes128_ctr_encrypt \ - test_aes128_ctr_decrypt \ + test_aes128_ctr \ test_secu_kenb \ test_secu_knas \ test_secu_knas_encrypt_eea1 \ @@ -68,8 +67,7 @@ common_ldadd = $(top_builddir)/SECU/libsecu.la \ check_PROGRAMS = \ test_kdf \ test_aes128_cmac_encrypt \ - test_aes128_ctr_encrypt \ - test_aes128_ctr_decrypt \ + test_aes128_ctr \ test_secu_kenb \ test_secu_knas \ test_secu_knas_encrypt_eea1 \ diff --git a/openair3/TEST/test_aes128_ctr.c b/openair3/TEST/test_aes128_ctr.c new file mode 100644 index 0000000000..b29b0d2e16 --- /dev/null +++ b/openair3/TEST/test_aes128_ctr.c @@ -0,0 +1,265 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +// TS 133 401 pag. 88 + +#include "../../common/utils/assertions.h" +#include "../SECU/aes_128_ctr.h" +#include + +#include +#include + +void test_1(void) +{ + aes_128_ctr_t p = { + .key = {0xd3, 0xc5, 0xd5, 0x92, 0x32, 0x7f, 0xb1, 0x1c, 0x40, 0x35, 0xc6, 0x68, 0x0a, 0xf8, 0xc6, 0xd1}, + .iv_p.count = ntohl(965368244), // {0x39, 0x8a, 0x59, 0xb4}, //965368244, // + .iv_p.bearer = 21, //{0x15}, + .iv_p.direction = 1 // {0x01} + }; + + uint8_t text[32] = {0x98, 0x1b, 0xa6, 0x82, 0x4c, 0x1b, 0xfb, 0x1a, 0xb4, 0x85, 0x47, 0x20, 0x29, 0xb7, 0x1d, 0x80, + 0x8c, 0xe3, 0x3e, 0x2c, 0xc3, 0xc0, 0xb5, 0xfc, 0x1f, 0x3d, 0xe8, 0xa6, 0xdc, 0x66, 0xb1, 0xf0}; + + uint8_t out[32] = {0}; + + // Cipher + aes_128_ctr(&p, 32, text, 32, out); + + uint8_t result[32] = {0xe9, 0xfe, 0xd8, 0xa6, 0x3d, 0x15, 0x53, 0x04, 0xd7, 0x1d, 0xf2, 0x0b, 0xf3, 0xe8, 0x22, 0x14, + 0xb2, 0x0e, 0xd7, 0xda, 0xd2, 0xf2, 0x33, 0xdc, 0x3c, 0x22, 0xd7, 0xbd, 0xee, 0xed, 0x8e, 0x78}; + + int rc = memcmp(out, result, 32); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + uint8_t text_decipher[32] = {0}; + + // Decipher + aes_128_ctr(&p, 32, out, 32, text_decipher); + + rc = memcmp(text, text_decipher, 32); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_2(void) +{ + aes_128_ctr_t p = { + .key = {0x2b, 0xd6, 0x45, 0x9f, 0x82, 0xc4, 0x40, 0xe0, 0x95, 0x2c, 0x49, 0x10, 0x48, 0x05, 0xff, 0x48}, + .iv_p.count = ntohl(3329599051), // c675a64b , // + .iv_p.bearer = 12, //{0x0c}, + .iv_p.direction = 1 // {0x01} + }; + + uint8_t text[100] = {0x7e, 0xc6, 0x12, 0x72, 0x74, 0x3b, 0xf1, 0x61, 0x47, 0x26, 0x44, 0x6a, 0x6c, 0x38, 0xce, 0xd1, 0x66, 0xf6, 0xca, 0x76, 0xeb, 0x54, 0x30, 0x04, 0x42, + 0x86, 0x34, 0x6c, 0xef, 0x13, 0x0f, 0x92, 0x92, 0x2b, 0x03, 0x45, 0x0d, 0x3a, 0x99, 0x75, 0xe5, 0xbd, 0x2e, 0xa0, 0xeb, 0x55, 0xad, 0x8e, 0x1b, 0x19, + 0x9e, 0x3e, 0xc4, 0x31, 0x60, 0x20, 0xe9, 0xa1, 0xb2, 0x85, 0xe7, 0x62, 0x79, 0x53, 0x59, 0xb7, 0xbd, 0xfd, 0x39, 0xbe, 0xf4, 0xb2, 0x48, 0x45, 0x83, + 0xd5, 0xaf, 0xe0, 0x82, 0xae, 0xe6, 0x38, 0xbf, 0x5f, 0xd5, 0xa6, 0x06, 0x19, 0x39, 0x01, 0xa0, 0x8f, 0x4a, 0xb4, 0x1a, 0xab, 0x9b, 0x13, 0x48, 0x80}; + + uint8_t out[100] = {0}; + aes_128_ctr(&p, 100, text, 100, out); + + uint8_t result[100] = {0x59, 0x61, 0x60, 0x53, 0x53, 0xc6, 0x4b, 0xdc, 0xa1, 0x5b, 0x19, 0x5e, 0x28, 0x85, 0x53, 0xa9, 0x10, 0x63, 0x25, 0x06, 0xd6, 0x20, 0x0a, 0xa7, 0x90, + 0xc4, 0xc8, 0x06, 0xc9, 0x99, 0x04, 0xcf, 0x24, 0x45, 0xcc, 0x50, 0xbb, 0x1c, 0xf1, 0x68, 0xa4, 0x96, 0x73, 0x73, 0x4e, 0x08, 0x1b, 0x57, 0xe3, 0x24, + 0xce, 0x52, 0x59, 0xc0, 0xe7, 0x8d, 0x4c, 0xd9, 0x7b, 0x87, 0x09, 0x76, 0x50, 0x3c, 0x09, 0x43, 0xf2, 0xcb, 0x5a, 0xe8, 0xf0, 0x52, 0xc7, 0xb7, 0xd3, + 0x92, 0x23, 0x95, 0x87, 0xb8, 0x95, 0x60, 0x86, 0xbc, 0xab, 0x18, 0x83, 0x60, 0x42, 0xe2, 0xe6, 0xce, 0x42, 0x43, 0x2a, 0x17, 0x10, 0x5c, 0x53, 0xd0}; + + int rc = memcmp(out, result, 99); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + uint8_t text_decipher[100] = {0}; + aes_128_ctr(&p, 99, out, 99, text_decipher); + + rc = memcmp(text, text_decipher, 99); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_3(void) +{ + aes_128_ctr_t p = {.key = {0x0a, 0x8b, 0x6b, 0xd8, 0xd9, 0xb0, 0x8b, 0x08, 0xd6, 0x4e, 0x32, 0xd1, 0x81, 0x77, 0x77, 0xfb}, + .iv_p.count = ntohl(1414351309), // 544d49cd + .iv_p.bearer = 4, + .iv_p.direction = 0}; + + uint8_t text[40] = {0xfd, 0x40, 0xa4, 0x1d, 0x37, 0x0a, 0x1f, 0x65, 0x74, 0x50, 0x95, 0x68, 0x7d, 0x47, 0xba, 0x1d, 0x36, 0xd2, 0x34, 0x9e, + 0x23, 0xf6, 0x44, 0x39, 0x2c, 0x8e, 0xa9, 0xc4, 0x9d, 0x40, 0xc1, 0x32, 0x71, 0xaf, 0xf2, 0x64, 0xd0, 0xf2, 0x48, 0x00}; + + // Cipher + uint8_t out[40] = {0}; + aes_128_ctr(&p, 40, text, 40, out); + + uint8_t result[40] = {0x75, 0x75, 0x0d, 0x37, 0xb4, 0xbb, 0xa2, 0xa4, 0xde, 0xdb, 0x34, 0x23, 0x5b, 0xd6, 0x8c, 0x66, 0x45, 0xac, 0xda, 0xac, + 0xa4, 0x81, 0x38, 0xa3, 0xb0, 0xc4, 0x71, 0xe2, 0xa7, 0x04, 0x1a, 0x57, 0x64, 0x23, 0xd2, 0x92, 0x72, 0x87, 0xf0, 0x00}; + + int rc = memcmp(out, result, 39); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[40] = {0}; + aes_128_ctr(&p, 40, out, 40, text_decipher); + + rc = memcmp(text, text_decipher, 39); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_4(void) +{ + aes_128_ctr_t p = {.key = {0xaa, 0x1f, 0x95, 0xae, 0xa5, 0x33, 0xbc, 0xb3, 0x2e, 0xb6, 0x3b, 0xf5, 0x2d, 0x8f, 0x83, 0x1a}, + .iv_p.count = ntohl(1926809201), // 72d8c671 + .iv_p.bearer = 16, + .iv_p.direction = 1}; + + uint8_t text[128] = {0xfb, 0x1b, 0x96, 0xc5, 0xc8, 0xba, 0xdf, 0xb2, 0xe8, 0xe8, 0xed, 0xfd, 0xe7, 0x8e, 0x57, 0xf2, 0xad, 0x81, 0xe7, 0x41, 0x03, 0xfc, 0x43, 0x0a, 0x53, 0x4d, + 0xcc, 0x37, 0xaf, 0xce, 0xc7, 0x0e, 0x15, 0x17, 0xbb, 0x06, 0xf2, 0x72, 0x19, 0xda, 0xe4, 0x90, 0x22, 0xdd, 0xc4, 0x7a, 0x06, 0x8d, 0xe4, 0xc9, 0x49, 0x6a, + 0x95, 0x1a, 0x6b, 0x09, 0xed, 0xbd, 0xc8, 0x64, 0xc7, 0xad, 0xbd, 0x74, 0x0a, 0xc5, 0x0c, 0x02, 0x2f, 0x30, 0x82, 0xba, 0xfd, 0x22, 0xd7, 0x81, 0x97, 0xc5, + 0xd5, 0x08, 0xb9, 0x77, 0xbc, 0xa1, 0x3f, 0x32, 0xe6, 0x52, 0xe7, 0x4b, 0xa7, 0x28, 0x57, 0x60, 0x77, 0xce, 0x62, 0x8c, 0x53, 0x5e, 0x87, 0xdc, 0x60, 0x77, + 0xba, 0x07, 0xd2, 0x90, 0x68, 0x59, 0x0c, 0x8c, 0xb5, 0xf1, 0x08, 0x8e, 0x08, 0x2c, 0xfa, 0x0e, 0xc9, 0x61, 0x30, 0x2d, 0x69, 0xcf, 0x3d, 0x44}; + + // Cipher + uint8_t out[128] = {0}; + aes_128_ctr(&p, 128, text, 128, out); + + uint8_t result[128] = {0xdf, 0xb4, 0x40, 0xac, 0xb3, 0x77, 0x35, 0x49, 0xef, 0xc0, 0x46, 0x28, 0xae, 0xb8, 0xd8, 0x15, 0x62, 0x75, 0x23, 0x0b, 0xdc, 0x69, 0x0d, 0x94, 0xb0, 0x0d, + 0x8d, 0x95, 0xf2, 0x8c, 0x4b, 0x56, 0x30, 0x7f, 0x60, 0xf4, 0xca, 0x55, 0xeb, 0xa6, 0x61, 0xeb, 0xba, 0x72, 0xac, 0x80, 0x8f, 0xa8, 0xc4, 0x9e, 0x26, 0x78, + 0x8e, 0xd0, 0x4a, 0x5d, 0x60, 0x6c, 0xb4, 0x18, 0xde, 0x74, 0x87, 0x8b, 0x9a, 0x22, 0xf8, 0xef, 0x29, 0x59, 0x0b, 0xc4, 0xeb, 0x57, 0xc9, 0xfa, 0xf7, 0xc4, + 0x15, 0x24, 0xa8, 0x85, 0xb8, 0x97, 0x9c, 0x42, 0x3f, 0x2f, 0x8f, 0x8e, 0x05, 0x92, 0xa9, 0x87, 0x92, 0x01, 0xbe, 0x7f, 0xf9, 0x77, 0x7a, 0x16, 0x2a, 0xb8, + 0x10, 0xfe, 0xb3, 0x24, 0xba, 0x74, 0xc4, 0xc1, 0x56, 0xe0, 0x4d, 0x39, 0x09, 0x72, 0x09, 0x65, 0x3a, 0xc3, 0x3e, 0x5a, 0x5f, 0x2d, 0x88, 0x64}; + + int rc = memcmp(out, result, 127); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[128] = {0}; + aes_128_ctr(&p, 128, out, 128, text_decipher); + + rc = memcmp(text, text_decipher, 127); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_5(void) +{ + aes_128_ctr_t p = {.key = {0x96, 0x18, 0xae, 0x46, 0x89, 0x1f, 0x86, 0x57, 0x8e, 0xeb, 0xe9, 0x0e, 0xf7, 0xa1, 0x20, 0x2e}, + .iv_p.count = ntohl(3329599051), // c675a64b + .iv_p.bearer = 12, + .iv_p.direction = 1}; + + uint8_t text[156] = {0x8d, 0xaa, 0x17, 0xb1, 0xae, 0x05, 0x05, 0x29, 0xc6, 0x82, 0x7f, 0x28, 0xc0, 0xef, 0x6a, 0x12, 0x42, 0xe9, 0x3f, 0x8b, 0x31, 0x4f, 0xb1, 0x8a, 0x77, 0xf7, + 0x90, 0xae, 0x04, 0x9f, 0xed, 0xd6, 0x12, 0x26, 0x7f, 0xec, 0xae, 0xfc, 0x45, 0x01, 0x74, 0xd7, 0x6d, 0x9f, 0x9a, 0xa7, 0x75, 0x5a, 0x30, 0xcd, 0x90, 0xa9, + 0xa5, 0x87, 0x4b, 0xf4, 0x8e, 0xaf, 0x70, 0xee, 0xa3, 0xa6, 0x2a, 0x25, 0x0a, 0x8b, 0x6b, 0xd8, 0xd9, 0xb0, 0x8b, 0x08, 0xd6, 0x4e, 0x32, 0xd1, 0x81, 0x77, + 0x77, 0xfb, 0x54, 0x4d, 0x49, 0xcd, 0x49, 0x72, 0x0e, 0x21, 0x9d, 0xbf, 0x8b, 0xbe, 0xd3, 0x39, 0x04, 0xe1, 0xfd, 0x40, 0xa4, 0x1d, 0x37, 0x0a, 0x1f, 0x65, + 0x74, 0x50, 0x95, 0x68, 0x7d, 0x47, 0xba, 0x1d, 0x36, 0xd2, 0x34, 0x9e, 0x23, 0xf6, 0x44, 0x39, 0x2c, 0x8e, 0xa9, 0xc4, 0x9d, 0x40, 0xc1, 0x32, 0x71, 0xaf, + 0xf2, 0x64, 0xd0, 0xf2, 0x48, 0x41, 0xd6, 0x46, 0x5f, 0x09, 0x96, 0xff, 0x84, 0xe6, 0x5f, 0xc5, 0x17, 0xc5, 0x3e, 0xfc, 0x33, 0x63, 0xc3, 0x84, 0x92, 0xa8}; + + // Cipher + uint8_t out[156] = {0}; + aes_128_ctr(&p, 156, text, 156, out); + + uint8_t result[156] = {0x91, 0x9c, 0x8c, 0x33, 0xd6, 0x67, 0x89, 0x70, 0x3d, 0x05, 0xa0, 0xd7, 0xce, 0x82, 0xa2, 0xae, 0xac, 0x4e, 0xe7, 0x6c, 0x0f, 0x4d, 0xa0, 0x50, 0x33, 0x5e, + 0x8a, 0x84, 0xe7, 0x89, 0x7b, 0xa5, 0xdf, 0x2f, 0x36, 0xbd, 0x51, 0x3e, 0x3d, 0x0c, 0x85, 0x78, 0xc7, 0xa0, 0xfc, 0xf0, 0x43, 0xe0, 0x3a, 0xa3, 0xa3, 0x9f, + 0xba, 0xad, 0x7d, 0x15, 0xbe, 0x07, 0x4f, 0xaa, 0x5d, 0x90, 0x29, 0xf7, 0x1f, 0xb4, 0x57, 0xb6, 0x47, 0x83, 0x47, 0x14, 0xb0, 0xe1, 0x8f, 0x11, 0x7f, 0xca, + 0x10, 0x67, 0x79, 0x45, 0x09, 0x6c, 0x8c, 0x5f, 0x32, 0x6b, 0xa8, 0xd6, 0x09, 0x5e, 0xb2, 0x9c, 0x3e, 0x36, 0xcf, 0x24, 0x5d, 0x16, 0x22, 0xaa, 0xfe, 0x92, + 0x1f, 0x75, 0x66, 0xc4, 0xf5, 0xd6, 0x44, 0xf2, 0xf1, 0xfc, 0x0e, 0xc6, 0x84, 0xdd, 0xb2, 0x13, 0x49, 0x74, 0x76, 0x22, 0xe2, 0x09, 0x29, 0x5d, 0x27, 0xff, + 0x3f, 0x95, 0x62, 0x33, 0x71, 0xd4, 0x9b, 0x14, 0x7c, 0x0a, 0xf4, 0x86, 0x17, 0x1f, 0x22, 0xcd, 0x04, 0xb1, 0xcb, 0xeb, 0x26, 0x58, 0x22, 0x3e, 0x69, 0x38}; + + int rc = memcmp(out, result, 155); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[156] = {0}; + aes_128_ctr(&p, 156, out, 156, text_decipher); + + rc = memcmp(text, text_decipher, 155); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void test_6(void) +{ + aes_128_ctr_t p = {.key = {0x54, 0xf4, 0xe2, 0xe0, 0x4c, 0x83, 0x78, 0x6e, 0xec, 0x8f, 0xb5, 0xab, 0xe8, 0xe3, 0x65, 0x66}, + .iv_p.count = ntohl(2896491791), // aca4f50f + .iv_p.bearer = 11, + .iv_p.direction = 0}; + + uint8_t text[512] = {0x40, 0x98, 0x1b, 0xa6, 0x82, 0x4c, 0x1b, 0xfb, 0x42, 0x86, 0xb2, 0x99, 0x78, 0x3d, 0xaf, 0x44, 0x2c, 0x09, 0x9f, 0x7a, 0xb0, 0xf5, 0x8d, 0x5c, 0x8e, 0x46, 0xb1, 0x04, 0xf0, + 0x8f, 0x01, 0xb4, 0x1a, 0xb4, 0x85, 0x47, 0x20, 0x29, 0xb7, 0x1d, 0x36, 0xbd, 0x1a, 0x3d, 0x90, 0xdc, 0x3a, 0x41, 0xb4, 0x6d, 0x51, 0x67, 0x2a, 0xc4, 0xc9, 0x66, 0x3a, 0x2b, + 0xe0, 0x63, 0xda, 0x4b, 0xc8, 0xd2, 0x80, 0x8c, 0xe3, 0x3e, 0x2c, 0xcc, 0xbf, 0xc6, 0x34, 0xe1, 0xb2, 0x59, 0x06, 0x08, 0x76, 0xa0, 0xfb, 0xb5, 0xa4, 0x37, 0xeb, 0xcc, 0x8d, + 0x31, 0xc1, 0x9e, 0x44, 0x54, 0x31, 0x87, 0x45, 0xe3, 0xfa, 0x16, 0xbb, 0x11, 0xad, 0xae, 0x24, 0x88, 0x79, 0xfe, 0x52, 0xdb, 0x25, 0x43, 0xe5, 0x3c, 0xf4, 0x45, 0xd3, 0xd8, + 0x28, 0xce, 0x0b, 0xf5, 0xc5, 0x60, 0x59, 0x3d, 0x97, 0x27, 0x8a, 0x59, 0x76, 0x2d, 0xd0, 0xc2, 0xc9, 0xcd, 0x68, 0xd4, 0x49, 0x6a, 0x79, 0x25, 0x08, 0x61, 0x40, 0x14, 0xb1, + 0x3b, 0x6a, 0xa5, 0x11, 0x28, 0xc1, 0x8c, 0xd6, 0xa9, 0x0b, 0x87, 0x97, 0x8c, 0x2f, 0xf1, 0xca, 0xbe, 0x7d, 0x9f, 0x89, 0x8a, 0x41, 0x1b, 0xfd, 0xb8, 0x4f, 0x68, 0xf6, 0x72, + 0x7b, 0x14, 0x99, 0xcd, 0xd3, 0x0d, 0xf0, 0x44, 0x3a, 0xb4, 0xa6, 0x66, 0x53, 0x33, 0x0b, 0xcb, 0xa1, 0x10, 0x5e, 0x4c, 0xec, 0x03, 0x4c, 0x73, 0xe6, 0x05, 0xb4, 0x31, 0x0e, + 0xaa, 0xad, 0xcf, 0xd5, 0xb0, 0xca, 0x27, 0xff, 0xd8, 0x9d, 0x14, 0x4d, 0xf4, 0x79, 0x27, 0x59, 0x42, 0x7c, 0x9c, 0xc1, 0xf8, 0xcd, 0x8c, 0x87, 0x20, 0x23, 0x64, 0xb8, 0xa6, + 0x87, 0x95, 0x4c, 0xb0, 0x5a, 0x8d, 0x4e, 0x2d, 0x99, 0xe7, 0x3d, 0xb1, 0x60, 0xde, 0xb1, 0x80, 0xad, 0x08, 0x41, 0xe9, 0x67, 0x41, 0xa5, 0xd5, 0x9f, 0xe4, 0x18, 0x9f, 0x15, + 0x42, 0x00, 0x26, 0xfe, 0x4c, 0xd1, 0x21, 0x04, 0x93, 0x2f, 0xb3, 0x8f, 0x73, 0x53, 0x40, 0x43, 0x8a, 0xaf, 0x7e, 0xca, 0x6f, 0xd5, 0xcf, 0xd3, 0xa1, 0x95, 0xce, 0x5a, 0xbe, + 0x65, 0x27, 0x2a, 0xf6, 0x07, 0xad, 0xa1, 0xbe, 0x65, 0xa6, 0xb4, 0xc9, 0xc0, 0x69, 0x32, 0x34, 0x09, 0x2c, 0x4d, 0x01, 0x8f, 0x17, 0x56, 0xc6, 0xdb, 0x9d, 0xc8, 0xa6, 0xd8, + 0x0b, 0x88, 0x81, 0x38, 0x61, 0x6b, 0x68, 0x12, 0x62, 0xf9, 0x54, 0xd0, 0xe7, 0x71, 0x17, 0x48, 0x78, 0x0d, 0x92, 0x29, 0x1d, 0x86, 0x29, 0x99, 0x72, 0xdb, 0x74, 0x1c, 0xfa, + 0x4f, 0x37, 0xb8, 0xb5, 0x6c, 0xdb, 0x18, 0xa7, 0xca, 0x82, 0x18, 0xe8, 0x6e, 0x4b, 0x4b, 0x71, 0x6a, 0x4d, 0x04, 0x37, 0x1f, 0xbe, 0xc2, 0x62, 0xfc, 0x5a, 0xd0, 0xb3, 0x81, + 0x9b, 0x18, 0x7b, 0x97, 0xe5, 0x5b, 0x1a, 0x4d, 0x7c, 0x19, 0xee, 0x24, 0xc8, 0xb4, 0xd7, 0x72, 0x3c, 0xfe, 0xdf, 0x04, 0x5b, 0x8a, 0xca, 0xe4, 0x86, 0x95, 0x17, 0xd8, 0x0e, + 0x50, 0x61, 0x5d, 0x90, 0x35, 0xd5, 0xd9, 0xc5, 0xa4, 0x0a, 0xf6, 0x02, 0x28, 0x0b, 0x54, 0x25, 0x97, 0xb0, 0xcb, 0x18, 0x61, 0x9e, 0xeb, 0x35, 0x92, 0x57, 0x59, 0xd1, 0x95, + 0xe1, 0x00, 0xe8, 0xe4, 0xaa, 0x0c, 0x38, 0xa3, 0xc2, 0xab, 0xe0, 0xf3, 0xd8, 0xff, 0x04, 0xf3, 0xc3, 0x3c, 0x29, 0x50, 0x69, 0xc2, 0x36, 0x94, 0xb5, 0xbb, 0xea, 0xcd, 0xd5, + 0x42, 0xe2, 0x8e, 0x8a, 0x94, 0xed, 0xb9, 0x11, 0x9f, 0x41, 0x2d, 0x05, 0x4b, 0xe1, 0xfa, 0x72, 0x00, 0xb0, 0x90, 0x00}; + + // Cipher + uint8_t out[512] = {0}; + aes_128_ctr(&p, 512, text, 512, out); + + uint8_t result[512] = {0x5c, 0xb7, 0x2c, 0x6e, 0xdc, 0x87, 0x8f, 0x15, 0x66, 0xe1, 0x02, 0x53, 0xaf, 0xc3, 0x64, 0xc9, 0xfa, 0x54, 0x0d, 0x91, 0x4d, 0xb9, 0x4c, 0xbe, 0xe2, 0x75, 0xd0, 0x91, 0x7c, + 0xa6, 0xaf, 0x0d, 0x77, 0xac, 0xb4, 0xef, 0x3b, 0xbe, 0x1a, 0x72, 0x2b, 0x2e, 0xf5, 0xbd, 0x1d, 0x4b, 0x8e, 0x2a, 0xa5, 0x02, 0x4e, 0xc1, 0x38, 0x8a, 0x20, 0x1e, 0x7b, 0xce, + 0x79, 0x20, 0xae, 0xc6, 0x15, 0x89, 0x5f, 0x76, 0x3a, 0x55, 0x64, 0xdc, 0xc4, 0xc4, 0x82, 0xa2, 0xee, 0x1d, 0x8b, 0xfe, 0xcc, 0x44, 0x98, 0xec, 0xa8, 0x3f, 0xbb, 0x75, 0xf9, + 0xab, 0x53, 0x0e, 0x0d, 0xaf, 0xbe, 0xde, 0x2f, 0xa5, 0x89, 0x5b, 0x82, 0x99, 0x1b, 0x62, 0x77, 0xc5, 0x29, 0xe0, 0xf2, 0x52, 0x9d, 0x7f, 0x79, 0x60, 0x6b, 0xe9, 0x67, 0x06, + 0x29, 0x6d, 0xed, 0xfa, 0x9d, 0x74, 0x12, 0xb6, 0x16, 0x95, 0x8c, 0xb5, 0x63, 0xc6, 0x78, 0xc0, 0x28, 0x25, 0xc3, 0x0d, 0x0a, 0xee, 0x77, 0xc4, 0xc1, 0x46, 0xd2, 0x76, 0x54, + 0x12, 0x42, 0x1a, 0x80, 0x8d, 0x13, 0xce, 0xc8, 0x19, 0x69, 0x4c, 0x75, 0xad, 0x57, 0x2e, 0x9b, 0x97, 0x3d, 0x94, 0x8b, 0x81, 0xa9, 0x33, 0x7c, 0x3b, 0x2a, 0x17, 0x19, 0x2e, + 0x22, 0xc2, 0x06, 0x9f, 0x7e, 0xd1, 0x16, 0x2a, 0xf4, 0x4c, 0xde, 0xa8, 0x17, 0x60, 0x36, 0x65, 0xe8, 0x07, 0xce, 0x40, 0xc8, 0xe0, 0xdd, 0x9d, 0x63, 0x94, 0xdc, 0x6e, 0x31, + 0x15, 0x3f, 0xe1, 0x95, 0x5c, 0x47, 0xaf, 0xb5, 0x1f, 0x26, 0x17, 0xee, 0x0c, 0x5e, 0x3b, 0x8e, 0xf1, 0xad, 0x75, 0x74, 0xed, 0x34, 0x3e, 0xdc, 0x27, 0x43, 0xcc, 0x94, 0xc9, + 0x90, 0xe1, 0xf1, 0xfd, 0x26, 0x42, 0x53, 0xc1, 0x78, 0xde, 0xa7, 0x39, 0xc0, 0xbe, 0xfe, 0xeb, 0xcd, 0x9f, 0x9b, 0x76, 0xd4, 0x9c, 0x10, 0x15, 0xc9, 0xfe, 0xcf, 0x50, 0xe5, + 0x3b, 0x8b, 0x52, 0x04, 0xdb, 0xcd, 0x3e, 0xed, 0x86, 0x38, 0x55, 0xda, 0xbc, 0xdc, 0xc9, 0x4b, 0x31, 0xe3, 0x18, 0x02, 0x15, 0x68, 0x85, 0x5c, 0x8b, 0x9e, 0x52, 0xa9, 0x81, + 0x95, 0x7a, 0x11, 0x28, 0x27, 0xf9, 0x78, 0xba, 0x96, 0x0f, 0x14, 0x47, 0x91, 0x1b, 0x31, 0x7b, 0x55, 0x11, 0xfb, 0xcc, 0x7f, 0xb1, 0x3a, 0xc1, 0x53, 0xdb, 0x74, 0x25, 0x11, + 0x17, 0xe4, 0x86, 0x1e, 0xb9, 0xe8, 0x3b, 0xff, 0xff, 0xc4, 0xeb, 0x77, 0x55, 0x57, 0x90, 0x38, 0xe5, 0x79, 0x24, 0xb1, 0xf7, 0x8b, 0x3e, 0x1a, 0xd9, 0x0b, 0xab, 0x2a, 0x07, + 0x87, 0x1b, 0x72, 0xdb, 0x5e, 0xef, 0x96, 0xc3, 0x34, 0x04, 0x49, 0x66, 0xdb, 0x0c, 0x37, 0xca, 0xfd, 0x1a, 0x89, 0xe5, 0x64, 0x6a, 0x35, 0x80, 0xeb, 0x64, 0x65, 0xf1, 0x21, + 0xdc, 0xe9, 0xcb, 0x88, 0xd8, 0x5b, 0x96, 0xcf, 0x23, 0xcc, 0xcc, 0xd4, 0x28, 0x07, 0x67, 0xbe, 0xe8, 0xee, 0xb2, 0x3d, 0x86, 0x52, 0x46, 0x1d, 0xb6, 0x49, 0x31, 0x03, 0x00, + 0x3b, 0xaf, 0x89, 0xf5, 0xe1, 0x82, 0x61, 0xea, 0x43, 0xc8, 0x4a, 0x92, 0xeb, 0xff, 0xff, 0xe4, 0x90, 0x9d, 0xc4, 0x6c, 0x51, 0x92, 0xf8, 0x25, 0xf7, 0x70, 0x60, 0x0b, 0x96, + 0x02, 0xc5, 0x57, 0xb5, 0xf8, 0xb4, 0x31, 0xa7, 0x9d, 0x45, 0x97, 0x7d, 0xd9, 0xc4, 0x1b, 0x86, 0x3d, 0xa9, 0xe1, 0x42, 0xe9, 0x00, 0x20, 0xcf, 0xd0, 0x74, 0xd6, 0x92, 0x7b, + 0x7a, 0xb3, 0xb6, 0x72, 0x5d, 0x1a, 0x6f, 0x3f, 0x98, 0xb9, 0xc9, 0xda, 0xa8, 0x98, 0x2a, 0xff, 0x06, 0x78, 0x28, 0x00}; + + int rc = memcmp(out, result, 483); + DevAssert(rc == 0 && "Ciphering did not produce the expected results"); + + // Decipher + uint8_t text_decipher[512] = {0}; + aes_128_ctr(&p, 512, out, 512, text_decipher); + + rc = memcmp(text, text_decipher, 483); + DevAssert(rc == 0 && "Text and deciphered text do not match"); +} + +void doit(void) +{ + test_1(); + printf("AES-128: Test 1 passed\n"); + test_2(); + printf("AES-128: Test 2 passed\n"); + test_3(); + printf("AES-128: Test 3 passed\n"); + test_4(); + printf("AES-128: Test 4 passed\n"); + test_5(); + printf("AES-128: Test 5 passed\n"); + test_6(); + printf("AES-128: Test 6 passed\n"); +} diff --git a/openair3/TEST/test_aes128_ctr_decrypt.c b/openair3/TEST/test_aes128_ctr_decrypt.c deleted file mode 100644 index 928853c9ba..0000000000 --- a/openair3/TEST/test_aes128_ctr_decrypt.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include - -#include "test_util.h" - -#include "secu_defs.h" - -#include -#include -#include - -static -void test_uncipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, - unsigned key_length, const uint8_t *cipheredtext, - unsigned length, const uint8_t *cleartext, const uint8_t *ictr) -{ - void *ctx = malloc(cipher->context_size); - uint8_t *data = malloc(length); - uint8_t *ctr = malloc(cipher->block_size); - -#if NETTLE_VERSION_MAJOR < 3 - cipher->set_encrypt_key(ctx, key_length, key); -#else - cipher->set_encrypt_key(ctx, key); -#endif - - memcpy(ctr, ictr, cipher->block_size); - - ctr_crypt(ctx, cipher->encrypt, - cipher->block_size, ctr, - length, data, cipheredtext); - - if (compare_buffer(data, length, cleartext, length) != 0) { - fail("Fail: test_uncipher_ctr\n"); - } - - free(ctx); - free(data); - free(ctr); -} - -void doit (void) -{ - /* From NIST spec 800-38a on AES modes, - * - * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf - * - * F.5 CTR Example Vectors - */ - /* F.5.1 CTR-AES128.Encrypt */ - test_uncipher_ctr(&nettle_aes128, - HL("2b7e151628aed2a6abf7158809cf4f3c"), - HL("6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"), - H("874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"), - H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); -} diff --git a/openair3/TEST/test_aes128_ctr_encrypt.c b/openair3/TEST/test_aes128_ctr_encrypt.c deleted file mode 100644 index 071aa603a9..0000000000 --- a/openair3/TEST/test_aes128_ctr_encrypt.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include - -#include "test_util.h" - -#include "secu_defs.h" - -#include -#include -#include - -static void test_cipher_ctr(const struct nettle_cipher *cipher, const uint8_t *key, - unsigned key_length, const uint8_t *cleartext, unsigned length, - const uint8_t *ciphertext, const uint8_t *ictr) -{ - void *ctx = malloc(cipher->context_size); - uint8_t *data = malloc(length); - uint8_t *ctr = malloc(cipher->block_size); - -#if NETTLE_VERSION_MAJOR < 3 - cipher->set_encrypt_key(ctx, key_length, key); -#else - cipher->set_encrypt_key(ctx, key); -#endif - - memcpy(ctr, ictr, cipher->block_size); - - ctr_crypt(ctx, cipher->encrypt, - cipher->block_size, ctr, - length, data, cleartext); - - if (compare_buffer(data, length, ciphertext, length) != 0) { - fail("Fail: test_cipher_ctr"); - } - - free(ctx); - free(data); - free(ctr); -} - -void doit (void) -{ - /* From NIST spec 800-38a on AES modes, - * - * http://csrc.nist.gov/CryptoToolkit/modes/800-38_Series_Publications/SP800-38A.pdf - * - * F.5 CTR Example Vectors - */ - /* F.5.1 CTR-AES128.Encrypt */ - test_cipher_ctr(&nettle_aes128, - HL("2b7e151628aed2a6abf7158809cf4f3c"), - HL("6bc1bee22e409f96e93d7e117393172a" - "ae2d8a571e03ac9c9eb76fac45af8e51" - "30c81c46a35ce411e5fbc1191a0a52ef" - "f69f2445df4f9b17ad2b417be66c3710"), - H("874d6191b620e3261bef6864990db6ce" - "9806f66b7970fdff8617187bb9fffdff" - "5ae4df3edbd5d35e5b4f09020db03eab" - "1e031dda2fbe03d1792170a0f3009cee"), - H("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")); -} diff --git a/targets/Makerules b/targets/Makerules index a25e2c6e8b..3488c54762 100644 --- a/targets/Makerules +++ b/targets/Makerules @@ -14,14 +14,6 @@ DATE_REV := $(shell date '+%F %T') NUM_CORES:=$(shell cat /proc/cpuinfo | grep processor | wc -l) -# Check for libraries and export cflags/linker variables -NETTLE_FOUND := $(shell if pkg-config --exists nettle; then echo "1" ; else echo "0"; fi) -ifeq ($(NETTLE_FOUND), 1) -NETTLE_LIBS := $(shell pkg-config --libs nettle) -#else -#@echo "package nettle not installed" -endif - OPENSSL_FOUND := $(shell if pkg-config --exists openssl; then echo "1" ; else echo "0"; fi) ifeq ($(OPENSSL_FOUND), 1) OPENSSL_LIBS := $(shell pkg-config --libs openssl) diff --git a/targets/README.txt b/targets/README.txt index c3a8156d9a..b32e0640e5 100644 --- a/targets/README.txt +++ b/targets/README.txt @@ -20,7 +20,7 @@ First, you must have all four openair SW directories, openair1, openair2, openai - libpgm-5.1 and libpgm-5.1-dev for distributed simulation with reliable multicast transmport - libxml2 and libxml2-dev - libforms-bin libforms-dev - - nettle-dev nettle-bin openssl libssl-dev + - openssl libssl-dev - libatlas-base-dev and libatlas-headers (for Ubuntu 11.04, libatlas-dev instead of libatlas-headers) - asn1c and the LTE ASN1 files (for more information on how to install this and generate the required files see the README file in openair2/RRC/LITE/MESSAGES)