From 986a1a80ffd9413081546ab838b8e7d84eacb447 Mon Sep 17 00:00:00 2001 From: mir Date: Tue, 4 Oct 2022 19:12:33 +0200 Subject: [PATCH] Remove nettle library from OAI, support OpenSSL 3.0 and 1.1 Add byte_array_t structure under common/ --- CMakeLists.txt | 49 ++-- cmake_targets/at_commands/CMakeLists.txt | 45 +-- cmake_targets/tools/MODULES/FindNettle.cmake | 22 -- cmake_targets/tools/build_helper | 4 +- common/CMakeLists.txt | 1 + common/utils/CMakeLists.txt | 1 + common/utils/ds/CMakeLists.txt | 5 + common/utils/ds/byte_array.c | 58 ++++ common/utils/ds/byte_array.h | 42 +++ common/utils/websrv/DOC/websrvuse.md | 8 +- docker/Dockerfile.eNB.rhel8.2 | 1 - docker/Dockerfile.eNB.ubuntu18 | 1 - docker/Dockerfile.gNB.aw2s.rhel8.2 | 1 - docker/Dockerfile.gNB.rhel8.2 | 1 - docker/Dockerfile.gNB.ubuntu18 | 1 - docker/Dockerfile.lteUE.rhel8.2 | 1 - docker/Dockerfile.lteUE.ubuntu18 | 1 - docker/Dockerfile.nrUE.rhel8.2 | 1 - docker/Dockerfile.nrUE.ubuntu18 | 1 - docker/Dockerfile.phySim.rhel8.2 | 1 - .../LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c | 79 +++--- .../LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h | 4 +- .../LAYER2/nr_pdcp/nr_pdcp_security_nea2.c | 65 ++--- openair2/UTIL/ALG_DS/CMakeLists.txt | 2 + openair2/UTIL/ALG_DS/README.md | 2 + openair2/UTIL/CMakeLists.txt | 2 + openair2/UTIL/OSA/README | 1 - openair2/UTIL/OSA/osa_defs.h | 2 +- openair2/UTIL/OSA/osa_key_deriver.c | 68 ++--- openair2/UTIL/OSA/osa_stream_eea.c | 158 ++++------- openair2/UTIL/OSA/osa_stream_eia.c | 225 +++++++-------- openair3/DOCS/Latex/EPC/EPC.pdf | Bin 243263 -> 0 bytes openair3/DOCS/Latex/EPC/EPC.tex | 23 -- openair3/NAS/COMMON/nr_common.c | 9 +- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 48 ++-- openair3/NAS/UE/EMM/Authentication.c | 13 +- openair3/NAS/UE/EMM/SecurityModeControl.c | 11 +- openair3/SECU/aes_128.h | 88 ++++++ openair3/SECU/aes_128_cbc_cmac.c | 254 +++++++++++++++++ openair3/SECU/aes_128_cbc_cmac.h | 48 ++++ openair3/SECU/aes_128_ctr.c | 62 ++++ openair3/SECU/aes_128_ctr.h | 33 +++ openair3/SECU/kdf.c | 81 +----- openair3/SECU/kdf.h | 34 +++ openair3/SECU/key_nas_deriver.c | 5 +- openair3/SECU/nas_stream_eea1.c | 4 - openair3/SECU/nas_stream_eea2.c | 84 ++---- openair3/SECU/nas_stream_eia2.c | 104 ++----- openair3/SECU/secu_defs.c | 96 +++++++ openair3/SECU/secu_defs.h | 8 +- openair3/SECU/sha_256_hmac.c | 95 +++++++ openair3/SECU/sha_256_hmac.h | 33 +++ openair3/TEST/Makefile.am | 6 +- openair3/TEST/test_aes128_ctr.c | 265 ++++++++++++++++++ openair3/TEST/test_aes128_ctr_decrypt.c | 85 ------ openair3/TEST/test_aes128_ctr_encrypt.c | 84 ------ targets/Makerules | 8 - targets/README.txt | 2 +- 58 files changed, 1500 insertions(+), 936 deletions(-) delete mode 100755 cmake_targets/tools/MODULES/FindNettle.cmake create mode 100644 common/CMakeLists.txt create mode 100644 common/utils/CMakeLists.txt create mode 100644 common/utils/ds/CMakeLists.txt create mode 100644 common/utils/ds/byte_array.c create mode 100644 common/utils/ds/byte_array.h create mode 100644 openair2/UTIL/ALG_DS/CMakeLists.txt create mode 100644 openair2/UTIL/ALG_DS/README.md create mode 100644 openair2/UTIL/CMakeLists.txt delete mode 100644 openair3/DOCS/Latex/EPC/EPC.pdf create mode 100644 openair3/SECU/aes_128.h create mode 100644 openair3/SECU/aes_128_cbc_cmac.c create mode 100644 openair3/SECU/aes_128_cbc_cmac.h create mode 100644 openair3/SECU/aes_128_ctr.c create mode 100644 openair3/SECU/aes_128_ctr.h create mode 100644 openair3/SECU/kdf.h create mode 100644 openair3/SECU/secu_defs.c create mode 100644 openair3/SECU/sha_256_hmac.c create mode 100644 openair3/SECU/sha_256_hmac.h create mode 100644 openair3/TEST/test_aes128_ctr.c delete mode 100644 openair3/TEST/test_aes128_ctr_decrypt.c delete mode 100644 openair3/TEST/test_aes128_ctr_encrypt.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 014a67c9f8..2545a17ad0 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") @@ -885,12 +864,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 @@ -899,9 +883,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 ################################" @@ -2053,8 +2037,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) @@ -2074,7 +2063,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) @@ -2106,6 +2097,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) @@ -2715,8 +2708,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 @@ -2846,6 +2838,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 ed02847387..d31205343e 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -725,7 +725,6 @@ check_install_oai_software() { $SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET" - $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 @@ -771,7 +770,6 @@ check_install_oai_software() { mariadb-devel \ lksctp-tools \ lksctp-tools-devel \ - openssl-devel \ libtasn1 \ libtool \ libusb-devel \ @@ -783,6 +781,7 @@ check_install_oai_software() { openssh-clients \ openssh-server \ openssl \ + openssl-devel \ patch \ psmisc \ python \ @@ -793,7 +792,6 @@ check_install_oai_software() { wget \ kernel-headers \ kernel-devel \ - nettle-devel \ gnutls-devel \ libXpm-devel \ lapack \ 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 c3f6d258b3..413710a08a 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 598796e12838ba5d4c0f2486d16f09c301c871fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 243263 zcmcG1cOcdO_rJYo%2t<>&0V-eGPAc3GOxWyD9H-RDuf~<8BsDa%idd*y%MrXNiu$~ zOGM+{`}2MG>yPB-d0yvr&Uv2mIOF-mtSlkL1>uGhFn4s<_7cEBV33`WC4rC-h(`^? zbKXwf4#Xn?Vl_55w0A~2vU5Y(KxfYqAZ<-hKgIv;r&$#gBteF@CLlEqWv=sv&PZ27 zcecGBLi~v&{2)mPWRIpAL{u4MZRn14+$RNr{)ravAzHk9v}9}n=DC~=ovc6>sDGLo z8Y90`<@*g)C#12ng`F)oj2m)@tiT>waXVXM7e_~=t?~EQg@XS`?T`$iusv!@mywQ! z*47{sq?56ug+1!g`#eH_rj>Lo+1E$=Doe;&Pbi zpH;+n@bzK)D%vAzf;6?TwKybG_@6b!e~>7AUsLKRL$dkC?oSec|5;avLv;6b^^I94 zkhPte*+HSg|Ews1gCu$P6(w(BW8rLwdT*zF74iOAMG){Ia{D?GL)rp@bUr}q&zgZ8 z+C9AcssUV!iQPU^e81DizUw*khJ5?V*fnsFsIts=TEEl4KCQ#=$G5KmbqgD$<6&BV z5@4&w=`dwPi?)J#<;^P04=y`weu=|o%MLM`3oty!y02zX8k**-8osGT!&isE; z1TXg?55d2$2MG%&LnCYCjstf@+SpwN{t0qM31Xi(;&;l~+tj?=ha3fBUpu=(*yR<3 zbhEc`{O&3de^%2W(?RU3N!-rH-U8(zK*n~CNRXtm_;*(Sq%Xe1`V!dJmju!th--i| zw>Y3Mf!`|3#c1#40g6A++}E0@nj*w_pErTu>gX`BLjgiyUs2W;Mz%<2XX^u@3;bKf z9Hw|k^$_sBddzHHoUOl`Cj|UEl{g)ycSze1@V;V99g#>A3quCIJlS``zXb$)s^LGZ7zkuvGv}@Cj0~+oDCA;q=(x-A z0YO0ig{lDJKa$_ql`7I2;1$?Ps0SDu+8Y`J(egXvzefq*<%}YKSS;VMf`Xx&g^i01 z$kxTi2yj?-rXUT;1JwV87E#m>Tg7+G@H2I!qSyiQzfT za`+>F;Qv8?-x0(PAl<>EzcRkxBZz|nfc{{7@cmt=;(~MmaFoRrB*-4H4%BlFaQ$2D zeS^FFKiI{0Frg-{uKdg0@_R&akl`P3H1Gaqlu_hS(ohFEIRge^!a}X4Y0PX%E02WvS z4jWhqI4z_E(iqr01VEa%s}BOV{u|+?ikJ{G$*-G1Y%h--7dkF-=J-W23!e&U=|GGl zxQxu4{U+oa!n24B*7Qk-_IM7RN;=je+isChOuT8DCf-7pxj3%~SS6h04U*3v<4R!` zy6K)7k0`fb=HMzBXzu5%Gi*2^*&l^{6S>8%cIk7%{fA3&rfPneOu=tvj*L-1Apj8@ z8)#B2tjsoF{(QFhlu}vgg{zS3Zk(4p{A4Y{Yp6rAJ@`r7JMC6W;FN4j=y=C^kCVRb z2pcgg{!m1_N;x@wn>>ZY{Nva=Yu)W`XGfMt%VHdFtG2%sar2hHIjYf%%2vO0T7JpzCdkTyC4KaMhORY2IFy~plB#GS`VfcDkOqosWj1cAc1 z5nw2YpBKh0zzYL*inX=gq1E3)`)^jmcUMFBxWNFj`FZs>IDuLX0^ZZw&QT2rT}Tj$ zsw(RJodG+s1))F@@U5hq^LaHOyFh|aAW9Vk7!n{FU@>4xK%|B6qc#KZb5cMwh47?Z>&+MF}@QN$B0)`)$HRBgPU!q7pUIa|&j|=eKj8Vgzko=o6>d zfNf&p$nxAgQq&nNeu>rol%&!5!Qo5Tj3F5b7ho$lzPOevRL$mV=wrxkbbAQlFjgKt znQ-q*3lY|N{JWR^&v=~8Q9HU|>z4lteEKx~7i+8Fukrj*#d#Wn)?Jg8XZaV~Tf5{d z&81R47Kea_@zC;E4O<8yE%n9mVNwV@2vZGN!-b2P>{sX7YCMnn(I**`aLPO|ygN?f zWf)I9TuQt=jsvf5<3dc?Fx-()y<(zy-hDnXJNrBSUk zJQu{m2gxYP5K+<1;-_+i6P03*kDhyLKagp_gcAdf^P^lufzh zB~i9U;C7bNnT*g?%T}W+g%EiY9$UF0(|UoD!1p7K(q*CBryRZfd(RuEZb`*x6d$`C zvl2n_wNFdB-iS8lUf*kOXm+4fuxE;y6ASM+# zh&L9u5%kw5k;AE`3TWhPz0{}15YR?6nqX^zm&zJx)KAdGYw?;JE1zA*rznUK)XRAC zxMeivg*=O+W6fn<`QB151x-V`GqaLyEc~O4r?kjUK<&e@V<#U$*yujXnmdm2(wiXG z`t3iic&+!XT3Ez|*&V%o^PNlfb*${hBVXHFCatJGh;EjuDhx#7igP@dx#ZnBR|a30 z$8S6zm5D3*{$>5Z3zX{*lm@E0`aj+Yd{D%AjllOk|d~Vt$Z3HRXnz3iKCL?fCp1hc${owB7 z8}yZBeM?bmyjc+^Sm&DfqEuSO9VJ;>a6Ro+N#Y7M##ZpsvG;=3F8V%d=u@eflW!L#^fr zBl@DVq@%ctU01eypM}D7iE$Ts)rlo{JHny@s+ruedbZ-bRU1>=z7-AJ|DW5Q0%zRU;6xA*L29|LwC}Z z|JmpBh}zoP0Z~K;@QoGcGdq` zl`wz-UJx&smsANEVW_G$rp>Bm9FPKTmS%O2oMy` z#|=d(5)2?N=&$AVov+<2{~%xAs!o4TU~s^)z)(P7aDHwuA0G%V0OdyfQDD0Tf`g15 z#AUnw@jq%3&JX4W+yN92A1^-$jsOF8_9uD$WchoQ#J?ynUIaG;0^gCB0FVL0`4HR! ze19^qpDiEd`2Mbe0hR>;@>?hz#?24s1;Kd%g@XD2VEMa+jf0B(mQw#kiNWC9D2ET_ zgK@**0w6e?mmACr{R3mW9hQTPeXC;pMaG~|ZYaPI6vofZ4+MBP3C> zf6?uK^A!+)F`z64KniX?Ah&@7P8JM<{6S*7ZIFYE{YAI`jWIBICtHOGAOKYYjDZEX z0Zj1+#=iAb4sf;uH~y;i!w?8=7!(2oN(48s>0tsui4FEA8~fIPI>^{x^!wki1&j~Q z4F?=6fY|`f5Fi*o&~SnL0bBf}%e{8P-?08Y#^3;B06+vlBsTN{?DY!|3hXaB{%@ua1@Jur$St5K6#_LVC<1V_yubEi-&;|; zJ;#Hb{dLa|H;0PF$10Mt(91<*DW zwNDWLN_sy+?%fpsFR}M+y8>ki0CNMj2PhZL2iP7MNILoc5JDk8>-Dck1fU+njp7S% zCji_A${|3?0!CHwe=ZyBMFgP#xidj?a6A0Pi12MYK==Us0~A-F08r!S17Hz90>IqA zi3#7g1FAXuGkbqABiLgP$W2hSC>W3h^8?*f2p_8N@SE)JFnd31^)H5pJ@$YM1wfAg zdq8*qU@n9gX!pVYmGpkzt$#5_?6C)I0~p|uQLQ5&MnK>|!x!;Y&F`aAe`ShqiB$h=G{COk{RSxMKz56u|E__xH%zhfO5Yk-FkmbE+XmL_ z*9vmgU~1f@uV*Dgr<1flynEEDf(*sKNSG1wH zqS`}eenu|zyxbY~n=)jwve(_oE^d#0N_+S82}7&6l(DzAGlBtwtQ9L4n}Q1&f!>S7 zigx@Z4%zstcgTy@x|F4GC75vVy+ouB~{JNRLPCAfH$_#3zLb(HtHf`hZ<*HLn z99^f9jUsOnb}hS*KF0UDN=nM#*aE|&9+rE?(QAQ5lOX!V!hdmK^hro(ipVv2p-?El z#RUZUR|Rz>y2M&v-O>3BiOXZj&BCu}CB(h;T7|BUkXzyxBMmbt?+D2X!@(&({iRH~2;n%(IiM+K&j;JkH9U(+iFw zAT22daYh5+x+4}c6X{MS+Y0Omo(pdYJJyRZ0{*xOA`_y9}+2m%VYb{H^L1AuI9 z@b8@H{)EO)!DmP0e~GVeV&ela1r$ijp*s~%2#5~=6_9`9KljFd4j_xYX|lhU)A0eo z0)~Ru00M*af%s6kg6}stc3*5i1;ri9{L5kk6o~-n!oYkx0}y-wq~PcOV}1g>&CiGj zh+aSL=l@vD<^zhda8yj(0f-{O9u5@% z@d020$S{5lVGl;@y#c6$*7n!&HBi;y=0)Y{0zf7NSQ`K(V1E?bPbdPIXZo&A6pGmK z*9TApKhT)@-QWz6?|xtXA5p~riWT-IBM)K)I8dkgw^-puq(WFSn7V$^Gw66TdMeMk zu?8mN-ayE08NS%LB=#f8K5Q>2;WH+>5D8ITpvi(Jb2NaHpMG5PED)Opt;EV%$ z4%Z}v=oMzg%#b)%QO$Gfx8BaAXUB5W9~r7nR?H;!7?d9COYmt5q4yJ4j=;girV89N(N1jqA*Qs82W zm%-$T^2{RdRLRC5o^+cc$C9WYk*MYLs4nS^2lm@PbmJ$U(!Xe>(Rh`$dhyJSH}XYW z)Ul%7zDZC~Ay!G3nO5r5{ywD35ZyW}p@0P_)ZZC*piH(V>Btn{va70dQ(NraES8%x z)S*Y-lAk#Jx&VO`WH5BGd01|7CEa*L$?S|wGWq?r&>?zfgIdGwi6UV$^7epJExK=R zv+4%UT(KxM5@C2fLsuOrM17&Q&1C$u-Aa1RGGlLaYR`%aX1eL+`&XI^-s%yy6u--! z8BR6u_5Fm`96qC-<@?oE>-fi1CPm_~s>B>Y+29cJt|?2tdvx_>8ko12r(RHJrz#PK z1Pm2)%H4Jwx$NYS-D0EqUNe_IT5D4!nI|^NC1<`V&fa0J#I&(_qiMw(b8el|g~8y+ zKu&l7Z^Bu z{SEielWGUH8*sqv$F+Ze{D24B-|GKyvmS!{|MSj0hzR%QDiJ_;Zs*UR$JFL^<(%jX z$;)OnTO71Ayq7%Roo>!;dWw*|p+1rL!TZt^=DN}pu_toNf?{ZbC*I4d9clImd2xN=gUx5t zPvc=cZC55*W@aXBN{ZH+-M2qjmVa?ht(lpTZ+yLICZf0Hbtf%>hdTkUXf*!)Q7Un4D{dr20K2fx(FQtC%mRx(ibY`;^XXs&gaK{QyTnRt)DT>LIa#vGIM$o zjIt4ZmmE4Sb>?esgsl}uD?-s71~^)ao`nf*sk&{vA31+qWHcdzg@?ZrF*< zjfQcNoAp8UuU@qZPE_S|hh*n|k%9PXd!OhWdU>BH*CCVY4$Z@?xj18VZtKEZ>7QD3 z#x=YPG3gVZ@sVlZeXepa&3b;?h)H^ky`>IvB|Y5O)sMJ=ysGik^NPgRGRFjy@xhF1 zXvq7}{M1!5`*7BnV;6B=(bN%N#(RvBWZeSdd1(HnK&+WMkK}DoERX2huhV$Az7>rl zEn3lOZ!E#m31Vj(eRQ6lmdx+3y3wifGOX3#n1UKtYsO8Gmquqo>Roru``3A-CklFI zGdDlYx7tgKk%(huW>EX(G`+lI-c{w2M)EDQroXRzgS)zX~QXeh^A!0GU~u*UDb#Tc(N*XY1= zH}(wlg#taw5Z;z<>{)wj`nS1(oxHVe*W$ zWQ}*jC6C$+s}cqHf4GHdI!s5UESPU1>x6zI2HfOKu)02~G@2eMf3>thC4)ijIF1#Q zc9FFcys#+*Cvby}R2Rgl{DIi47f z+7u00SMN&8z=tVfPZ0}+t2V-Q!I?Rd`@z$BpUVoG%rSML&3Z|)DXeIU zI6jH@DJQjZ@)Gl1Unv(w5og2-T-05G^7ux^SUgF|r@wtK5T z1WX4KcHgv)3~ru)pOYn&-6ZFmyueE*Nvb{5MYufYVUb~z2U(=#oRo8d)?MJNYtL5W zZd(YB;9@-np*!Ui!e(3tUTNyOffj34!%9pTsF!CSCj$4rLuT{n6g|E?W&Lep6AMnf z9AZ%;TB8)RJE2u+Tld~2;nKuV@WmBgJ<G%(;+VdaWOQFZ?x>DLMZIogNaXNUoSbQpGRI-A@tM4ci24|L zd&|o+N|F{sS6HcTC^0L6p72&z6~~15S47@w&MpW(lM@~i`o!^}ME_Lul$^FX`I{y& z2O?5Nn?5BrGrF?Wuh&KCB6?yb*$F}NHuhm(Yt2tp@n3}}SR%*k))Yf*3&+*D7&WBSGTt$N7T=sIB%};0OpJyw& z(}~*_rH<8nk(DJ)C(TN!c8XIYU^8U)73I93TA5RH!#r@EvD$)CHABS~w)E+1twz3d z$%s=rW`_C9W|(tBje3Wa%c%U*6e70GI3F+vm2dZhb(6L8;u0T@RaBLBT$>qAwCvnO z6WI5RoPl$o)JumpsLN99!n$+rZ2D4Z-IueN7&^n4z;Ax%Ifrq9W@W&E=8R zx~%h8rmHdp-A~%j-!@{mxztg@d*|jwwThd0Dl7{AWc1gx+RoilGn6Zo=Q!yym9#Xu z%s94i);?@4T#MeDZM|&BGr)mYgxv1oOEAeR9R?+uMCTyI4>8zvoV64}Y2J75gYeG2 zgNMJJMJEJv_#63%gYgvzX2`>C1QtF{@urC;a6|`+#$IKgBH^M6*C{%F;~gC$#parCaC!QvP)oP_?{2tn^i|z>p$wV!?@{Aa zW3kE7aJ-w67(PkKok+Co5hI@7koDDgpva53hvZSTe@QKu`T|P%)^FSG?Ang%&o9~* zE;E*C$J=Gw^5vb%Ul5QHt0xafr$^M<`5b$4NRov~VGwyV z=Lsv@-4lY^<_}+I)d~x!+R>h-NsyAMoBrsdQgK@*+&o?GNj$cU`jZVIX#<$+Qd%fE z>-!LbE^1L{+LLa^v?nD<7+qClDy>K05+B@B8O3mv;FSEl9>Sz#@Fi(4>c)>ZB`2KzxFLY?|~%6gc;qH4Lj^B_ zOKNbKH<>F6k9x%(8BF6hGB|?tYBA(Lg8q1GEb)XLz0j1o%z8uS`BnkYu!d zO)T(uau8bPL)S~~7`S!@qx32CeA@(UECTP!6wgLFO0+mMiK36UU`EhSYn-*!Nzt{1 zW#aWqoMh6G;J7fpoQht=`wTr|xK84I?)aQ5uh^R$!1TsCB% zuQBS2-mxDo_YEI#rhX`vOv*B2x)xs^)3mYJ=S6<}5&fZ;19SWj*JpukURUuuacgF8N_dro}KFb!Q(kl zprP{Ls@U^1c!6#Y(2D{_qJfeK6lj?NtutUU7z#zzM1DORwsSHT z$qk$`MV<5ixswdcvg~I|ySdg*N&0(xI0>wznSL&tsJ06x1&fNssAilGWE4sI94i+JHx5ieP@tne4_{&kl$<~(p z%P^MnRgK~`)nDAHh6Zm14)iS@@`YXjPiYSY914UC#v#WwvHmFFm))AG8&zFa*dtHa`(T%SO2BBq1t0_6q zQohKT;~{y>u7@ihey86S4{O=XR%%>URx+)RsEb8&)+MZn7sov`%HbH3I!-~|TtuYP zy6{q70F{1hl$!Z_y!^7HWT(Y=JpoNym)84quDylmZ~EKX9_cqfrXw|}QV1k%^kbkM znVCI(RCu7cIGDjG!~*xk9Op`U@@`?U}^!)tIulN*!Jzj!M|{Dd#8X8l!1S2H|?0>;i}Hg8RP%bZUXApKRLLa z&;E{s+nI|5b_-lU04U%CbCSSVB0n(w#|r^k4ZoSnl{U4ra|X`JAb+mm1I>x=n-Nt< z+L7A6clzfV)S**`KQI1+Yuh_-z3A!q7Fj$EIj`aMrdhfXQub+)-UH}|JfT20y=)%vdcP#9iG5k%Z{M`@pNCEzt zch5fqeNW)P&NpX$z;pk*Mm%6*-wkB1M28w3`uqI^@pEIG^&jms6`pL5|ud)Nz zGGU-~EA-yHAr*~vvDIBx7rjOP`KJsSHq!H5C1=sWkDA8a!~8X96>`v&62q#wTzK*{ zeA>+m9u(%$e^|UZ_F4bZcEH8Y1M7ZQ3PlnzUg~>p%f4@6smSnolSm(KqPjrJJ!m4o zAl0jSF6_m&pq=TCD2>HU7RLH7;kL-yDxQWwQ_vt2$zO`Iv!%=BH_Uk8`Ak`cO5=#76nm zf!2=%W(azbM3?+GRL%Ev4P5*+UXIw_<;5llKPUMXUBSxob-n-k#g3QS6A#d>={n?i z!!bG#jg9?RrBBWGob>QHIhYlu@N#B}VRZoa6@VbxC0B+ahWhSzivdn=w_b!2h$%JEI84G6Oo6lzfg8fP z9IW_b)}?x)sd{5QN=5bX7z+zuZQl70Ma5y~P7IyKy6Ns+=gd44{6+7Ie%abQFZuSU zKM#cP$@{OLh#y~Dx#w3>l{*?4=8glRW+14|l0H{6(S6T?4z0EV3x;A$=FttIN;cFWq*#FH$Pu(L;Q1E#zeR&9`re1#Xeubr@rzp}RcwjyR#`zQ=1; zdT){pkCE&-My|^Pqm-^Q8-B@thF4%@uz25V!!?i4L%BXu*hIwH=W{SJA|>B>XCb0{ zluKh`qH)y~Zz&s{U7AQEE?NuiXHlGCi#7NEi(<9YdN7qj|Xmtre4cBU835Jg* z5T4Sn-=5ZINj&1OEpHfPL1F*Gpd(`I!>XfZFp`uh%alGjLsbkq1(&@UrMvKmL9Jf= z3n@%U!#>>il0>&aNh5XmRpFNV@Wo^0ZDgw@GSyh>9#N4*m|GTW!Tw+gLs9SJ$@ON8 zt3FihZ{_3}lxlkTipVWkn)PmBhdoRQ@Y5<%Tvjv*UOvr=dFMEIwOY1%`$X=I<0=km zcf`DzIVX>rdF0TkFs~4VtNU9}!E16fh-8-xk{$fBfor519T_Jb`KWs+qKq#YkJ>mT zBkO2+f-b#)wn(4kwCK3*oicMLt>mb>o+6%ckHB1+u?f+!7-iX#7TSBTG4=2ix$P*O zhb)(xVm00&3zdg3#?i4qlLg!wC^n1w`aUb+($or`lHXDSy?T5jM3+b zR>*wmJ*sJ!T9hbn6q>namH#EkejYOb=Yx4rELmGgHjfl>p706b6iyCbA{w`P8f)D3 z?20q#A6(opF6S5Kg&DP%t~^&-Y4wU8eRzpRsMe8$F(r#F%j^vnu_xgrJB)X!SWNm@ z@86EDS3(+VDI&Neq9j&i5XO$oQ~VJ%-OC-sqr~(vB`~1}eF0a?Rf6J!2Docu<)+R)W;A{xz1M zIm0W&7w3&4amN|#{mmocm>y_Hdf_iw`tLlBc$#@a(*^VDmCwqM(!gWw35?;CLPsVthnZ9cf7v|G~{rP0C zL=4R*e*Z0(M>p)16Kh*=rW}@NkPTuq+P-7-kr-{~j#_9T{uf#&?ku2Iwpy6?LYLllb=f!UOE?^pm*@s7W zzG_j|ZgCC{k#O<4QyiuGa?~;YN`J2`rj>s#mAge)UlUWC4>R$C#s``x$s_Ov_pM>s z)H_S@lPq5ia1GBbA(ZW@0vaVmFj-Ac zXAnoQ3y~a+5qvP0>p`hqCwQxc(zi(%YKR#TO1MNZ729zn8LIUWj*u`XOnPV9blh2P zTwGplFvBi=5dPpq^}{HgVd2YS_v~ZB$STT(H8`d(+P^DsW79$w`b29)QOdt{APzb) z)0KV;;+-};Mmzn0>|(XXi!u7C zMq(n{Z3p|Bk6>;C#!eA~+aqPwEsaURfuGBibwRTvkKI_$zVKTuaC34|XhW;l>2-~J zIH0Y?O1jK=^sG%urw%4oAf^=e`y5e&c{H!)I3^Ct;vbD>1` z|0@|p9m56=H=uUQ;mi=2)&}fn_w)ajCGK3EwWqvqSt1MyT&M9bv&7f5dJ)}xAFf@$ zG4eK}S}LI+j$ir)eX%S?-y?3#3g6h}w)HpT+H*9N3qAUU7Yj_n@+xd+f--#=GG1G{ z6t2tN)yfai`q)L|RIbF+c3cFea+@-?A^BEwAYl~k>Et*h8g}A?BimkY58Wt`#+YH&_I}Wgb}!aeeMVfrmpH9`mJiPbDIe8%u>`Fo@i9{;uLZgC zr{f+b8%WSt!+lm&k}EQP(i*21*b?4ls9?Mk_w=KgXl9C{^q1pEKrQz$p<$;=k}+`Y zu~YJkCyybReYa#3{OT>j8n*G0?^fMqhUYzKcD8*M#k@BIwsi<*@6_YIX zUK~}wW!>jDoqcRg__1BD4TkX|1p;q!zwxW!d>zXtMB6AAZ<*vSMIS7j7#a8WRGQzN zE^NaE4c1izSj8VpL5}UiIl3V44@kzq=o~6bW2^_Sv`yYkKU1m3!89bsIY%ebYkGwC zee&%xA~rV+xv~mgIc(~7aa}zzx1&5TLYU> z-H<8%5}ZdWO<}h9_!I8pP)GPOvT%eP&v#vSQXs0hMKSK{7oi^7BR&vV8fj&lo;yy7 z1}CZRJu@$6YJRnmDFG#S6%*~id*aj=bep{l&$V`A z8r`WzWYFdI3=Y-ke&6W%q;m-KX;l#!-lz(u==mT*LG2)t%QU+0ydg|9ctZ^Ae%z}5 z7AxpUV)$em3+F^xUHxwAPjSQIAx<&gvuAw$l$Cw&%^8YfSc8teFXQ!mz2N{ zLahW()w?x1`@ZNtl^~$5V;c5KGSMH+HP#TNh}EbSd5c4KN=*b!L%5qgt^g2$Bqz~EA`mDX7oZBOfBAi8_>kX9c ztda!sf*TJe;DMn6sxylIc5;uPXi9v!d1s9O-bPY)){q$GmlDT3w|zzu zi$+LULJR%cC33mmkz6MGk(j0o%R9O%^3lWCr%sQO@(`x7pEeaM0J8a3ABw=Y87L zfdP7VkKW3ZwCW@*pfTNnbi%%+dER}Xi_oyT2{GV1#;VRr9C?o|M*ITqMgtF4KqFDx z1@=*MEOdqTb-Yg)q3@P*0x>?&5q(jPe zV#s5t0#C_+8WNgrttKbM!E43eJwK6)Fro4cc(Han$o_qEhlXaj@f3 zd1D6O)|y08Bix@=c_w;En_6tYdAb~Wm+%FpMjSUEeuu{F<1Me}SD)i6OAKBp^gA;g z+b??c7EZ_d9W)@uDdsK=*~y)}rl!G<)ldGJ?mTh!o!R_cGuA95KCS9Oex8gJs)BxmpI;f&RHCdpMmuuU09p2 zYNM#vyUiTI3-_I;bJr8rCXSjN9n@10e>glQTh-}j#D$MO!_7Dbb}e>Ie_ikB+Ew((bCWLZn5WzFOsVJX5tboZU<8u% z^*WlA`DfCPuex3e!LzeU?C8ZCD{;IWoHaW)a-V!<@XqSJYw59mwvSu=B+V*UpPuc?sYu}5k``uBO+I$(I+5)%diA^zs885;WTCgficU2 z4l?DZZWGA+CJu#H$}QP}6&T9J7Ut45X)ixrtv9_ruOgViT+_SN@!AT?!_`2YpI?V7 z^4>H=+{N_P6Aq6F$3&9G8(h#t^hf>Vl0+$OdP8Wumo_eMZG;&{&9~`Uw#2>^Dwq|2 zX*az|5~%|T;?mwAoclQZC7UrS(YAs|LZybfgsgaBU{N<>Kv>*_I6J%z3IXgaGx%dK4FVHyfYqI*qXGO^3Q;G0~bNWvh9WieEg8 zr%M6_jSX1o6kgC5SbYYCF_E7>S2(s>JUom&6&7$Fi%sv|3(it9(5CSVZy(=sD_w?Q zzo+%juN2;cb@4RkHBIzU>Aei_^SAg!@u;^G_iVI*e(@29tS)N7$Jd76<4{K~+})r~ zvVQdD?jo(uNrSAKi)~RZSJzz@X$(8kF8bltN_t<#YOH!4B{#-ELY6LJSRs&Er}0&b zl@V*6Ql}_wAlLUX38$ePS=u#;>SH#tgQ}xa!+ON>dQgG!AUnC@xq{b~=xjplTJC{j zgmDFLR&0mPv=nGBk2RVt9=9l{h6EM_Vc>|-26P}WlhRU2hRlqE9xLbxsJ(beD_z2p zxsdY6oWCp~F6X$2FXq*?&{y%AOWLt{rxS0tPx_hqa&1^oozM~z*siw^_goBnB@j2X zq(DG_H1?S*Q})Q)9%{->`o4ga&L@&XeT%$qCN{|{dC_uHu6Nlz0#7%UM9IM@w7nCBll zuW_I<@b9|8J2w*V33jg=j5VKL`CH@qQ}ayTY=Z^-;Yt zFk2~1@1o94SHdQRQ&4h(S(NTCbE&ADkkHoF8H>M$kQ!8Kkak{K)vB)A4PEg+BjT9s8-eve7po`cR83jLPnm zn~V?7v3cU%!eB|N8K%5eFxr-Utul9o+Ms3R$Hang|9<z7-?*ukM6Vxdv^!TkcW5!fVy^;H&x^n-DNLehd5EZA|YF5`LFuC{Z8 zmu>S42r;Fr4GCW4uCiwK>G~(>N5X73&U~%dP`J?3=pw~YsB!6nJ8ZnaoJIa(+vK^p z*Yj`u3np$%EO+`ihKNfM;&T@bed4pbllffdarEWs({hEgS?i{Jnu4paew|`sg|fya z>Lg)lGLE$C(EGO#9?BPDdfTnUQu{WdZ3l8)=((*Ot3sUowJ{LEpa7IfwHg?9nYF@^qTH@g|YkkKIlE zQs7*LOS%*ZW$oUCX5M4LMINP3*wgyfhu7ac(DT_Gm4DM89BO!ei7(WpSgd}yPftef zc^kjGcvo&Bxm$-xghvzq-7BRIS%aAN#XiqE%7A^W_gp8FQzqVEv}!{MHrZa^62(>6 zmR^NJ5jekZV|;d{NCS7**X^}$nol4IKE*VDFi3juH7W3_+%3S z)k%{1wYMtsSEBSs5_#*@uSt`G;koE+1d48w#W~!!tY+a_xObU5Zy)1g%6OWW8sBqb z)E-BIr{Bdy`f3LfC(P+HxekLn0_n4jEZ%}zSO<>K=MJX*WpTGE|&1;-@Lkfy)iuVEr1)83syX#v- zV?8+&o=v8H&oBJ!DSFDZupwEo>N*^XFJqmYYBqNzjkWKZ+TUzovU9{+O>>;f$|O)_ zi-tTNHx!q7+%V$fZJ9}5b95yeKbFjbI8Ce6=Dvw`6x_!4P8~#{tEBe1Gw5~hL$5rJ z2@=T%o|UPQ@!CKah+n+XQqD1Fx3hC{x(cwvcieBQ>B?|%L5>pn{uiBi;kUbt(t zko+q*myqYP$0qN?EE3(78C%rfQ-l5PdM}TRZR8qfZQ7BSSGZsQWW&<5CbGI@CcGgT z)()xad8v^sGVg$iEbdmWc%n2PPt3m#s(wOyL|ev$V{?)G5|c;368#uk)rrgCDu=a< z!dap*d@*&eJ~|2Ud31cD1xwR_4xC&DTZ^JZLzz>p2J>9RG*5;)yR=DZjPChGa*<|b zBQ0<7|aO;>0G|W0fd5yU*<_;rUV_hVXj0|6@2}1c!2pi3vJ284hK|EN!;N<$! zZUNFHj)-b?=^*ED^YB6!y|=`rHLoya;^1xxsiZU;t-~}db9zeFZIS973p??^Fb^)&tFPdb;3`-}Uaw|LRL2M+$ zDbnj%O@Roqiv?)|$y)+d7>w~fqto0vL=j0JwoT64(s?P)YLJ@F$HpAp(wDvg`p_?8 z6*4^TzQ{25P~8BllJ~RzxySx!xOY7*S;nhuO%gZtw{OK?UFjjGG&^bY39IPbnk|6} zPRT}^yvTzfUpI$^6E(No*e@*wXjAcEj7u85zze2A=j8Ms-^i_nvDG_!c6Aje#t1qW z1#a`|uGNesm-pKXglkc*&n8_rez91R?3!m6dC$#lyKytKf9jJw=w0>WI&rRf8!9zz zTf>|7H}lhMo|vgJ@X5NL+Ge%H@hliNDlQUr3qz(X1O=bt50AjYdQ++K?4{Y!>#M`q zg3~3wv?rOwG?>)o&fH6_mXLn9X>=q2?WiJnd1$!hAYovQd6vmt{r_#P*hRu%)Dt#8nK|=fiM$a zlxSbnrZGxxzj7hCK#P$}Pl~`*S}5A_9t&b5A1*&rO(}S~rKi7E?CR#~=PX2~1$$^6 zyK&Ztq35j?uD1Ib1g;^j>_gcaixU{UkLY?LkLx1Be8~D|M6bTAqE%0{&SeZD zyRh)LTd!zJ+1W%|k=}Z0F7aM+;=+l0HMmVO-Ib*3dUz_zL!ZDjI69ChE?bBORQ^8E z)UmeNYqB0G7;LYf)yz)Iddvys%nPOHRx7PMo|3fu#LpFSEvHN=sjxDAD}A&aiOsS) zl#xzc&R}r*3wm+az3!JA16(uKCCRorJa0J0O&>#TuOJ8IHR@^?_3JXaZk0WS4tqMT z2{sqacaO*SuuXQ_JzxS0S~jnh+eqA8wR+Pqh2UF#l&M4a?*9w;&j0frjz3P6?*7V# zL-2j)7gGGs@cqC!;ho?7um`$OSa^qzeJuRXO}Rs}^}kxY(^dnnfdejE_z95yH2MDH zlTnL-tDk_2OMcPY+WFla|HL&?6uxr-{2w0; z1>PFCardW3AG&Y*cQS+hcJ+_R$1fR&@B+EgFNC&pMg1Q+2kwmF`_*LX&c*hBS`7v6 zbU|Gw_VauH*vkAB=TP8klV8rY?p&h($7ch^0$fo2i)a5hi2TcE1E)B^z-f-3IsZ4t z0s*ea04^^6dG*0x8S@{Tum>`#gC`?^+prE^jdd^~0}lN|zy02Vf0u(Dx)pe@*9u%_ z`fqcvAv&utAO|bGj!l<{ogHYta5Xj&d+s!3u+E!8zk^i95PW3uRGfsKL{pDd$M$e+ zpPnPz@~NR(+0Lp}N4RdAm6@s8UFQe7Ebbp>v=_2@coKxSgJ%62<)vFAnlt?zV*BD) zPWRA^OF9b3c}h!~a-R-%h`My?D3t5|{aZJ|?0OmsYL_$@>R)7;HA`N*wj9=6ewqHk z^+y!3$L`{vI%~*8A$y9#HuuF+P2Z?DeVtHVBhGcfr8B2aen@E`Ag)RdhZSCBj&C6OntBQ@Ord5X78G?wO7)1H1Bq*22=@Rc0iGn@rxh;SXEi8kjWTS;@B z?TeS<5mx8rxL_orqt87^j3%EEow(2T)b6%8NWoyR!%b=2r|w?etW%DSOy(!;246zm z+h^3@k#JS2`AnG^;@yj!V&r7QwGVPs6sQgfW_n=E`f3OUE-XF`^G|n;HF7x~K=zI- zvM*RT`t02QqwTB1s?656r8`8VyGv?sHjOACostp~0@B?L(kdn0h=6n>E#0j&2qGoj zf{5P>Gjoo@cE++gso@cFh?X{k~??ywJ6k~qgPsY1l1@dYf?tFGK=A80n z$zZ;O4i@wLaHS;l$u5e4$% z%t42p70duKKRD#XtFs0LyF= zoD1S=T5W9>8)~oV^PdHAzhuUBl1K z@Vdexqa-9@4(}PA?~t;m!Ux}djLAM^p+YuA_U#3yPxriP(rC6Z5c-b5o}}$(L5sL~ zX_0puf8=qHNJ@3n)J0Ev$yS~cwt*(j zEmS;J+eFyY!0ldsGM)@F3y~F*4a^!>_QW@-p|Ev(nh_wjl>#qh-Mv=8p#^Vqg8KdI zb~RT@d9|nhjf(C?iQDs7;zGA4fCAd1T}c~l0#fBTG1?uK*aiXzFB0NN-!0ronmj%t zzD|S3>JI&bLxDjcBar&K@HbLkRBCaTJKIx*G>UOV*Ulp6V&T2yxASrYD0NnHx9Oc( zPj_HoWX$%N!K89>D!?(?U0fLfk+kUDtmD0VWYoSlg# zE}1UR3^u*K%}FVrs+}ry5LKTu-%N@{n?L?R1ER<^q(<&rN)(ohH7{}~`@|%JDDz>L zoie$24}_4xVV+U*Wf+PR3!E9+68_hX&)%&e^!WG+ zS95l~zaP!)eFN9K?wYjOfw!%tQk+P4eM6mlebGDXkI$9lW_70JnDKeulue6D^S(v3 zHuT~5_7SgWy-kRSDyg6)EwPLZ|KR4hpnZFz`gdK*9T{iHUJ=&*xPp=I$poik)&6HgG?rZ7?(mI$+iW(OY zuLtiY2WO8&ttJ`6@=BvodI#fDMBzd>u(h0Hn1vtY`Ab4ncGqX*z6c{4V2^6udDbC^ zoVuNPjTOfYSJ~)x=Etd$BYsE0DjgV!BpJ=8cTvpXD`i+Z`uNyz3@Q3PG7iPTDkMp< z$XU>}8GJ$_COR%Y9okU$>?kmRkkzsCgZ8lwTafO$@O0pXPtazmbrRyZqt%a@K9=5r zdyQ#ATU_-dvbYm&sf#q>5=wH$xFB28xaF+&+?2lus6doc! zE9Y8bg28c*q@%&X)$=0g`%{ zj9;}Y9#nl%%zZn6u3pnFPgfEy3iqz|^Je6@;#l6W+3;%5988M~rYlpBHsu?cr!Zv< z3}1QPxrydL6w+ zEFaF4jb5xWcvoCLT^dB1N_GRGD+el9bwGch$cX-%BEp6TT2|cAd&6u(cAHbRr4q*P<);F% zn2Wzv#<#&Kr-K&w&x*e7w2N}46c$Z8C>rcny*C<;>62Xu&)Zao_mb@)f(f9{O6qUJ zo>Ja89QB#Xq9)E#{SF`LP;EaxN}J&Dg_li}d&9CMbL(BC`_@<90m(sLNUH@#lcpMc z)%)I=J2g1@L;cK1x*t-j-Pn2%2Pp2}cF?XRG<;*}J)6~<@3dvCRn1?v@p-i5D6BB( zd0A(+w-O@ZEE3=QI9S;VjTb#_jX{WIa!PMzPwvM~I6mNgT1KG7&G3xYWG-8i94$sz zYmJ^idOGsh1=;Iu`lRz+&(EH=NIfgfAA6XRigz|~Ti5V9heJA~T##T3*5*9#7X==5 zjNik&KMK0-G&IfXXS&jHdr3yMhj4OOkm!s&DqOB&166zrj`((gc7CpT?>jc5GO=29 zzp|N!>L-@si#P+jgC0B7t9`Br;jF`12>GNwKs%TBw95+1=242sneTljFT=68e?k(#yr|ZbOsrb zwdQMW<)XK}tEB?{&38sg3)C041|uow7Vo|ID(`?j-fy;`K`DcsQj}N;qsc%wf`3qx zj8p*G^fWHZHSw^VjXua_(k!Bb^RKJUm=3v}WXRDmdgi#w>XAQ)<`8odd{#LIN3p!W z|7asCZ9T5uHaez<)@7HJ7iJcIEJ4>BL;h&BRoUQ{=A+TclA^pc#}ll!ja5!4xtt41 zx4)uQ=%v_;KD_kK!Wt zFUUzbf8s_t&uT!Eh5*DcK%9IvM!ul9`)j{`DGh+I@&b8)EAjaSG2TB)1CXu&|HW0| zA4}E0R1Ksh*rC-_eEAhPV1VM07l6mUV);*$qrW;WU?5q`3#9q3O8?GT1GsO1$(pN|BEU~| zDMt-;*MPATc3}SEs_x%8YaoDV5MXY;BK;GJ%CDAv-lcLrg>hB&?;KPR00DkZlyq5| z^Wqi!^K<`~`O@D>i~g8M{jC(~IiJG6YX^U(NO^(R^LJCE6{@mfQ#|PP14Y|Ih@)gZ zG09)X!(=(cLJz}X5hev0O6WM+Ba|d9`M({|it)*Y;Et0m(FEf%?nZ<;#;-?mx;Wh5 zJ#qK2t9?MHJyfBRn7?&Hu}fb=wJXCMP0^vNMqcQZ+_I*bQ0(1Jy6k3M*@#7@%2n5* zvbsXU6WCZj!REe~Wg0rSMhXsR`IM}p)BEUh!80j!o023f1^gCZfwyv4b9Xk%v+oyi zTmyZY@LC(gc4rkG;=&LEP>V+f4DZW%vh$aod^yDE@)IHvx87KFz8#p=$gJSKbq{yt z*bzY(S>s)40XDX?M0W-=f}k?KHX@sv?1>Q%I;HP?*Cxrm;#|>^{PEAPP*Jh-9=XC_ z!+T9CgDBkzuTQD8tf)D#{d9C)ACW=Cd~ldZHZkoK?)B-coPoU3%SNNeYb$Spw~E^o zkC7e9D<9=O#rS#*sbMLcmqNg!RUI|+V|$_wrc4vi6xfO;JoT|WP(DHCB$*G6;t~@l z>(q&OKHM}@U$!1-lg8BS@+s!-THs1f2WCG0YH~WUXNK-dCabLpV{F0h3Av}8eCHS~ zg+m*!2~TOMTqDMU1iyi#Q?XnW{O*?cp~GlN8e#7!83WRwjU$Ee+%o-X>PcZ?h#bW3 zLvSSV7H>HGYi#`w$vN(|IJ-%mgXKy(m6YnYJj-~k9!$Td2y^-nzjNI>f^_t?={3Dh z_&w3B|&~=Ggl0u5xWD=Ox zWD1~oJ>qz$g5D-ZCfb2(<_Df+l!+#Ry?iC#^TinIEClnTphWis8RScfluvuPXaIl20DFBW>OyCiW^rmJE7Zl0td@rfQDY(Ra=KZ*Jxv)snvxETtyKeZZy1lIL>jk|uk!BX6`- z{@EBQL|gmxJB!lc8r{;7E^C+9b(R;z6sGAmxtMn?VsIJUG5f8))ixZXL}z-Zsb4g_?K({_hnk36!`BO3!3nGt@NB#;GC}L@`e1Vszg&%5azjyurL;&#D^$*PO z{_gevN>$ow0fODIthOQnQ$f{TN^=y000}Mca~yK@ft?|HgJW@h$V`$??##oOhnjb` zrhXs$@fRDO0jqY&mm)9jky|RAHB8M+&l-!pSd`R==A7K1MzM`HQjEAMnW8dO7<`7? znAnn5<6ObY{c&?d-(O! zCuhH57um)KcRk->Viqe{h{o+V5tornb_ZqDo4B-rVM;|F(mP;y8Pyv|uQx0`y*IzS?S%`zp}9__Caj^E zziWeQoov3#hc;d!*QaaYs?gQs915X))HGt@@F=IQ-7r3HzMBCQ_dk8bkQ&Rz(?O6_+z?-D%uK{RqnZD@pfJKI%sjU)wQQ=culK!^ zBm~2bBV49`F(A3+&F49SLRdQmXVkruqRBVmc}nglfj+{9?=bB`gFF?#y<0WAKShAl z$N=)UkuIOMTE4l3ZOX?1v9_S=IjC1OYe{4~X5-AysrVj7!&0R{)fBLnJuPV-mT36bSRdMicyI(=rb=z)au&8x9p z>V@*a`TXYz6!sBiyVP_z$+6xV_-k;B>a2JO)rmN-p*6fG)0!pC5yZdGi0F zX9sja9`x56bbcjY*zvE&;P3N17jMh2h5rov&w<~dg^@qb!v8P5^B?c$|NKh+@s;`W zO6Gw4{(yKr{)FY!z3rKYO;t)_t?O-h9=62vifB`>3t(X)-==j%i^WlqMwYI5dMvAV zXJkyGd^|LC;^F7#KSK9+T146E^RfQQw&xdHr1FXJMyn)C{c&^DHTt_Q5h1WIajbNl z$xmIXOE(_nE)3pw=T3A__iTtoA(7jpA3DowEJ^bEM-fDrryM4t9l#zfU{WZ@kI(zb~5U6)B>W0}0 zMA8mPseAfoK5g_Gy~iCmwog3Lo?s)jsF&}@NsUTaw-Iu)gGiR&zMYbsrthvaP7JZp zE*A1OGo97oF*!|STEmyEMIB@>@k)BHTM%79&+w+Uj9@c-AE^GrBf=FvHm#NK??DN& z#+vs3sP-(J7%_;&EOW)8w$s)rDdK1@zqrczao$qlVoSIZ6@YDO4I=U?(6fgCG zQ@dUC8};cT z4dE#0v*^lNpms%-Un*O83Hsz>4Zi)wox-PLJ2M;S`ig{WIy#)*UABj$?q6u?U@_+p zgtLR4#50-Y5lkXsm0gyRysX>C&LRkVNsn^EgL!wj)O3w|SklfpntH6Y# z9!`euXtj-2FoV;38vJS4J1jR~mx!X9AS)7E0Q-)aQ~f&WV6>NJ79kH-^;SRWTHPr_ zW*1!HX9_`yeA!Gb?Xk2K3NHfT*AYtoQyA%~k0ouJjTqgzHx?JoOe)P`pWZj9d+n>5 zPE+=zY9X0_%1BfKE@i6wOg#n#mBh83#z%FDKZ!1i=bGPj`W3&^&#PTSDW})1rPqv| z?@Lm6hZEPkoE_R@BFaAVdb83scunb6wQ=0H)PVk(pyLc~n8>|3gqXMQ4z9gfK)s3c zLdz;EBH;1+S{38>y6CprjJ_RO{D$JPwChano?}u3_nvxUj=|C!CdGdsP41I>*yo9$ zNz-8*QumW}BX7EqOCoV)mj7y?#w0X8iS_&)Q7FGKDGg!|t;4^soTiVkJ>X>#Tih z^LlKEGxut=^a;pPL_kY;$++(Q;d7X=#Ut6kDMl~#+Ut5b4|8Joi@5bU=Mu=G44*D! z?~jVY8pjelPGaEWmh^F7coA|UTPra zJS_a2RrfTQVrP=s>e@i~GrWaKdI!!YZYWWrpZzj8(BY_!W&=&AigV;f2)c$l9}bzC zSfF^_v99trKH+M@CK}EJGYI7pNP|PfE9~?#edXX}8SiC&iJ?QmV1l)l&!c-v^+o^f z8kkd*IY4d7a-G3R3&rNaSGoyaJ8=)>x+5N(G~Sn{w7A>wq$2zM z@Z_+oG;>ZgO%C2${PIGR4F$@b4b*sgTuwhe1_4?o2%K*bN&`jQdlqEipTn|>0<`-e zMCNH}20@sHvob)TbC9LnJd-kc=N_g4y0%e2lY@` z|ClYzNV?(i7kNUr`;xMcv>kf_XWu)1)f{FAD@mgU#$;+syQ(-&&{im{i-U1tgrm@& zzO1^DgXj1zAL94@<*m;?8;ALVWI>KohkiZ}YKsf}Ej8UI(#{q;M2Hbemb!2wwLJ%t z;6`vxAJDW)N`X$D;KSOghlyYXzInN6?W?TLSk6~tLEt}NIunL$$W_TpIm>-sF~ecI z9?X1%g<`zoP#Ams)*7XVi_Eh28d)DS?mq2BdG`!Pc`@4znz!*|UJZKa zd6nYud{*v12t9$c+?CMtQtlT7#7`HnE`Je#{vB-3<-W};!sh|tuh>I>0)Dyhb1rGV zh#r9+-}Cg_<>>LE#q%dW2a51Ti!YQOUw~KsQpkLH(dVi`K->;thmtn_iSy}KhJ%2z z5Er!K%1@MIzmz^F*#+LslH)&n&X zVoQn#H&Mc+ED=;xM`tQljAD6S6<~i)E}<`gFe^718VU5*xma@P9iyavo7()e zFGEBHzCS53JcCWiRi+ggLrj-RJrkle6tJ3$cNbC~I>oM9VM?6v(RI6uATZE_ggnn` zCU68KO=5?r0P`&B0jkj};iLf(@-$&HK8vL}LWGYhGH$mIqRZ{?*9cppdj#FKW6FFv z%!a=l8~wf<&T`*?cBL&_q*v{DP${gMa+;i58QdSvh#qae`U2rm|6TSm0H|Stg)}knN^S#t!|Mgkj=9XS8`X{dw zXEruiQ@2Le(9h~xvW){CFXbz^%$ueYgd=?5%%*|hg~DRSfTY{qTemq|7(9#LY>P=4 z%o91K%b_( zfA@U;1kZkcoBzda@W=D{_rW^Pk3YAo!hheC0X#52{8)b_eaf^NLPh=E)%6Rh7edAd0DJdnW^UPQmU>*2QQDn4+^D8 zGkrvi?u221pXzwnn0705K7Bi3vTfXoDVp_s@tS^teI$N6hFBiEkb3nMCx*f6`o+nw zQ(j);Wlpk1o$H2W1PxnMb;T z*Ksf-7T;ol*h0Um7*Sv-g=)$7e)v)3yee$H6q@`a#LwNz;UA-pIcaY?-td^dgIGV` zc2?|EUdd3Ph3;oA3xOa5yBmMYpj_cw)i6&j$n1mh~%-N_mPi9C-^ zA$qG&9%UP*S;o41{Xg&erd3<&R1a<|e_0Vj+X8jPSFbxI62c0A_864#g_$ zD_zx8>Ie@zBhMMU`=TAQH4hFJ2NBKez6)}|kfXwX>;4qjTHaC!YC9Q?3|X)q$9F<& zU=W*crp&~RvG!X`pU^50IT0DCGGIF^W71Gm&P-(3g9&1eV1QLPJ zE2{4iyO>!(k~!9L#}k|E#~5%$C}YEM=~y3CK8Ei|-*m~#D7enn2hahXzI#mZUMSZ` zF@Pv8)DCI-z82y;1QMjgh!~4Dv8n4$mKC6f&sB_*RF_r5Gj5*lKT}f*6E#hrlSscC ztuAk*SBM+>ee{5-CVzs8{F{X1{SW-Gg)ou>EIp_C*E74VV34|BvmC*lq_+!OJUa{j z7+=ZEhx6{Kuht2ME|vsZb+HU`k$8^Sr~B+{y&rD8bBy2Sp9|pKNEd-|MtY2}*e!XB zvf|M&;@ZKR&^bRtDvOsi4L83WzQuY=Z1&)j7ar4Dq4<1S=o0Hg>zsGX0+ePq1#mRQ zkhfr@6%glcr4>)ou?yeT93|m;x{YIftxc6A;yHJ5iY3L-)~%;0y3JpRiebcXZX|@k zPBV&Chxc-L`o6UFEV!lyN_v?IgG>E_(^Za_NVL%Ujl-OO$9riq`Ge_&;kG$cYb@ux z=(Yl$@nZVCEypk7KdPw*N=FM;-YYX`?R`(sh3s{0+OIipH~#DJODEo~hW^u!xF0KgQ;^tvpV23a*IKJzw;)Y(he^YNwp0lEe|F^X-wc z#$sLmDNUQ*S!#LIN65>=crPrwnf(((CfqT|P@HKTc}4E=7CcVD*cOKk@P_Q)P^Ane z*T$3`9>Wdlc`U1Ao1P%f+?7XRg^-k7jAWi#t&7h?wBx@3ujZ}!t`f%?$r;uh21%IX z?(39iWK2={C~U%2xCN9VHD=#GXlPp$6}^&r$j4k?!!KBPrzQXPer&Wvq^#D|yZp+o zY*uG8Zi(+)-$Ji3W}&veyS~$=a&k?Iciv!nqCuqV+q93MHRc?@LjF3-w}^(Q`cJvw z#4IJ;6g;s`85Qzx&Zdk9PE*Lo^lxWUSTj>zP2tnLXhGu)x+@DJm1Rkn8yM(Zr99rt zzWvzVfz6Q6U#e%1ZWWT8-JRWlhAf-C8@dIH8@hl?Wa3uGTyuj>S@1^K0?3>EjL`pi z`8_=wkEeY$z!Tx^aIjD{qryTjOlL4a1pARwOy1$Ur}?#;NiRdKOlX+IN_Q zP?RDlQTR{%9MIi}i~Id&H{uVDjNk3;{3{A)`xhcH=z`Eh=^TIe+#dn{ec_i-fc|9S z_z`~RkN@_sm-`PB|G(jP0HP6q`5r(h1_O~3@ah45R_9}_AntSe66grUcK_xm2Png@ z(8Bz&g#VFwKm>l?90>w*U33!xkUKzZ2>>Vq%r3l;e`KCNH}5iv@*g|I-4u zq;Lc67+1VTU?2Wj^*I_9Fol0r__D(a&2FG;7D$^wQ++vs08JWbj027~lrBS{O!pgx z1HV^p00HW%<-fDzoWQT22k3>oB7GT@`^wio-*QeaPF5ZOi~6ec<>&_Lx&f4HUUn!! z!ewA>=(;(1fb8H^-IqJgp$c>Gf>^;&Ivjy9?|&rjvzKVub64&coFW~}o5fwbLJ=kt5#?aZ6LnYk)(#w^-E>QYuH;`S)dI~ zv_X>c5G~pkSd}_tS8JM?jWr;F@36Z=`Ek|S%g7xu^))eHO3h^EOY@GZ=6iAcI=H8QdWX=Bs5;RuQ8i8q#^Q$2*pS7 zYf_Kr>Y2f7R*avh*N{xMxnk-sr?U4>w6XdxaF(oSxDLoOtgbJrSyw)sVeZmd^4Am zq~E98GLd? zL*nB+oy0UyW79VanbunOO=_DGPd`j$tOh)wXRJCEz_`n-@#)^DtXYUj!*MVM@#9bn5jfWrTsTvF3j_vP1UG+mpn&s^75nmKDw`s)%4XuB&VKr zyUz5Wl|MasV7od~>b)!Nc~H=dtLDHzIQ2;Ej_DWNJ2vnfjWgzyFK4>lqKeuI5;F=C z-55XJ*}g3kjh24DPs3UlBmoeSNO2b126`yEN$Dmy8UDun@Q-Ta%CIS)}vs<-lFX8kDo$$ zjzdf-o6pKDZOP`>+*H5CEm;T#z42nWVG<5$n-u+uMQ`mIELMan6#sD0J|bN^1wzyL z%)FpNW6s>rtq!5qry?iIUUaf@@gCoyG4Wcq1>0sHDD2Q*zVXaa+jg`yT?LO@wpno* zH4{g0Ew?WA^9C-OV8K$nvV*7oS!LH=zJ#hvBKPoVrDY~lUt*EP8QY=_c$~o!- z4q17|P?LUhJR6yv<#6z-KQw3C?rmPKCwZ>6yx_dm(X>;@`&g}h z!4d6&uVp*tiXcMM*pg_sDw__>f}?77{f!|HB$hd!A=QEJSOT}ny`pvyfz2&a3g@XV6=$b2eJScD5%dO1O1!P#`)n5(`)tD%e-^~Z7iuZgvrWd(YAKmJnRpw0 zZH3nU6xkKV6$MSm`#ZcVSDWG7*Ff1YPwkZ9ElTkZWLXD8S(po_WeG|F+9|hJPJ6T5 z6V|k8ABJ%b${;Jx-fS5+rnM zpr%>keFE@ty1dAU_wjWR+h)9VjpsE_)9SquD()VD6400c&)Q$)>qFcfum+eGoho{P~tQ9_v&DtBbSEsL~ z0;ME<(96X#zg1sP<_M=dPMlRMh)fXM$e+bK(H>yJx&CcxVlgFbiRNgdT48`&!OFWz z&buD%9u1uP(l8P7BUyR%=H6Kh5jC_ynQMC9PwYlqcpfF>Mw zF)#{g!L`>3%!o^TU?{)UtK)RqnmDy)0^bve{GY%@dXFYsksBfqE=Rc`DUV72+|;lANH z&D{QI9YHsVb4RQ06zPL_##+uT19WaIZ$ z9g|rSq*VBkBX!==A?g$h6qYMgrt(1k)GHPhz)k8rLb!dWBaht^KKWL^sPWL=5aDY( zw`~~dm5$k1z2nY`&+jV*Q>sRh$vY0$Nhi-dN)o?rtGLaGz~A~Z!<`$X!y{)OuG#Xq zK{LJM;mURRdtB*zWR1*{<*4>+^jf_vy~^~E`?$AoDzBj?(~ge+yxAwO0mp-1Z%9?s9v`X9t4|7o=TLlgwL91mRB@vkW8@00$Z zACX$mSzmzQ8*n)PCH)Us{|ivqAHyK%(!lr)6jo=@m6|&=X#gIIl>=HFbQxI}s^t(K zPF7AR#HqkQ(Ivkcs%~y}sK~mYAAy#Bxof~|94iP4$P>W0^gFu25P+`Gubr-Nqs@0@c^;Cu4`zlf{r z{_#5f)y?#4>EE%O6R1a?Gml->{r7k3AGabW&=vy?#0_Zl`HfuzZY3Zg22J0VmN?e@s)M|1j+WRJ?8-0VmN>`UX}ix+kxYJloMzix+;CS znFy-o=UGl@d95o+7O2v|to3;V`xV_6kMN(j!+)74`9-z%$Jx)HK=giZ66mMl|36bB zAi(P1O^p;Nb;-2=y)etnOOK^n`^KLeP}}I5q$?<-^HRVdjo9BG$ppVxSvE}JU)L}-7SQ&AWNC}Qlh{NbQ5?)dwl<>!y0+frR zNc`PgC1Q4?viBlO52M8t-$MpG6bA64k47D*_t{MHgOX+42Yjg*>!v1D6XBX#jf5Do z18wQqOjdZ>!J_(hV{Ugp3~M??V@JgE9DWT@i#=L)n#sboADN>T4h*^mbEE48tRc;f zVDB9!XO~b4JFbqVCqu<%5zKSFj~D7l?lmotbJC*RSE`bEZqGK-!tm-r_+Hc8(c}Jz z^j5F9zL^{8JY<6IpASz4vRfPl-bZF~8|%my8YuPkSfp?@&}==Uyg{CCp(4wPl`EY} zT(lnPDWb2x=264athzQxK=(#S^_1%_@06u^JpORmJ(iFT9dDys+a3&+hMfDM3F1 zUHq57h<|s7{nl9r|Kw!+)v~|^q&F}A{Bz4ffx5;?dpDed819ripEVi%0Sg zc8$kXV=T#;kPp6%D>R4w8Q;;qfWyolUv}wxsUs7lQC+$MO9;F5yz%1KB1{UvrnD zQe8lS3wCbe=D|n(XJ2Q>u&)J)^NTK=l_erwrzyrhUcKH3XH~JEei!zAjpw!&>Rw9z z*8|7CMq_>f7)#qnSw#u5fH;z%I9Z29r0lh8 z-&08;1aY0ZJ;cz=9JWRX(G>|WqhP_I#y)tPM~-iTH|c6GxQ3y*rY5x}J0ly|7VE$d zG1eSHi5TA?SzI=9IarQ{zb!`Lm)U86QX(sc6H3M4q_!m#q>Er?9m&HeV=W(9E8OPK z=$-4wt#;d{k#t!N?YcBWq;k$UZX{Nttr>r_hR}p6Jr%^|5TQ~wa{STiYGq(fn`U9A zC~iqwh@e#8=tT6|n==Mk)`k~N4=XYGTOTbOq9uta>K(eX!KA*u=Gie@kTx8d@pd}J zlq7g>GdtI9>PQ_TaYJ`*YZPsx7Q(mlo?CC#RbgyWSmPS3AiJQx4XEn?^GP0dZ8&Rl z&Lgtgq4DI6{ew9<@ zl9;#mN=74Cfb|+)%ON}}2iA=oMekKn7_T6Y%itfw6}$BwkKzp%8jit~0B zrkb<=)`Z8)IiaL*%o%UdH>$%gdJq=+q|{!&tlUjg6^>OS&J9 zTwZIU)vn+=mQ+|su{t}8WwyzzDeD$cg?9LDEhe~Zi7{b6P|SB!epl~B+o6zUVp8sx z)4Hlxr)G}B2V>w9q8yP^T_MP3@IBIMPgj4*-|wxZyWWZ_0eAF{!yQA$tpN0+&o#!T zT#oiinKqzpBLBVOe0Plusx$=9Oo%CHSn8Nn3}}1*5O<^4t9^xlNsXjT7?IHAkMdvU8(UQ9P11$e(N?zV!2|Nwlt#qM2IOQ~)Gx-V5COr!aLmRHp$tG5e>_ zQ*M)^eCxkEu<9@7C6JLSZ_3aL@f3lNcFqvEKSx}r=e$dGdeS=J*O*<5jlxp^lhpLu z`E9(qi}{-hFBN|C??WGah`&cNu*f;%Bs9b7ByJyV^cnj!J7;b?v&pEd)uPtk!<}!1 zeX{xORXqNe_NUSoeq)a_-?VwFSJ&FK*nTaUx_?|zzZNfs9Ht*-(~hT=fq4UY$Gb^| zcbnL;*T0+AX>PDvhBWw<6+G#KJH>8ck8z|h1k&!oLt1@X-&}u&#HN)#MPOSwXV7;m zW=Q*He6onWcy9c?<^5>yy#p+rvTO0+$f3FZ=r^D^xM#T^w22OnRGx{5yuF2|T>wcW z4Dv@EqSi9-MnFu*_jB#A4(>s(E!N5?Ttf_1(~?9dP9N z^`OmVQiI^7#w!0=UuVZsd*!KJ5CY=IZQ1wF4?-U1&7?GT?(d^S_Zo!5;K%ad@YH@I z$h3JB$?ge$oYUbG;7eSA^lVD(k*&G2LG#04PigR*$Yo!C!4^4gB7P4~p_&h}g+d!g zpS+IvGfzKQA{NcK)<8f;X6=4hRt218s{OTtE~9c#s@CK(_@41;=?e12-5d$I%aM0^Cr#7{EZ?^`|KD zkDdFMr}6h0C@>H)|DE(7u@=`ahD134^rC;31_Kc)G*m2(%UsQuEdN6{h!;R;0;-&s zqXvM6`8RX}Q@KDs<7%7-z8qUa*L`j|6m%$#ABSVlGf+^aIRO|m2$c914B+tm^R96M zO|R$uI9JzwDZYiS`yAr@YLLkB;|#(t4L?7WP>_beK$hX3?dAaULd9nSU+(yTYWJ_C zK|i9H{g)o`|NZa;_$M@}zno|YkO}=wC%QrnsHOi29nmKW-l6ibx3#`WyCC<8=9#<6 zNY^0FEgPx`RC1SZC!27Y44Q?>@%yFf>#%6LI~)4fpN+nJy#HD9)6@ri`F@>lXByF! zrx7pP`XnSsCncUoGGO}KziczzcM5+(^==^;dl){nWaLgXYljqk>aM8ELc57Amq%9b4`|E9ONQPAncK5iuw(FdiNYtAAa`2(QiGpMz}~L9wL5TY zO|1Ca=8<1E472PRB@SQS4%q(MzIrdxTR-NTbsmC^qH;(N_l%1cG zoMHCsv{RGvG2@;XQ7Pv<^@X4$N7i}2;kqLRXN5|NiiApZ>?q)Kzn+ed9#vE7Baid* zXXuWDZ*)=KQQfq@LkVd%3rSxhGy_I0Mf$A7iTTXUoqM7f%9(bM6zl3;YAtrZK@3ve z35joHPT|!_eKY**;rOfp>omvV41tYtucp$d*P-yeclb=dTXp}TNi@U|A#nHsQkm5% zW{lh6r#xdz|4y+@#@z5Rl(#pF4I{EbI4fRlC?QtY znlbuF(AQ_FRL_o6cbE%4UqerG2w`9mKNZioA6Z9vhA>1(mEdE+;>)NvNYt!-w-c5K zOH6;fM3np)Bzx2MRs%+*n##mxZQ!!bTheX13fQ{$7taRwv%v4s5gf za2?dG@u}j|)Ts=FQyu-YLuNq6stG&m|M`}G^OWnDkwrV?^J(Dn;S1xk5V!JfI2d7->(ey>)T$aY%EzTm zDf6yqZT|A*-iBc-AvX!o#y3lA5v6&e9)B8d_rjnv9;4q}#>DegXZ(W(M4J7?i zpx2o{g_<0;zKgQX$?aaW62-bPT&FKEo(qrz;*Xh_BCoH2vI?nv;il?7_?{=MGwYykOE=z|t za;72_47`jL{eabe%G;T|EV?`s$12|L3vm6t@~MwTuuAo*vWJH|{$lRM<42s7-g9V$ zIN>>z+KM6f5s}^oE2(uRYCwM3;dKm(>S+N3aA@36xP-u0oP20|4hBvO1j=k0$4~RKzgjmK1Qc_iltef#<8nf` zoc%mJf%3(G|KmUJ+Iikw#X?J@)%RLeo^!1spIl)&-Rz}&BN z1H`;g(WSwc;gX>0<^Tdp5b#^RdRl(x_sszS=kh=UQU#)lf8KMTa0fIBJ7s~I`X$|#hV273 zxK!7h?O97e;N(Of;(MihkC7FChQ{7Ej9#>Kw-e;p>U-*W@Sf*UvBmU7A8h!OzFHJU zIaIi*0Yq1_uO3Y0c2Q#G9JJak!&Qjryw4jFFS3Cg+ z&s{4W!iL9$yqg=yx!1d^aO0sDNf^3I^|s4Xm&bj`pLOLz`R=W~8FkPSmtUyyvyF&J zyVt(Sp3bW#v0<9P8F};jbzAhrck$inDKkVW z_pBlCl-(Sab}Qjf8U6$Z!A5V;D>{;sfAr9`IsKE)r%x*QiQMv0c%4HnX@_qIM1A&P zB2k;PI@vR33<*r5;=iER;UL`VE8M`cC~>=~4ragbb1 zu+-X4K9}aYwTi<%8NOTawrX_vczN1y!rmwUwhEQLoDu6X`qny(d)dP*28= z&@7z}(Gt38Qm$2@+~e9$#E`&*E*8C)0O#rh(-;CXRd+`>dcZSdepf!@ZXRkzoLWsH zj<`_buHHkj(lTSN&Tn$hC&dQ5@93bL;yX9ct=RaI(XZIZ^b}LGKq(MNs8|fA#B&AD00YN~zmG18DMmnYAyPpU4e%*V!&+k3oIoJ2s$8|l!+*502 z&6+i{W@fD!jJA6&e)5)iw+VhF%TZEj3NhE0wi8DCBWlp*7gsuVtk`kRodloblllzv zIo+X}I){F|uT*uOa@vch{8Qgh*LCBYg@y1b2ldbhjL$_LqecI~dzTu;KK$X+3iHYH zpbmNsuh6J?Pf`>X{~TKbYMWUR zUzJW&IsZ=|iArqO1LkgTNcC$xY)v7tXfe_{&e z$4(AxB?~2q7-__2vt%|M&>tvj{U~H))0|~LZI@gE*m)UW>=1|a&7tj2lmL`u@FjqQfi4RWv4`vdt%e^09zS$F7z-r|?>W5jz zO1geXRd@qS>&4*m8(HfwV$1JkE${^US6Pb%d=~NFUPAbdto3*MLTuoA{3&bwua5?p z+5f)w{%h{L?fHL`wU_}};IHeU-{s~2>0SNidMVrAZ5#cq=6A4x4OIqq;60LmtmOV7 z@B9`vaLtklcp<531~y<8lz{~x zj=$HO?eEr&ev36$W&rkYuKcn6L)Q8o)WH41tc~6HaDQ0$o89eTiO00sr@!Lpq$A5n@f9af4BPbd)UCG zT)_6(Z)*N`$^5sl0r~cKmvVs%v;PIHu>cQ8Z~&Ko|B1E#hSr#Yha)(DCu0Jtmj5%I zGjjpgYJn^A|AhVD@D{+bE1-<}n^6K*jsN37_TT!O8IW(eej}N){X;_i9nP77%gFz< zd&UMHEgDtkZae~;CY|I(W3th(+jke3obByNe=5o9Y9!N{T&%Q;M!Xj zlR%_woQGftDUB|&ti^;Mr^WfflKlfRk9h`FO~$X%3V4HFPjJ&A<3%9~*(e9SFisT% zSJzLL$+?onEn+`x&62*>w0ann86}~^0*9gXin_qLTih=$9y$%45Wav%usS0T?KK_KxT*g+WsL&6!`Fr?=0$FP56^eavGP+?GhcummN*mi=H`nvE;!qWw zWR?J>S2@uoeJ7)*%7gJrroKZ`uTdVaag{lBEe<#}OreCQOgdkBVZO+_xT-#G5s$ycYe{xEJ{#Z)bpNm#mq|;gw)BHiBNep75B8d`> zp)|YU=^R|<(%3iZ8JPm0yK*dN~%#)MUK zmU_O&&XJ!%RD*W5ETLNWZA|qiqVX{)z~=j=&zAgQn-16g)siBG$0xM97YI7kP3x02 z#;H_!+d(tW;ppuNJgQeF)iT}MpJ`&&8TV+{ql}W_gl1fX+Led>T&z_Zlo+hqm0+0k zo_n0^bbuAE1x4|jwHa6y{f{C2`?VRESpT{<``QCVkQ1Raqr6c)xCqo4mw04zH{$FI05KfKzo6=?uY>!I6!>>@d4xq#BG2! zfz1YHpz8r+%*1yoSpof25S9Q@o|p?Tjl>2V{sQ*}iGer%0J^wKb6+yJgnK`58xqI` z-0ow&hjI@W3>~m+1OU9N2-xKSPDWY(f{b4g^J}y2kpwQ74X6TOFZ&liNa_cgdxuVN z_+8%naNubrfPn)LfhGcb6KwZ+e@)L0P6M2R18LX*Y6ZEhe?qy7y+a$=|4T3b$&A@S zFMSdN#yCM30J|W3f(8`G1$4uJO0Y74V}XGL5Z7ORV3Gy|E1+^f45(KC8V2V9eRG4k z05C#h?*}Wm=Jx{| z?B@i`Spzx12){2MG^l~!J+A_T2XO;1z28+8)X2a4{_}lT7)a+9=nZhecm7{`4;*@z z<31G3^zK6Ly8@gBjLthBI0Y-1*8*BhK-u>l@=NSp1K7bS@7()Z{K|^{&@Trj7U2Cz z0Fz+%o)LqYKJfY)sCeM!0MGzHvHI^nE`U=3F<^wSgW2UB*XIIP3zV7}u*?RaoEccY z04eXn|0oqeC72xVAc9ig`F>5s1}HSL5Z}3=6u-u?f(Oc7X@9TT|LXf5{(aj3iodHZ zU_l<}f3SNOa@RU8&?Vvf*^CQdOTf4RBbpO*?HL$Qf6R)&&LAj1xGccL7SP&1rbBQ~ z-A$a}VaEkZ2;58uisAz9ssob|81Y=7!3QSbJHYo-=Y1`}_~QiQ>#qKHxcg7*e{B`; zVDEjQcYSjQ07M9&iQ|vnybHb02M*-`E(IGWsO`W81IPvU z(66y~G;o&^?EZ(#{b7^-A2+$?~!a&m%2Pg2N127DMsTv3ZC*T6_y8(9pL8t-yxqv5onZez`2~5|( zI0bfrK`$wSkPHl6pnS0R&gB3uSp0!05S+VK+_n1G7O?|D9zcd5(E;cu@PB|E1J*Bp z>0eOjeV)5eVEw>(A9B|#;Cy$Z1XL0@9uQH18UXeifcD)l=l+blqlCM3_wHYK-XGg* znk;~c3y@+zu%H5bY+PW}{U5lXQvUdH0<#a$5kR%s?%lf(PT=GMd>(V(ZNLN1pe_Oo z1ORv9fc<$;pMW|R#B;%`20(QLloN;rcr4KUcS}+r{;s^cocCn|>Ik5P)*mDRDh2cd z7VaEi59kAY0qvIt|EKAHRQ(PSpkhDSpm)mARX-gPuv{^-=zb)zp#rxB~TF7Scy4+MK9n2v3%|>C9}b=n?m{?$^(tsh1FGS#>Dj<(Kmq}XyWh>&Apd@r6tHAbNn zl!9}A1cgM#$|xu+q@3)J)6mn?*3r|0C@+;`4O0ShqlO}%gW%v)Y+tl~jV029V~Xq+ z{|?V@?j0h^35154CIk|mkAHN$e@J{HPD58u&yh~LA5hrLL~j@J#|HTKjzw_a8kB;$ zx!ia(HPn6Qmak493tCA-=`JoVrr!?Z6YIk{RIspDz)@rS(YfFre+qp z9|PeiLmPifJ%ZmOwASGwnhT(OJ@gE4E~#wTaxbEKta^A zJZ=a~@wocgYoqHxGTKXlurN6}f^Gb;9lrc+dWbdE3PGQ!%x7dBP@bT+=my zD}$?UxQ$G!ie()*uH8$O^(H6?tM&U{d+Hro9b21tPGpo&&BJ0gp~+nhY1DGNR1>mr z8>s;y1c72~Y|QZ78e#we;+U!2@Pf?eTQ=FgJViIr(kZS-Edc@kgS9;)2+#bUH+wq! za|~_Pf)E{(7(ceIZCYq3?ll?2|lUw+3ny&<~ty6ICTgy35{JurB{ zbbD}q*}34^)Puim#drJZ*0n_zmqni^7tO&t_Nr1*d883)p|_zCL05NG7q+O#wgjqb zj>zM7ynmkH%;u-JbZl7uP1mjtq0x3P0mQT0r%Sc&xAZMLg`FR7EUZi+Zt;W$7d=zo zKx}%q>7*t4O&(vPcHgd3oDHws&Tro?uHHIc-P(vp6;xDsZ|2;JoZSxMO>0cL-L$%- znWzn1T2ph?*aThQel~w_TRM=AQek|nMg_&vg;r1hnHq?%vF)T5J8t-X!-; zhF5>j;MnM@&c$igHLYXZY0J%^eGRSlT;Y4~kq;1*0|J|;1H>{W3-!&lYD*W4XQ|#Qf{NKZe>$*@=A{`^RL!t_xa;)TfOTbeFRZIKD`>M@q4OMWQrkE0uAW3r@sn~1!#XZ{reRSL_4aeT?_D4$iQ#@;Fw@ah zjeWXXt4LVx`I$E3(~&#PW$Xug`2Nqs$b+~F7il5JPwSHn`xc{w{IG*`%?26yUKrb0 zn+%jv%}E+AZ!CDqXG|j2IC5$j5U$mXb&YCh^Bhp`JJ`J=wi%Gf{!$}`THm!q=YoYL zZUs+gXy^HkKnrD8E+Kljh3rVF%@Kt`@6j11@%$U1!NeWwi{44qVF%&If}$|3Q*o2yZ5I*96OMeWO|&E?-`lj)76;xUq`hARnU5$vul` z{RoOpDe)jC<|@$eb&=ztkr>7H26Opd9a^pk!=U5&oSUc3JPy(x_E(bpW)DOmr;Dwc zT6n@4uC8Ty$}Y#icUUHjFa&mSB5prb5;)a`qQ3;}JX_?ACLU9(Xn`%r({;m9#aCD< zEs@<7njCq!#x2W>CHxRRUn*9Dbw^3DDTkkAB{9C|q*U<}M(pcjr4!bV=9vy`zKycb z21yz9i!0clUbL-i?;g>;3M88of9NspaUiPA_q|MB*01d+Yu@F}(e~4#pB3ZVeh9B8 z+=*Si1ZdFmkKfxnyBZK8IT%eaP<7MC`WzqNZ$G!F41SvQ9tkSmoJyr6zO(Diqr-Ks z1y?EsgTv--IBjlkqm6DClTMo}XS9-PcKHnt=wzkPU@t0)2T80d&x;OA90HVz##kMv z_dlu;a8`fTib@moRGVNsm%+%!_UeVki9COFwG2nN%z@qfGeWsNYANiQ;!09J3~G}# z$77L?l;Q}&M1>_Nvs!sJ9vZ=;LDKf*vNI7bhVey8Unqu1yR~+XgnbQ-G+Yz8J`NX( z?0S?bxi41W!xO+qMM2J~LNn9=fm$hs^L!KyLPcZg&*7{K|8H5XN(@LD-HP=J9r<&oiYw zwr13;#Wkdf>d;D>;98cD^68-N(0AGI9Y1y=Ya%90!qYd*l5UL@bgjM@h{rY+`17a~z2+%2vKxD>w&7UQ z*i5#4Zba*e!2WTVIkGaTpPvhAWaW6$cW$eL?L;{j;T_~DhQc5632`Av$Bxuo2S0!C zTS$t&KjjpA>Y>K-Sv={B9=i8jRN)Lm>uCL_S+u%S{Y!OaN%q7Z4Q!9jq!L7eL80?E z;XLO&vy=^AVAVX9V{?ojkxmBSdQy{6j!|Na7Ng-9I$Ul@maQ`*JG&RW)VU~~FGdMi zwCa=;o~6ayeiHE1h$@(fopOVv=IgXC5=*enCPc(=&E?HX*6DK;6Kc2Cs%{t3Bw<_J z8NOIVkqCo@#&$;K$7YDi>{^bdy{0-s-|*yLT=a?F@Z)zPipk*{mcJ?6iKQkG&F*f$ zQc+m$Tw+!zKh8g_@6F$cT9OZ(_I3*OnNKxDHHva&a-P?S5{a{_+C*Tyv?gGP?1gJY zP3&xu8E6`W`pSFq@Z@p^`@0}vZ;?8MEfxX?nl?{Gb*z7#v0f;$pvGIjsW*7VRfgEN z!VjX*stLB;?8q%HrEyr~Wp|h$TT~8U)7*0__7?d#IeY_E6Rl=tvcKpiU=yk+P*L_4 z%nC#Me^MGn@PoK0L+Uk-mo4mDS?7DKM1HGE{&WeaWyZ@(X*%jAlZp1AT=e^Wss+bkcg9fKT>9VN7S|Ng_^;ft}; zS0kUXd^zXIkm?S?&v0W7MHjEq6nu|{Vjrw(Q^})ZQP4V_JjkHC2j!~4HhZsa03anM1BtMc2ePm!T{lt6mu8z8EA+HMKph(1}yv|ckr>gWa6tZYN ziv+Fz*&GuywtAPZ>vBEz@W+aY?;0NJ*?pXf`f~3qy*k^q4_Ndr8*2QR?3;b^3N%({ zRS}$Rs68KJoj;W=BnZ-@OQyHs z$%iQ}+Q!~+lKM#hQAnm{>#zP#Y&Qh_Kl(9n)2JRyq(?(b>btc~?_+9yv<+7Hw(fbX zJY1Oz!_D6cH?Dp}cs=8a$?u2Rhmxrph{++}#d73D=c~o<{1>7HyJ?oId zKNSd$u)H38UyW78C(IL z*s6nN5hcMgbx1r(UWq#ALIdk3lxMLi-YnuAvoR}slySp(Iy7^;jdR$lGmr48uq6+& zKw3SH=V~@ipD*8$tlR4I_5=O2Zp35`m0iq&3k!WA+PAhp_5;j`7nCGyt;DmI92h>? zTEtRZ=w&Hootq47tvsO1#4NDiiFE}uU(ldErHF*(H#SLLjrWZj zQ`wx9h1lxVI}&!Xl5l)s{g_WT&zf~78?9i@(50#BQ{9VDOw+gCOmE*6a^n`KTI$5^ z2hP597CYfg3Z6#mu|Z?L=<|C?7o^Rqgn%Li6OFB#%6p^}XDTW|#_)66Kc1eSNKCE+ zaq=;Nl2&xv9(Tq)Fj9)F4{VAgQnkhHACh-#RV zo@<;>*VTy1Ks>fq$aRU^HJtyB207)%a9n7h=2mS9q{oi#K}U(JXz ze=y(j#7%n=gCDUi_s&-41p;1)c&C?GbD*Tl*N&Bz^d6RnKIHvG`*{%}lJBq;rfz+p z5#A=;pb?!6x=4jlT#rLDAs5Zlzgq}iIqVEZKK;SfQrgEC&Y#2If%<&Agt*a0vs|F@ zOIYecYZ6_MwONr?A0@7oKh(NRTaoOGoSz+~qCaBa@$_;_Q%Iv|IGE<^)?N-KO)Krh zp~9e$UD}c6?}vsAAl8g}p1mbgPm!9hsAJV)LoJci=+9!f^~2NNU~>3eGhuCU$feCZ zh{!2Qx2Dzv*DooKTDjzsG! zN>30H`DdlhnW=WDj{G~W^m3KQVF{{)-k9#q``9YBHu|4h#H~*mWYR;FI^n`Eu={FR zP-54~t8j>Ha(6!O+nK!xpV}AN?H~&d#!d0FJoH>7|91Lf6Y9A6vr6Pedk6V&cz>Bf zUXzC^9~Fbv^@;KTUAHCA%mllh@!{)+;_!jhvX^bF)rG;)SKlX@^c&I!)*Mm==-XI7 zJY`V0%tAXS?V(_~2_G+^X=dq5L!o>G;fzXyMoQOwiq|{fZ^#JuA#GfTIz1f0Z9kt3 zwGr#w-z0%$Rg&m=%;4kpP{rUW0(K@_IZ}O-oX@4NYTgdL`YA>Jkc;c_k>lI`^5;xD z8Lefugj*P7T^W6889Z!`kJ)m`ZeIG+pEI0O3>JGCCn>%NN&2PcT<5o$hb*es#!wg9w~6L@Cd7`+CHX54taRR@j2|f; zAEqnt3zugkJu-@p?U!7E>VT6)Jwcg%d;7*mMreV=APK46$aJWVP{0I!Gi*?k_${lxBx1?rk&+{)DHZ!HjZ(YkhCjmM9qs1z!G~ZS9pVT7g2)3Kuyw z(s^VqHMaXH=2`H1(FMymqu0CGke%`8*^Do}^c|~Fop@a8VNiT{Lyco1f-ZY}ZTvm( zunCI8!qC5~rL~dRLvJ{;V80_zQ;j}s94>v@7@g^6`;sYtdLyTyubBNy+h~_eqC)sE ze0rDSs8^^)+14JLqkvdu%2zp|K@EG>0KF&_j8TNv`r=Ekk6U;I-)>Uf^e8!aZd3M7 z-m2$T*3vK%*VoI(Yh^M#ICYoWX=S4skV@Bh1d}eJQism4&n{@KkkDizrL`sTa;1ko zx7Bj*TuY5c zQzX^#h|t1Vo!E$l3pIY}jKV)&XC`~M03Ke5_ngqRl^~V3pOLCu+vQVskuJnC4DJsE zv@jD~JMmA&u0^h?6+P0goklgshC&ja?yRjTkgGe}>!XXPFhZ)&DyZRR=gZkNkhRet zKBP-t4WHU*tAsN8D#v!PSO<-2ifcWQIQ(itwCg-(x0VY7>P91QPT{CivflN`2J$(M z03NfEdv{l>l%v|z`brBzK$hJ1-SC{#v)AQza7(s0tf*3ypCghYCo+qh;TnXc4GnC* zk;GQ-K8fm-2r^LFNRnl*=n5Jct!&6CHI>9orC8xl%zrWF7#CUjjAGMJUK=W6v!&l z@lSMW^avx{m`G}!b2VBiSozRIyKMl|WJrpH`i#Wf_CEI!1_ejB3D$F$oC?)o-!;Y9 zLiNrGsLlz=EU|XIcib4)A8(efTKD9k-tm)GImqLo>Q!M^03DJ#P65PWu&LoGhoi0@N&KiURgk3#AVa@}@xWK}DA_Y4NfR zkmf!W+o?Az56P&cRm!AjVw`cPI+FVse5CpXZMg#ynLZd&%2Pde1^W8Z#8?c=H9VQ3 z=pe(zHEO=#F*5VQha=1Y>xf7DhnFZYXt8qF)m|)Yj`o?BQ)G2XHKciGkvWI-&&G2 zT_fUP-a;UhKQQ7GBONAr$`3ht-elI?@enIDdn=%D?364g7wO>@ z7O#&^M(^vQKG`rMZLWDb-EXRV@0`X~4}TOdeIsDv9?6XCSS?YoJ^u0ttIO`RQ10^4 z>wW&KrR7`WF4QKi!2S;ms%gP`#DniIoHVmmF4*gK?V!qZ#q-MgmmdJPsYLSpgF zj#073J366DJEkZem}nK7TYZ|ZuoCLbNV<7xoN7UfUqWqHt`x|TN7X~6bP8`ypC4y# zVc+|GkWEgV2r>u?lThZMo_u_oBhj*23r)G!%`a`g%Viu#;lT*L&bskqi-y-q%d`$- z^ufe1uF|`d?GRt``V7`Gg=$=p)OV9lI>@^{sCzqo$n+v5xT_pULK3X0TV1jTmeHx5 zig2x!ljhWa`Z8DXD-}IIE?-gx9$iMLUSytof_G9gpO9x>q~jTXHgQ&8fR8$UM3fCN z!p1KYD$&Nn^(temHZj@`K18%>byp{mOOMbG@6lX^MendVO)DDh6$E|%aGv%{>?T~? zk#(j(QDuBq$%hvGv+kpWLsIAD4PKm_vbG%W-v{eVGC95M3@Q$yE%8fc{i0UX?=JJk zF{1#jP%roUt2oZ5B1ZzjT1?Y*>WbHmm83uABsX z9NfZJs6CIK3XIpR(35{+!1u;E`O*LAiM3~#w6ZP!`gll~aq1%)uLmgmLO*heblQjf zW4>&zPR(c@%b|*>SDEt2DS!*3ANItt$?Td{a+jMf#i!ApEU+KxDN+w^e$=CG>N z*gYMTdoINMTscRk8OhaDWol(eJy%f+xB4*DH`mDSE%!puM4RCXgSgr zm2G;c;{(L!Z=n>J1nC-|%yHnvZ5hO+xROGuq%HC+tmSbNYc@NoiGnZ**-^f(phaQjL03d&ZTfpyPg)NY1IAf*>zI&0jxH`)@#rAFW+)8QW%G!9>@(I|8MC5lh<#tg-7&iZ`lT{VZE2AQkKk+2_r%PZTe-ayWWXY1-wOZz) z;5KJ2J)4zRHV)eSL_F5O`x4VxJ;Rq0Gd_d(YK`Efb=IH7?0W=2#5@#l4;aJin zUay~(tJ#i11UvEhNG-e;-Myxq?P(e8j>4*k6za$aTV{fsA1&D8lqy!ToLQex{ zTO#>Hijx;btj{Fh85Fn zb77javKrnd%+A<0!;CkX)qefND~dAlBKmDGBzu&ZryL6;3KovUvvC+~ev+&Ayetoc zao6El;%g_iyI%%eF#OCEUi+*$>KO^sf39aBQ)HJt#6FbRSMia95SH|-j!co|)hHq6 zN=!G~p`&-g<3amsqcYec8h=QtI3xjt;iq)yXlUx01)uACVf|r`io;sTUaBde&{{lP zMbh!^`s&G?6XXS`m2?+kjXhuI$SORf{R~xRRRz0IGkf}buM#)h#6S9~9I|xIce9 z%ksdm$l5j$#<-7VkuZx=d39T$Zp&pjG6XwCMLKf`jR;Ch6sl+pQOq71>RY0BjUj>1 zhGi4$xf9p;LZs-6C&~J2lj@2lVLRn0PHowVg3RgHl;JK^yG|&%y5%)kRTu>f zFre2^kSVO-m?2%58A=6ghXqTLeso_z1>-($qn5Ny=F+r!D<9ez$70tm*6%o(b`^{e zlLK495HmI>i?UH9;bhz>Grs~oOE?@7s~=rNxWuXIkf3&~iR8@bKVbM#;KY#0CweoP zbyh44n;FeT3-9oecVXJKboI!YE!^2|#%O?Gv)E(#!^izGx+}0T*&;8D40@|HV<93O zW)>Z4Mq|iN%hNu(7ctt(__QnUR%!;7z4$RwE)yb>Y_%n!F4DL?#2PB)UP!`d?Orgb znAR|ow7S%mNze?j!%1!2_}YG=Yz57meyrMd)^Dl_>b4fj(J|16NRK=>NsPrp`{Gs7 zs_m$D!WOG_<`zb~CQ(;r7)RsJw5R>js4;nZ;&9)%sG@~6>Yj8u%rHlF zIOAx-pvx1x`MnPn>3j#%A5!y7?Cd)OrAE_=D+vRH#ckYAg145CLjoHEEG+MxdxRi4EL-y-6|?rYVOIIDcsJ<*LqBq;zs&I&2e>z+gF@SeODp- zM0w?QWa>Qt^&x^OSw;WwJnHK+WO^A6I|W9so)=p4=rM(ETd?Kzht2C)`lS)^0XUqv z0vT$@MjEhhE@*@UUpGnBShy$YJ&SBfw}jK$xiO$uL^1A!JhK`5`02qS5(&zVTZY1R ztRk%U(t?v>7E{lRF17OkL#xp)hk{l-gjv{tJKlH4utfBAe2Wf}U|~1pHz_Zs#XEe( z$*5FzVLde7KvwO+o_}fn;O9?dE7<)~a;OL~Zr+wd17m9Ya}Rs$XYyKGq1+FU^O|2_ z6C^QXw6RSc^>m3<+PrabI_sOBynEy_S5?B5v4=W#!G8EA$#jL60COvP^W1h^F?iE6g8;IaL5+URq2ACS(_qoW7}2+ z2#V3K@wjQa7ha?l5KcMKIUJ@7{-~Y&hUjK{g}HXdiWAIxOyD8%8i6}s-j<|iNr7+- z-4i$dxq3;v2-DjTWIVA%x_HN~E)F)`a;r+WG1vMpEuXz^%BEkbx))8oLAK;Mep5t) zlb^ZY=sfa}ztV#8_zfJ~cWDH5xsxHRR=<-Tv&aHNPE}VrBLi!6^e}r!($5tMc+NLx zpC{-Di0L+JPkW>L_KUAj`lcXkM+?i!AEEcnc5$bmjw)xjzc6!4;^sAAt$W63Iq~JJ z$$TeeH7DTa0aQ=bi{!J?W5PGf+sn$1!`qpGf{OVTLfh-o@5N-ImBnBJt!utCv0Bh! zU@uH%zo@$`xJX)S?x3Q6XA{qtCZXx&buJm$H;wEAj{)Jn;8pvx?)8>S-2)nKZ3Zgh zk~PGNR~4Jx%E57|cJ;Eu?t(6K)uFh%Hs04IW^fvt9wM@mXkJ7uqMFrd_*?i)HV0(V zOQj_ufz-~Baqv1OJDGE$uu8I@Eam5Cxta|vcgM0qi-D);$)CW`TG4ODmJfQ`3c08z zoqu#KM;cLU_`)56`@+dz0-b^Jqj>It#se}{O|HeyI>XS(F(28eo<6_4j~cIxJsB zQP=qGoC%byj{8(8his0l1n}oCQ@qKizUWdlOQOnQpkOT6;M-|gIqeDRX~P{^=-}y< z^=Uu<$^EvWnT6oZWjluDds_5KL$T+gFc+IB`+)?Qek}1Zoh3A4-inKlJ}0Akz!ybp z1rE~ZUu`tbML2Yv3!fgJLx11GYumQy#2wD&Tkd)rVZ-(`RWYYCf7fO+J|SZ<hwqmMwll`F={H9*l=B3Hn_5#ZVM~NyO?F@Mx5cL5!I(-9sO>r%(XN4L2%&6w!BzK2DDyqLS0j4^PiDh)^&U^@ex@7_B=1=L`qz+{ zkE<`HY%94u{Fd61V|XxrKqNXPM>`(~)f37!lhV;a_O{Ik_KBk5ev={_v@Cy7d79XL z`nZ5bdOE_eRy3DbI&OlV>6!n7tnG47J8FTxnj|t^YIh)~ zT`u}_QA=mPzV|C+|9EyB! z5gLhFY6?FeHdUvZ1QislgpDe1F$U=5P^<=9XxY>inI}88o=ASZlt?N%j$_xRfv%>r zu`)E)6U%rFPXd`4zN-c2KQlV6j-pDhZ=m=n558oWL;;&`L2VHqa+Bq-W%VHCrAjxe z7#nMd&<~x(487vBJ}RUpM*s=$HOe)LJXEq1}At3k!mD*h)Yy`k_-F#vHhCW zUU~UDnN-fpETw|4OH$EK+qo!yo8XA zKp*b-YUC}0f8K@ODM2`E0hMQEMhTfQ@Fj!Yq4=t0{z*0hy>T|~x6Iu`2PVB&c>VJp zz8c}C5nqS-B1OK~Y~$}AGK+~YWjeQ9J6vqVjD?v(QX*87BYwnu^L({a(N`9{LSX|Dl@Px0ns4l49s-wFs&J(sRrx<4zWz~$9L3P&K=YI|+gBpB z24|9u!?{+wXU(6&H_NQt!C%L@)H>)V#mBdsP{Sl+(yuLDb@dT^)lr^DrQ=^0;>42W zkzG9XlHE!UQscOxqwMQ@gX`^HC0aRj7&6lbH?@~aV?c9i7Ph-C*9A2MO_I7hXz&U% zJxNWVDTe9ow#jil#Z`g0MxW*P3k~5`nHBio_{9Wd*qXY0z2t3Z0CZn~*HGvhpB>Xq-vZl(GH^sxl2j~N6JIFVz#myPUiSMs>Z>=@c-v)j zy^CrYr^h!?R5qT>jQ+r z96L^gg%FBW!I46x@v}x#akLc}1w+)v$Q8bcSHU{+-*#0^jEt_iNm4%AGk@bb^W_;dui7)6WUY2D#sUl@|J28c$ z-WDo?w-~GmM37q~Oc?8va^o|36jY>tKre-4H9c(#>-&KGhF&zKwOE-)sZ5vS4K~>W zw=LBJvKZDp8#&B<6F%8svBX3adVb_A#T=(u8VS~`P;s%OHz~H}2p=Aq8Ws(Z&RDgS zkiQHICip%N{eHD4wUg${3`a=C+xOv?verb@n&>01oqw#y zTD{yOq*!lwahOsVYuO1+N`H3X#Kls0nW1ueab!F&T%SzC_PA6$^3A!Hhm9;RWM{96 zlgwUUaS6_i=IF|b&qvM4VFR?xO`)G1swHBbuD6OlY>E*l6#`*vQuFUx!?)C|1>CIq zY+j$@!Bfqglk`AHh9auwPqW6F#2G$GA`jxEB;jA&X~a7Y+u4CGLr#IS5WpB*cN&>j zfq@SwcYkYOJTAu{ejJFZ5-dS~$cBc?(l0`wy}n)HHIsCiNG)S|IBYbA3Cq2ADE8`o z=_>DH7C9?R!s`z&hxiDZSviVjovVXG6VRO%qkUg+Ajqbh)I|A9cm?+j^2yOJS)O35wt?8XWB&B&84`ZtRQwb z{nD5B;c&B(WrpKLu+C!e!mv-v8aWjf@g4V`m6-hF*AtSBpgF@0@YSX zVLuEhh6MS(pH_M}Y~62(Aj*_wiKMCKzbX!OrbdqTQtXgp9@`t=%z*fo4VAE&D&ExS z9XXD^Y%kIJ4_$2?WECBD;Q3(|?-Aceg=X&J6q8}FD6?IWQ>7m93slf5(O#jbgQ3%T$e>3#Zi)vtO^Z)RuEon_M!YPqr>XT?RuZ*dT`Oyf{8~p4UsAVJ?yJYU@ ztj84YL1rH#U45RBz!%Iud=Zoh-C^2SY_+C7GC1U}aH;pGrKPNGGFNPgooRt{OpY`o z%cnit1MgeDf#S2&Z~fahU%aX^>zemV$uXz`9Hf^yV?RkEsD}-ixIN#?_4iWfNsxe= z3dMRDQa+tA2{TL$``H6goTx;8_29`U-nva`n-P}Kax&?Sn5$QXwyxK(fVFYa_!iI1 z=hTvfEt7}k3EOzS%QPjL#nq%A(YMgI5?1raCtgdRg-a?5qpw#D)g{v#%O&X>F2LU$ zcr$h~FBE-tLf|IQrlvkvlg`F)uY3;qcE<)@OhIl5an0`96UoFpZCn?(CWA*Vq-qRq zA6m~}OiU(%qINH$i^Afuz@9*8aG}j1%K|SQE2Y&{(Cf#7d9s2#%NBE)-OysA-L$&B_*7~D@5}<71h?^2nX~E-=Jw}4ZIo{)PrmI#e(8#*C&Q)ozpH%%+~l2$?ac| zY9~tkm9=coNIspU>k3M%zB?U>Z*NEnNK!bMk+!U@%FC)H4qSrhdcas-jIbU|>88yV z$1=d9E?HGdUfXD6UQu$<^vy1%=E<8huAasxH@eW2lpR;1!K=$c)=9>G7*9ys!bR$Q zNIz01`vnDWzJHj0kiuCZw=wpaWv-7r=)xg>m5$axW@w9XWV;W|Je=FF!!tf87)^fs zi83WwhFt8=X?Ubm@voCJZ+)NfXnk)n(+ao|VG4n;7b5aQXe^jTFnI6xxrEPWLO|?hC;y!V6KHM@sD{wTIEzs_a`% z%1>E_$&(9Q;-4v-awzLl=7NbdDzldd(S{{3P+72W*QSul+3#;YVbL~;NQ_Q23YZZu_ z{U|V{zHcDx&PzVU_@UvzHDi*|We(il_57-48x#tk6GZd+l~erw>ZMMyyBBPKff3!f z_`p2uD(yh`EBuCcZ{;Lc$Ilddbj-M<$SdRJo>L`YAutBB?@JK8mghCd);i*~+YQ|< zl|P(cf6Fb%x>olhq+H4#_1m0gGPf=zHe*wgQ}2$XUGv1kg>|uwL)F@__pnVeRuPPB z`k0wbcGq}Z#;wD{+1&OhsRf%WvxQDC*d@ZVp;3D=k4=3|Rw73WF@FP#2Nm)$d(?-< zoe1;JPRpO)zTai+6rY(BOqDJ?qC_r#q#}J-L-ZCafx^@!`&802e|oV=lugWiUe}^t zj|U=8?n;I`GC!rt8?YWaYNay^67YvEcqjShc|0`)0C%$O~) z?us<9fCg=SLcCYvYfa(fx%N}JH^(2Y%AethXh8%`7O{v{SO_Jmigbk*2*7mvZ0^Co zazqnl?w9Z+Lp7ni4D}XjUgB)&5v2E+rk!k}wctEap%M_OZsMmbxP9=DwhzAxW6)`W zK-K_aMKUYoO0d+n6~o$9da341fMfaK&8DJeA=8k~6b{aZ`Jtf0Cr*W-sfonI)8Cep z?DG76G#XH?Umzkrj8@L3h(2=B?kFiOlel@=vko=8LfmuzrHvCblJq01F7}s4~8W_|8oe%X; z+oG&%J5k_Lrpz?D_)_3;*HG!R3tCTRp59qMLPxT&rAGl{M8tlsHD&alWtd_hB4f(& zKct@O`5~cedZ^%!ukLlkC1h9&kn#RdAQI>>Vr%i3&ccC+V3=G>7Y$(SmwneMP?+bp zVpx6&vsxjOzL_R?I=SwQedASMb{pHhr8daNKxapFcHT3I8x_|+Y&k0rOSE?h+hEr9 z!TO1q2C6pa1~HxbK|9%|)tM&e>ahr2wZPKEkB1D&xRFF}y(WK1Ry-HN3-Y4z*g(Yf zqMIobJbyJfu^F`Bx)0xbgVRlJilTA}NrC85az>15NIHg*&?lQyJA^Tm7~`la-RyYj zlHONWvYb&Po2T++R^wVd*W;;cr{88=ctZLpS`&IIM9>@wubC|Uc}FRpYQkhcR>W|Z zknGtPh=A^GF}^DF?)D}$TfWMJkWLsVf;5t7%BeN9xbLOwlU+}@7cW&JM`3IxANVzR zWuLE*eru$`aE0(HRz zf_2XRAGXdhMwFmiwBtEr+qR7}w$IqMZQHhO+qP}nHs5@?_vYrkyres+>Z(TdkM2&_ zUTYU*!(x#)#0qSZM&{52hwuxk6Xak^KP^wG2kDuKT;c;i6PKaL)JZ8U(Zf>$DrZNw zCO}cdX)A-^t3$xMw{pA2wPPsL{Fw2yotTvl7l^1aju%-YwJs?{euS#yQ=(RFU8Xzq zkVtXY3l=@KDX~uQbJQeCHALzr+}y@C+ZyCVCGF46RJfV8o*jJ^Kxo(EI_74#G0u>?sGs;NtRL3R6WPIifrkbL7w*TJWBmM+RdyP3`pA zYn{xAqlj8@%;-a&&Ce*02dz%6)f_}<6AW6p%jc!gBV!Y-G=)2rPSh>Z(sJp2o#4C7 z$rWekvgM#WjZbIP@8xtTV;%EP8_{O!sR_QonNT+GK2Oy&b z;ancDFDQ1*CahD;%~K}7;4IuiSN>}Wl%8vSo;_52aVDyN`?X@81_!_FU%;1ds6V*| zre{_R>UnoEKjT0E${S|}Pl+lhm$_o8>#@n|#|3n5R`^1ngbyMs*8Z+MWpc2_BM!%5 z7_$`K^DvaS@fQ}ZhvjnE6g)%@0gaZE+s9gd!FE|fqe)y!kiBS46U?1fI0Wix(pK;N zQ|aV>cYbCkU5L^?W}6?-QoTabdam11Ncn}dEz(W*E)wyj{80*~Q8~cvg>vvJ{6Ea& z;2NY;La&@-2)J02UgoCT&zkPHVf0<*K&L=#>i}q$UCMQf6~yA9PSN&9**ZbG29PCj z5!w_Tt6~1S^F!WauUg;-Nhxq4d<0q(ps1G9KhQO4dLq`mKIDg*A<+C>p*^Yd+a(Qr zM)W7akL3$>3X`d7PdjwwdYm#Fw@7?N`9&6Y8l6l7(Mptjr&3BQtP5C)?}YW96%C_a zIJBkh8qJzBr(@vpv0Qc{QN4A(@2af;U~@n|DDV3BM-P-hj*llT_5rb$8UXBa4u>l@ zTxgy}mxk%!1b%nWV*3^NL& z+57h}3|QJgN5G5*!4_sz5Tb?|)T2fe2s^pG?#>qesC z;$Z85I`Nux!;I5RE_06&o-Q^w%h!Q7xmtbzYM0CsN^P|fFBkJY?m9+zO`GcRv96K5&KFQXKfXcM?!arvU zL^kZ{MCj={LM1JXS4&1Zh#kg}T0iMgs;EDEFOZ#(YY1w+)5u3Twc7L^zIp%ZVIiUSU)5a395b zC#dd2Z%a*m7c(?73Ei6tq!;9lWsx^moB{k7FBzyx)&Iwz_-ldqUzy;4`4dHKtR01n z91QHuY#nXve|hZRx{RKc5k8%gxS*Q6FqNRRfGWc;yDeg=XX1d*{9io;1Z-UKHE4e2 zgfxu*G21Zw%Ef-YHvdVA>0n@F?f6T$|MnErvlTNkGco?|+C~4XjfUYrjpB}a zmSzV0)+Uxl|3SkQ9F44$|0CLfq*MLxoqkm_zsE4uvsW;3#3!fYrxT7_pfjX1qBEv5Hv3(ie@iw__H-t6rf#;TM%Hv@bQW}$bXIiMbT)K0)<$%; zbhegG4s`Z(4s;G?u5^xcj;8iTMs!YeE_7~m?nd@D6#q3k5wqWG`j6}S|H+5+3$6d} z?fW0*osp55<$uWbU*?^Kjf3fbs{a@B&c^WHIR$^uVP^U3Tm4n=S?W0&2^ksK7#czT z`c@qr?Tz%TAYIoZUqI!s*XKbY53KvL`nI;VSX^zfh z>?ab_U*A3FUHOp4O_kdfE-%^s@ruGx{}v~wLCB53?TrnM^!I>6slv?~>H$?%SJQr1 zcyfxRs!S{2pE@Erb0D0o%1b`apHO%g5KOL~4dTeG9bl9zJ^&6hEC4Dl-=v6`q>Pv# z(B9$x{*N3!E>Rxez`BYg48AxBd=qdWP6D~`jWrK;bv0Gao|U&5QGh548sDUpl#IO_ zN8eJK*}3sWbPzda=Vp-gZWU&hX28<5GYC*Yg4NTe_YvCRnvg@ zWo{^F@tJaocDp$Fq?G}4E#W}Es8siK0HJ+-*uZao6r0>K%aH zzQEHo{3a)V;`NU8XDR{f?QH?aB|f>1w*qfRi~$|NZ0mm^bB8-1Us!)6ukicr`wp-)IE2^+1!AQdxkc zd{9*I{dmtVOtYUluV3FdRhxkA)Heqskh*UdCp|fjJ7klSu!aYBWS=)w#>$@-{cMR+mXTM!=3_#kGEtcDftmBM-pkq?h6GWpbEtp6=mVs$udn^Y+xeJI zQ}5xWl(}(vYJqy~mjBU^M>I4yd0x4$v$F?`#KDRB3$MBj9vPK@v^(_vAL{+3=a+h) z1gUrMmIdsLcmPb@;2`{TD$vXXFrMp?`Vr6sFs|bb#pKo^tL+SZ2q$Is2>+-O&zj4-cK; zQQV-0`1HEC{lL$>S0BmJpXmHKeTS>dyxEhvnK|@%+mXFAG`KW;gA0FA_-u=Q2?<_X zn@4z!iSChfc5e6(?dJ-a_#MQ6=I=$YbbK9f?lf%u7SH~E1MYn6y`9+JNM-Yl_$0mO z7_m6nIePvOetd9v?HvB>_Vlp$@wwzu^v`!@QTW`R;PqL(Eaih(M|K?eGbMJYQ#3|u zOGaPO#*o*BH7a5FT|~F!hY9{QrP_#RW+R*+rqdpoa;nv%fxy$q>CAySP%3fOKtLs{ z11G(Y5w`dU+l9bb5`ON~!R}-Mt|Z9l<2oX5z|nM-Q?zHe-g+dseYY*hNe8g4N?+=^FgHAs6v$O8rk}F0nDB z!1sgcRJ&#g*|)%3u5g3A)~=%Ex(QF4HT+`ervfoY zhPrjrb<4rG6a$ju-kiPgEnmkj-lo#f@bH^B!f&XVv>xh;unVP-=Yf*~$--V}h_RBs zu})Wsp(L5Cpds{TKgvI<2~yufL`0LyG^0y(2sbSRse%NREPJU{O{k;>As~u#*Kom} zvGX8*96Phy@gyMdx^6N8E6}(SD3){2>+YsWobnRcIaj9&_l{K&*Xn}MjkB!H`He++ zeMGw4xy)rQh4l@hN$VRk{U2YTzf_c-W(J|hi(2{U<@2s8;j0K2dez7OIyrXC>hJU_ zS3*~UMtPifm5nY;G@Ifh4!EoQb0dtzFEw``Wy9`@GLx;7*2n`0@ivD^5l^eD)dF#b z_w8h1+Us-%FONRDTQ(R$t=ajrJMiA{kArnJ#O03JMpC<__0rl~67^5o_DNIr7Yaf1 zp-%q@+0zu;jsK)eSAgc^y?B1(Z)Fbv$!r{*yq0kj#M|USI*c--VQWCQ5r=3fJJ9Ze zx_h%}TvTyrDdDy81hl}Zi;`uHE^i=@(6U#O((01SDbKJfLQpTFCB9#ozJQ#uV#Nr< z-3)00QfwiZ+u>5y(eSn1Orcr3Ib9O7cI88%V8`Qery8fayTuUWw{3Ki{&`Dl>s6%U z5F<3Y1+7U1=Qe%)=j1B_*TmjxgiVB2Ze!NYbd}csjZNg|7$0eR6yCzBj)Fg0<#47D zUx!#C>vIVK-M19DB#je15>i)Xa+#~KbG^PxK3J&wUQCfUpqjL(mBv}oM4e-(qZ8zq zzOfj4P;qUqV#`zGsW}mjq9gMT&v$B(DKj(`ht~*)URcnp-z5p0!0V+TE^;oW+W;+nqenOWx?_hRG8>>Kk5&(yo0tNK~e!F z9(&nm{01b!=};GPg*{NuhHp|jol zNC^S=cA4MU$thY3P_uEb48z9Xs_pgNdQfRtk%>7VK$`=8-VQaFKyK>Qv~#kL=$K&M zGf&q{4F`vt_9C&cagdlaqD^nyUG-hfdaVs~zD(jT5#_K!zDCWj=^7GTV?#(G;pD?? zY?28wylLRhRN^_iz3y6zKpQ*RE@9=WFUUenGqLUQYuMW81YXbC<&)}gA>@&_Re(do z!S%BqPY}(?5Jh|slIP8&KVDiPkHduQ#glG!sAvLFn_T%jSBga)J?KIuyIbgEryS-K z%aDP^84n5|V^n^G_m1lDR`Cc*({jOrk@i!U)sBAobe?J|F*(nBK-fw@8|oNfn&V5yhURO zjV^S2El*_4D&fKz@g=St8EJOAG*=+d*ufI9J}mV0)){s$K%M; zwutZ8HfylHn6`CkyNJi?mYhn-9z>$MQ!&wZde5KI5q-cLaw!aDAxyp{N})g3gs(!y zuaT8SnW~c}ImL(uL3HdF<=r5Ng~!5-OEjg;zm3Rczua>Ny=XBa9zv`0Q9Pb`J{sra zX&YJfs+t-27d*Ke|LFMT0eVy%r^4q1K60RSV4nj-BaX|u%YMbA{iT<{MY9;3%q7_D6_a-Hls{rkZ9xE4g1!|W!aTsK6E`I zmhLD69**3u^Ip>d`17tER2z2;RmbPi^4=0It=XBw;P8t+me5rL_Q|xU=&3jSY@+ZH z8GA@ip|pM|u8`H}>Gi%^k4S!h9ghCdAjE>;~5WLmay zNRHhY3EIMt!8Qp$gRbuU*b>V;Vm5Q&#Fa(=R+rp(z)Noi^uVg)9ds2(K_#Y!P zgYy4z!qj{eU+@Fr5nh`-n(5CZBfL7(MXjmd2bIt(D|ZUiyR;NF9QO=_eePn7)=~Ie zx-f1ZaHyWgTBj{XGTU?|f6OK~%-dRt(W9VbUW%O_nT0FXK*B6b?@XpD$Nu4T@i5J|QuhY*qes-Xxni!IqfV7G?j zBEKhFl2i={+j6SP@Fv&ktK7bI`{9L9No~l6^o#((<93MjjR}tw@XqucbY&o`d9ilk(X-<=M3o#@vb!xSNf=94xJitw5LK; z>D=z9u|y!EJ7uG{~}(uK&+s)wKajwdL)*vRrA`|3I&+LsC_j$DhUMm8P8x z&2~n)Qg=8ipwqA?^|?i-(E@X$4ke20p7CA}|94zK63M^3hK&7RiK1|7*JKRu?^IS| z8jMTdmuBme)~0jiU*anNLsPG@^zaU|C{~rR1`F=H8^z2#wp?Q|evTtX!|$Raqc(O{ zN7g}Xh9qa^ceftpDUPAT zoRawT%>HulJ(GYNuN|-+#HD}{7Bb~a)_SKAK2G8za0CYPhN~)70`Cc z6mG6)hLD21A4?+)HdtxE54@WQ#}>9x$J6N7l{5cK0#g*;B1@#q&TjN5g3sLVY>{$n z6ypK<>h@%qpZCTl(evS`9BuGA2mM#9aY0K5n3VH(tiJutCDK4V&WlE6#YlB--{4WL}9-(U{ zMl|N7+wY94N>T7e6l2<9e*)gz;oDJN?qZ6zA7H%YB865xybG#SE!+lOXc-%)wzeNb z*NO$PR9~wY88=bDA`IuP)0RQ-a3ZSlXm^#j9q9)6y?TSu2%%fd}uQ;xlJ$Q#9tk4NpRisKLo*6$dHe zkpr=RGEMbekr5}%K9z~2NAcScG+ z@;tD~`$Eo61~-(B3?Guj#g|?oImbnsgxaV;5Ap8$HcV&a<#NOEVo6HmSK7upp+cVG z!X$n0Iea)M&^8xde`qi@jIpYU%Bdi?@u&ZZ3@6FoafiG2Sq~Sjylgy+zgMR=>TRD| zrP>wl%{7LHtmhz|T(Gl+FJtYG?j1soDd#cb+w0eO?q2NWdd-_)Ro!>mVQ%j@ak5gC zM1SMiWKFYb*J5U)po%}*Ah5$wbh6JHg5jf50x8|ryAU%wHMSDRt4)tgh>iW5i|Ssn$DbTEHG&9TjfPIu zvA^qEBM;PM_j=h-Hp3ZPQ=uV|xN3o?2faCLrxK9w-ZfuFOqKs;Uj+(SiVy;VW)`SF z#1d7%4I1`Gt=nPZOzHTZM0xod)R(R#d#m|L8ekCPd89~PX9LLsWQltisAt$}L^&

BSO+AC8Na2||Wa{V7)jZ1r5HMDZslmz)ljj!I;6a5TeqPH=C z)STLENlN}QaWHU08GToU3~fhhVnX@aP<4Q@=NK+7{TYW=qZu^vLpvcHf{(S;mL+i` zx$UYTlOv6JwKB)tKG_)-$1#%-q>f#_>U=v*j^&}154rH0y3m{mPWOgoXSDU!LIS{;1x)$9wRmfoPT6tG8>@cjNt*j;CC`(9Yv?N8r(_<);b zrRQ7*`@1U;$m|kjh~gKJV1rqnS)wS=D7JQs7gZ4Xe2|(9I!!4@oTRY(Ckq~BMZOzr zG&YYJJX3>Xx*HL)4(?x^?k)ydtRFafO_uy2J1iuhMkcpaR0l=M@MRVT*21bJ{i&-V z=o;o)#gQYXck|+z^yq1{(+%0gwQT+s`w>!lK*V4rcONgbFV2H?^EDwJ41iyHnI~0aB&j^D>SzjqWe!P9w+E!X?1oc6ro3 z8kqdWT+8Grk$(~)2spg)-gw9+Y$LZPICJQQ4qhtDg;#94vwG&=HpIcS$yUAope)>l|FOu z!A*av%SOCNQw`ihL;M~odLjUnH1d>5>M_`%o@Z~9hY@*>jK>(Z<*-79SNL=mx%5g` zqn%n04qCgYahE<+rpys?I*fx<#%%Un!Tf{r>PzFLZ7KQMK3nR6C!BYuGuLr$dSI#z zT1L@NcwR53^kQSCjJue|@}jBTopF`vHOJ&#h6UEuck3L5Jroiw0vsK|EyDWu@4~T=~8evM1Ms+NS z<0Y#VhdRCWEq}S1Y#N~Tt9=tKQ)9>GcBr7v$mxWjknpm>z-STnT(w3$3ukknjz-Jb zC@nO)y00|^K7R-j^$3;(g@n&XOYnQpY<9~+pQ0`T1gM!bEv%`=^>ip*=GUg@@&i2u zw*4npjN@S*UBMppxEK3ePt6;DO}%79=>phhoy@2C%G`klScY|qeww-G#{$Kn#w~SG zqmcR|)sJ~tL7FXL+XOdGW?|ZnGe!^5+#p}tfBkCavO+0YNR-e=a3=PB23{w?*Vy?~ z&;00W(PS)xT&Uu(ZgrX-N^pSQkNa+K-z{|=bWE~x;u!ApU~!`eo}zkftAI2H)*c7* ziB2NunxZk*l#O3tNtuf%478xnFiX6D%jdq9HJiEL;XiV$EzRbUgtZnxdL}Lob0Iet z;N6opxz}k$9vD(26Oe9xc9Fwe zq_lHcr2k?a0C@Uv<$V>VQq9U{=(m}-+;{lt*`&7WAyN~KIkzF_v)2fGbZY1w) zQUu8mlB}^vY}v<2`gV0^-E6MR-I1nzMgzQ1hv+HJ0$QKN;^Tt%(=kYI{V`x!;mh`# z<=t|*Jt`4}OG=ij_NsbB@Retm>RVXKVAdx&6n)qHFc+=ho*0HBQR6E`pP10mu;^F@jy>E;DD@e#ZLadyRrt+o~*MdE#%hijIq zh}02nC&?`Y>poG>EyhE`4nD`0`{%wV(Vn}^ym{0!2v2ou)S&yC5rz$Zj3QI=2>5o2 zkcnD#e?N(tdB7y4s%ei^wq2}-1oA1#{w`C8ej$vIzxg){OGJy<2G2Oz@+`^-`lvAbVGn7e${#+DDLh5G3 z%NL$DMO)o+`b!_NZ$2PVBfikIe^6ChG!eNU%(&K1yzvQ3=v1W+`bkd<)uJ1mC)p_= zAEzE+O@l(c6VFi-6bpCn`a|m|YDv5U-GS=QTDF2)Hd^y;W!==`C4P*KFAyW(N%6{= zom(*R^9b&kg9VXIuBys5<@R{mRIw>>(+WLbnE`Os0!jOLUZMVQ*rGZkH3k^F15n(C z`D@ZG<~tfT?I)uI!KXH+88}Yh#^{L{JXau-jdv~7bQBQMKq8J8LVzD+9WR10>ia+K zoGC<0Ry%zmCTq4gD>$%|Lu&dMbE|(gYpV{4| zKGS%iRd1U^^wOmzTOvDzQ^yn5tSWeL0`QXK!C7|t6YzOEc#>e!u*DW}nNGur=If+o}?$9s>b zQkzQWi@S`di2x>GpO>o+LfN;o|o ztF|{#BF^FIkWmLMSUvTeB{58$^NmY`+xY-!Y3$e_Eaa)24;b`Gs zT*&4?-Co<8l&8B2tV?o-v5@ldQAMF$#S-iRLmxh)E9Y27_SME&-xy64vzz-k+gxv@ z^VmH>WSRp)pBk*s$$>N20F~MAY_dB@7~S=j1v{1u%4YZu;%8>H)7XBUGK4>enhqrwDWdS!1N{PqXjQ0!;v1 zd#uSN1b-TpWt)q{6|;z*b7X*|GUsq9%@N!W0g1X|baMQofSn)tA*Y1#7h?sCg|N6E zq$PC`FXhF>a8_2SPj9^BH<~of6MTs`H>lDxB$+G31_k9c7m~b}WPqXi;q|P1`Kb|F z$53Y(&_Vcbwqdmn7k92wu7SHxjj;FYW&KHXzh(1agS6NA^I#>9!Zx*e6SG}q0N97a zJh_^xATy48dO`Inxo))tJE$ydT0hjgy~UiKj;*>L#$&BXCr0r^iOi#06uf|_>z++Ww6x!<(_K`U;}fGPN)P;ZaP6lo@r10d zm_yWyo@X_G?q(v*CvAJi^lo}n_`fKniYoZXE2@obcN~a+?|{`#RTC@j1NnWcPF*q& z+l%iWZN(eeS9@)uhNS2dJpNh=om)0*r3H-G2ZGKqoI8$Rc6xtXfa90?p83q*x!G^; zb83l&#glufA$u=S@l8@8Qbtg(4Fg-Pys&&>7Tws^BNX%J7TG6CNUH~C{Puy^@rDm$RSfD2xxvF zc#vC7xvmNYn5;GTEi=PXW~7IGYY?dwoS0jvz0FC()9AzYlFjg$V7aXbrL8Vrx}rCN zJZ3FG%= zU&)=sjCi~Z{1pHOy5^wmZby*L-!D*LSbwb;yX5I~hj{4VZSNKH{n4Jw1_Bs~(m&S7 zxGzZeVmvh~`pPz-k9{W(n451I-BSX`QZ2Zc!(JKR^ri?O84?vHEyXHQAEzdxpxQg{ z)r(8Qqvv8rq%@FI7pErA+!tb$)Il-OkVE%gb=9l7No=nm;$&K2;Ayvo!RVS7&Lq6c zYg^L)C^*|PXKG5_c1>Z?ztH#f8-V_Z4II;10}iim&r=znF(s!yXuC&AmBlJQh?hO3Wbb)1%L#?)Yf3|NpT9Rz zmXN~iur3Y@6*b-q7#!?m52ciT6O+4wB5{n|=kqrkQHh@eXDLl1xh|GIS~zZag5v%{bgy2!HXtZ9q{PJ1f>5=2T4SGvh5K%6idDN*Rc^A3BQf5LWxSU$8}* zTjW9hx!uc%^w-TNNbm<6oCiz${nzlw3E@x`NHE@pr_+}m;`KX01L^E&s1Srj+cUA& zgc{T3$7whb%6m5fyTg#IfC@;HH-wH%9hPs0nZ_y|@z~HJ5iR25Yu0{*ARZIzL^TXO z;gc_Ny_I%t-_@=q?wnYQKB>5CUx>R4OvY^Er+x#Ox>ymRC6P?j1s$>UBJzwx!pc@yWgtGe_ro^Bc zH~rapsiKnCq$*2itWslt$5>t+3mh}qNj6Y_qw(0>`~!TIS=a~Bod@4bKeKSZ%9>pPsY_*0gl)^<*Qx(nI-jMK_FNv;5FxJpsFci&4iZZXDZPni zrc&$TWHNImdC!)6RG@1GYcxL3=I!~n{1MN-E{4s;+__R1Y72G!y+X?UymYT)rTa$E zwKlLiMM}+LmIo}}aTJlf=o#W$VO4d?$S^gYhKhUADKznKfIqG%W~2%xC8lI2VOZH8cFtXw(Cv_lISa4y`=}@5RV}r3A^}b@~K!6T3)ndF?kq=wyYOf$- zRM#+1AFd~TB?T|(JZemF5kFL*me)`n76!z^ZfIt87V?o0HPx+7N*HE+Obz2My+{;( zBsuda!EwB&(mE}Z(chNJsgEhkBo>X?{n9HB?~%+kinf!7KV2KMm(wT9qm{_BvsbBh zd%#L-o`tFqy^*y)y>J{B#YLZ5xxVNhdH4*ThE{#^*x%0euPyb6|0M7j%51$?jTp1M zkbb6$dV#=OR2HES877ov8->VpMAW)BD-c9piNy>>T~_kEEx{<&mD;BUP0Cu$5{Wgm zp!m6Zht-(v_EcAIQvAr-{|Om-`FbmgvcUEY0`K6Sh@S4xMj;byLyNh_*+<&Hg}zI-gN`HJv9dAd=R318uSC z9{=~rIeWMHezbpQr7)owP}3;-Nl{YK7qKStYwv~z4~KVCN@5L}o?V|1uN5_GUeY|0 zvQ~BX8B=Vn%gpvSKzzVh19*W9LC5Wf$#^WnFavYq^En1n7m1|apDJ^Bvj zy{;kmmi*J9?XQ-Lvg8m$3s`HGxmBkZ-V*8#nJL07EYOnRRP4~ecKnypu)JYVl?3(Y zlbSB#v1kn%CEZ2i*DN`@mcy;eQ z3)LT-rLviw@j(oH&{z4rUe~A{faaTgrgZm-5>6tla@3hyy>?6Ner7Td$m5;6GRI4& z11~YUI8OxYt*4wGQn5kP#W-yoRBQ?(m8TJ3(||Od5!^ zrKV7)6ZtyS{?2kTasx6sAr3T|hDTcR(HtBp`rUK2SpAN56aCJ4{irXAIb$=?J5pib zh#w>DUFMI?Fd{ms{EyZ=$~Eg94UKHSZpB6Z4{j&wU&3+4J?b6{+++)ZdNSc%VYeNW z6B0gRZVp7&w=3coe&{PRH=Qpf49KZQVq}yyqeQZmU9Qy88j=E3*7c%>%OYU)Wkx4V zq=2(0J4@@sEesNVSqp%Qf{HE#!;%xd^xS>Vo8q1^>(1Qy2tG94uzTP0DO~q1CKX0n z0q_TEXn$Jw2#ap7Gp|oYYi0-jtVcL3KOLZCusM9k_ra9vaIA))7n?{Vdu_Q+sa#nY zlbiML658xD@uEi&rmt;>IR6^eewz!cIvR+iXp+dH=x{^cz594mX@zWfxj_?VwWF|6 z`xB&wv!fh}cOw@=kN=5)E#g@vhb#wET`uZk~2GC}~B;JomL@5bHmc$#Oo&;tJhgBNV2L3ykQy{oo zTVk~jvH{$69V~5}+NVg=&0#Kx@a#CPE?VPb=_$k(cs3dWqbOBn52V~z=(!(Uquvq} zxN&-c9_&vhEwqPkSs;qz!Pe&P_W)n$W#KhL4|l$c)KeC^e$hVMb)0dZQ*}3;IJ!b zM8yQvY5p2c_Kq&NgX?EVf}mpC2eEqTS>@ZUVHVjW?<>B5mX?#$0rfN){<3TeVGWw| z&TPcZ@taoA^GQpftGk&-JCGcki{D|PajECN{B?rpBD1?3$c1NPRNxRiOzt&+9=8^B zcIMnb8)P3kmnZzs)MbXDDQFDF)WyH{L zKzU3rJQM7$6n9Z?0m@ni9$5xjO21_TmVyVvy_Dg3krqVEcebg^zR&!rV8fC7x<(%4 z38zP1Ou2}0l}^6zlPLyu7Y=|m3ht=3 z*DBjaZkC?hI6NZ@iiogab)b`!uC(feWcCkhRMX!#gD73)8%dw^NRhFXsj@Uv^`Jka ze)@816RB4rnUi&vO05yF#sSn*T|@6@MAf6umJJj1=Rz&jX@ES#cLO62Cn?cY#%Ht0 zkQ*>DzBP&}x2>{qnKlTQ6e7%A1X?P~gZI#dv$#vryACRi2tZ?@1{srCZ91jM@QpLDPz6O(n4mS=@E`vKcW^7N2iKO@Adt6Wi0nV*; zY@?*zTz8-Wf=g#!6_VfPgi{d$76BEwYP}W1@NR5;)Gx6Ww^@;s17^~(o(0q#MCNMF;iiE!nwjGG##Abb9i8Zr=!2!qoqlg;{S zmJn;*=;^D9)3sU{a4vW(ESTe4oUq#kU{J}ACr_m~w;v8)k>|VwcK%i)>xsxWBx8!Qt=_cGZHL@U&=3@2_B7@+kE_RL~lr^jdh{wxa!-gAP8)69pwdI9w3;*0f%Y< zx#=LdMw8Qoe2&e~(kP$;bx0aDOJH!3D|V(-1T`><^$3gpg#h z*K5_xd0MyPHkE6wKTne+GQXfWVSg(!F++jymR=i=N;`RbU zGNjmY5$?qHJRlXB^hx24;_Q;rb@B9~g+MdQ~lCKD;HHZwwjU$N?hCor|j6 z*PyR2k&@Wo!5i!>Qy5+m9S#S#wa(cmRbYK{#6lhv5wL%C#DsDP(1UeKXES=9^0C3L zhn8l{!w5)|`ZCwk7_Zhopa#ougGD5>vIzj@pycQ``nw_u4B*TU6Ivk~PV&b2>VG~eu?@#aI3YAE8BOhaq( zcLK)W)N0~B6~oY1!g0Bg%>NY|C&IMN@*B=U8^ray^^6BRplTWTD%z=?ec7-{G0j#nLAyRSz5WQc9{L zxE@9p)>~^nym6L2e}~&MIAg%~*5Ifl8f?#BfI@?im`6MrhtRv2-Iy0Ef&M*{-gaz` zBM}~#z7B5MdNl%cSBcK?G?*S!JOhpe<_P`J_z^)Yz=0aJwaN`2nunX2D1WGVb&7Td zd^OIzaLRL@zwvI^TM}*aL08t?Slop3>h3LouaMW)y}AKZ^)BZPk?wxj?+3yK!K&Zf z87SmCymzc>LuVIILXIy#QhE~6#!iE+PE-Ui%;BnWJSf#mdYTgf?_#tE1?$ytp1aeAy+U z)Vc|wF}!C+)h8SzGm|;2`OU+6Jr|Vvtz5)95`3x-gsMq%3}HHFaHa%RiSJxIM^#9W zSdC}b=!1jp7$epl^OC}^sgFk$Jd8oQWK${HNjkA)0$zaOoCgh_+6DHt5MtxoauGRl zM}XP_-?nknLde7D#&j|9O-6@8b0MK>xh8$Yz5&imqdADvX+)|_AMR* zv=+UOdryE=4kGAeU8w@ElKMT|y(MMrA5uncFf4rydT1oQbgEJPNfS#`2xVa%6&7Fa z5baJhbAgewy75JflNztVn(GcP?nN_~#{HG|JP{<2ipdrVd=3+kz()yR=yVyYKcL*C!!r=bV|HuUr&z}BG6E}4 z?G8NW`2u&bZxFR~;d5OyA~axxGiOigeaeuFowM?(Uoi2ala7Dr3!3Q=HLqKon?G^s z7UeULgtLZc5ms_?X*bd-{0@su?kn&1&RIgsyS0b&1sa(F00PEO2NQ%ZJwFSj+pxR? zQ*pu6tlgfelwy(6h45Iq=E&(w?0*ooYBG<{dXc0u_7$ofTur1Di9^&}d4mdsgGc zR#9`61Bf%@sZa4tAri>d*T@;6={c-#Duf-E_l(_c5iSZ5a5(3=X=)noNDG z=#lKCU_@s$I%KqF@}STOnUdC6Y$oPH7$OK7Aj6>rO^ zq#e5q2QLOIU4OqdJnkda;qi)zh|di@5uudF%CxhvH}=)f4>T+C*q)DofyuGhcmJ8D3O!#YdtUTXXqM1Au`dXU9b2$GC}T14HhHV;*3RU%{eZgNG&kx+vh!<-imhK z0x4%2;D?{MPXtT_sJXn=m_wM?J_i|1gnbifR#b#_Fx}>&C=^L@=!tf2P%43=E(~j6 zT!5{!+jd$In78CRMT*#Xw6vZ_4<^2#H3mmp3%xklZrLP2KnB^Pju!r4GL=5ELO8~} z2!-b<{B1VKGxwxSK(UxePubp~@RP015iDH^UMugITo!osr|JvQ#EvD>Cdjo= ztv9}kq`DLNru4ikfH2^$(4%gO`f>50L;wnl{DO(JuK0lFp!*v_baa_OWAv}~D*kwm zJ8A4CXr^QDJB)VL6a)ivt^e|hbyOk_;d{;{Q*b-AE zvI?%@B*hVqYHp%Wk6;s;+A8R@ZEfjjCG*}%75{fE3EThSYW%;kBx*u3@-nLb#gZ`o zvo!uYmW1g)ED6IuO@xW#{~wlwp5y<4B@z4wlL-GWnnd~^P9jSu_YWvhpi}&xNQufn zro`}nK_&kaL-}vGlK(qcVr%iwEBW7QiHW0yo$-I+B@X|^mzcQz^G*JPm^fJ*IGO)% z%EZ~t?jL93`VTa5{|{;M-=HS{AxsqiX(I$Cw#IgbmQc)W?ElBZ|KF$y3j@RdrI;`h zFfuZ-{Ucib>*D{3nlLi4(X$c!XZ(LaOY5AP!$tt9 zUH|mJKhRA685uDN85yVviHh4B%W!Y_3`8YlbL+z!fJ2{jzzk;j5mf4Awg*rxO7;MN z#@kl_)YbrKvbt!rx~8T8R7^~>ez3UN9)JgAH!CLqprZa&zz}DF;*=+QXUEny7ROMf z@3+MMBhhGm1A~JiziC|jLwIM_Hl{#86zOf6fY<%erev-FEZ|I5`IW1`!TI~GjxH`o zCWa4pclylrZU)ZwEhxn$;O^?3nt;jywESjn`5b$00{|k(UVFP43`B}ROVw36KdF@* z>TRCs?7)Ef0XfZ>2uDCK_P`myIe_|({+ZF-{NsoaADikwcEFx}ewM)c2FCB?TYg=B z;0<8k$JU0XC;GSMKo1RI8bH)l*Zu&c5+0&za%!IbkYiu11ra$>z-zlh+d~^OLnzjF ztK%{Ni9~+@knID1C1!`G);H#tL*|D!ZrmcJd;f(zQv))hJJq#<2Wsme_~prMZD5*% z(RQLQ?&dUua=80@{{T~037nwyCegb&87}~6aJ2)P4E-7bp%MNhXaMN|;!I6VX>(fx z9ULadrZJd;e6w z=>?As0MWOyI)SDG(NqhB`xOQa^GEeEw7t))wTLbrKKe&B$j+~9r`&J7Q*EM;DfoE0svEiGx;CC#ybSyfBmpc@qxbCJ@`qa$W;A0 zwfTu818T4Xxc|%mYIpsf?EmD|=fBTR%mMwR3Csg>Px1py=gqI0o#?Xy`_+H>>H7C- z|NKsW-%|YA75)0blboBHy{2WJ(0%{LZ4B*f%v|z;?J2lAf!2lu0=skY|E~ViOkV#` z0ZjiR?|y4lN0vdl@Q4VcI{hZh|Hb=VLo%zixUw{Uc!mCKg4(-tSs}=;_YZ%(ngHtq zuwDJ0^+B7NLifmP_jP|rfr8vF{whlPPvK1Y(cw{nllKj+uMa^ZZh6ul0KC=tvn}DA zy|0=Br(+1f)##%Gu=DWwhXgSl+{QXO0;CK3M*WCp1CY)0g+up|yns6do!-D70Mbi* z1+}FEN+JHvz#D?nOZ*C01CV9#K}^xUf(NW0{}Rx54&Z~Bs(l6ZT}l2D*wS}C z{Ac?9Z(8Apkgjw69|fiSS75Kv{7XRJwff)6n(u!rU48_(^`(;dAgnDuzyoNee*|#! zb25T(+m?S*>KcDj*EWCee|dnVPksaUto{9n{HdN^0e+17pkyJrQORgk{X8ExN5^5i zr2Gc_C-v{a17WFuK-c|*F8zi<4*BAPuGyS_o&JT^1oHKB_-1jnar{QXTI;{lLB#%^ zI$!N^YI$&I0t);#08IW2&%)4_U-uHU+5XOeYAb*G9Rty><;mmdt0A~M{gi-{U;fMR zxVpOIv%EXU{VnV7$LX(?h{v5fkV{zC_#t-r$=hfQ>fDFu8Nm5@io(rqFUrZ9>^%q~ zmHp*srSDG40)F#--=+Pr?eB#e1F9L#!@%i9ocq=TJp{<=^xwt$oeOMqt^a(5sjKsc ze+>ihzGrOL$?ImFETK#v=r8|Cb z;IT)r&OccfezbHQP0KWpnO6HIiDr3&skL?kTF5FJcs_a2 z2mjcV4Fq&@2e2ML4wUj+azXdeeA=$d&#R+KOk?P6pm&*6#?|qd&uT~BlN_M2El+>GpMU_@`P7-qR;jjL=-7#zEL62^z; z2;Z@W>rg(H#ArpsDXW58IRS32ToTpFxT$$$mRA;IZek*%b%>Y}s9lj|xsqYD{ytk$gq zggFqM7*Sj!eXz#ZIb6 z6)NwR0kKVmCemkol@I76(>xQ#$gLfzbKwW`F#m>RK*0&x}=yT0gEt`A} zDC7yZc_U3RcI_arkYFJ%58D}bce^O*&{>9f?dQ7qDxbm;aDU#Ea;TW;8kAV*|4xcf z>PV7cRh+q6)u8t$f2r#%={^fRi2Fp^+=0mCwACN6zJXf^KH3}>nn8C zq4$!>V~{^|P{udc2%X1*0dXMPToap|+(0q6D~#GFoxDQ_P!wc-=D^@L+^V8X0)KBhGeDh1Cd5nIe2=hO@VwR^Ej z0FL?-(H)^oQcP*|EBZrih<2i=_x7ar(*pdtSS#}ym2o+!YIfOPfSm#!a0d&^!h$I{ z_%Ww0fAR-e9@pb1KR1$V0%CsbFJShw7=tw1J;l9NGP2>bWU;!Z#D5~+n=yk ztMryEJT*(qPLeEI-ri}gGkiIFvVr@BK&|j{-@3F0KW*J<%)I7p z?w}Vuz2+y&bw7A#QLH0eP{m6PFcb}AfBSwa{Z28CHYZA!IbR;W_Ed@?WPcQhi5=K- ziPW?g_NY6Jq(zvNWWC=GglJafl6-E-7C)RUs%Qnnh5c+&XG${&6#@-3tHF;JPeE>T zdcf_xqKv*KwFU(w`=soahSu}=*8Cc?*i&3?11MwiK#!}(6n0#nMr`DX59~j%)^&yG zNi&4e;XWL6!QN=VqJZL zAI^r^eLNtsA!Sh4cr{*eQlyZoKe|V-h?p-6A7{9}Puk0}(@zdHh(NL0HeS6|c#C$% zn~!OsHya2f+Cv)O%_CSK6m0QUM8QFxZTnobF>i`$n#q?E(E&R4z(I+Nrav;3Yo1}# z-5zksceS9t=y3o~I$6PT*~(})O6-NCsKY&`HxQ8gtBS;0?+PDZY@L!vML{Dg`Ebcw zeagS4($(tj9Tf-bBh+6@*-lG(9)nT^G(ck!IcyT%eZRI?@D0>Z!PcxF`8&%6t4YVJ zGTdh|LV0DL6pb59dnrF-xOE#JmI3wD6+}6}w2(Eo63st~+tsBwUM;Gi=G*NGKi(|{ z5<5rE-b0NX%nq(j%F9gNv7hY+6~j>4_(X7#^vWhXv zS}~3}iZw@LM(C^8!h;c|fcux9&HMu6EnwEH+8TziOfdx3OiwAvj-l3v+wg=2N;Czj zNbv>U>ciFc=E372zGw&DAe95?1BfqpoWzfNOk$_}G=sNv*v%5mr>UsEvFc(*lQpL% zT8G$Xhb~Jh1AF=R-P>-UW*|_D=>(qQblrJ@+L{)R3WTH$V*~HBGu>|rp!+%YHq=i^ zqwY1t?I*{(g{`Mw?5UB_thj98>t8#w$o-5tC?zc(6sE@|dWCR;h}1wH0hcV@n7u|Y zyF^JSv@b_+j?nQvog}`9@SW%u9|>5M+~%>;HOtod6}5MXZl?d7X6_bb!Nr6bTq1DS zo{^tvgJ_*@rmGPBG}#%V&=KC%BU%D&_M}0O@RMQJ+~l+My0()EqC+M1q@XLx`%KxW zZhp&{dLQ+fQe&f6&OME+% zH>ggpDe`q73BLJWJem;-T~Q>#yYCk@vtRj{2Y0A+nXuP}`!3!vpL}v!*K!2EYNI% zZ56Z}J4y4sDk;N6!ehe#}BY0jwTT3-TE+__ahT!x|o+{sv*>aCXqOb|;ckx^{}Mv7)|_&$kG$`PL6_^V0f z$_4vr{by*TKekg55a?k%9sUx<@+GR)aoa(~{<-qvY1~sbG*fPh2C zdCHvQvw{onv8IfFL%h{JymOhEnzSd@ve#^Ra}Ka6+d>AvXuh$z#yd9-iF+oB!B9u{ z*8KQvcnWN!Ft1}GEH;%{XbWcPB~QNI5BuoI!!jt?9Tk}#^8W;2j8cARX4TZV&xIG;4`Ahk~N;uIxD>62XrxhYfG(K~K$zdm!(h5^xM%bS_^ z@s6K9&W)5sabr5h)5{+Rc*1uJW%3Ih7Np$A{YaHDpB7v^xQkVj&u2mRTGnC-KuWfs zEp)G;

}Ee+eiHY~goq+FXecoCCU+U_Yk@9P;NWudZ-~kKm{g5G0fuH^o!0pE3%G z68&RV*zn{fNZ4eai2Z186S-Fb3;#O(dU|)vd3=tw5{Pm~1sD5CjF7tz)H}R4x<4ta z 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 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)