mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Remove nettle library from OAI, support OpenSSL 3.0 and 1.1
Add byte_array_t structure under common/
This commit is contained in:
@@ -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_OBJECTS:ds> )
|
||||
|
||||
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_OBJECTS:ds>)
|
||||
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_OBJECTS:ds>
|
||||
)
|
||||
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_OBJECTS:ds>
|
||||
)
|
||||
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)
|
||||
|
||||
@@ -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 )
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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 \
|
||||
|
||||
1
common/CMakeLists.txt
Normal file
1
common/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(utils)
|
||||
1
common/utils/CMakeLists.txt
Normal file
1
common/utils/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_subdirectory(ds)
|
||||
5
common/utils/ds/CMakeLists.txt
Normal file
5
common/utils/ds/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
add_library(ds OBJECT
|
||||
byte_array.c
|
||||
)
|
||||
|
||||
target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
58
common/utils/ds/byte_array.c
Normal file
58
common/utils/ds/byte_array.c
Normal file
@@ -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 <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
42
common/utils/ds/byte_array.h
Normal file
42
common/utils/ds/byte_array.h
Normal file
@@ -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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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
|
||||
@@ -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)
|
||||
[oai web serverinterface home](websrv.md)
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -44,7 +44,6 @@ RUN apt-get update && \
|
||||
tzdata \
|
||||
procps \
|
||||
libsctp1 \
|
||||
libnettle6 \
|
||||
libblas3 \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
|
||||
@@ -52,7 +52,6 @@ RUN yum repolist --disablerepo=* && \
|
||||
libX11 \
|
||||
atlas \
|
||||
lksctp-tools \
|
||||
nettle \
|
||||
tzdata \
|
||||
net-tools \
|
||||
iputils \
|
||||
|
||||
@@ -44,7 +44,6 @@ RUN yum repolist --disablerepo=* && \
|
||||
libX11 \
|
||||
atlas \
|
||||
lksctp-tools \
|
||||
nettle \
|
||||
tzdata \
|
||||
gdb \
|
||||
python3 \
|
||||
|
||||
@@ -44,7 +44,6 @@ RUN apt-get update && \
|
||||
procps \
|
||||
libsctp1 \
|
||||
tzdata \
|
||||
libnettle6 \
|
||||
libblas3 \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
|
||||
@@ -41,7 +41,6 @@ RUN yum update -y && \
|
||||
yum install -y --enablerepo="ubi-8-codeready-builder" \
|
||||
lksctp-tools \
|
||||
procps-ng \
|
||||
nettle \
|
||||
tzdata \
|
||||
atlas \
|
||||
gdb \
|
||||
|
||||
@@ -45,7 +45,6 @@ RUN apt-get update && \
|
||||
tzdata \
|
||||
procps \
|
||||
libsctp1 \
|
||||
libnettle6 \
|
||||
liblapacke \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
|
||||
@@ -41,7 +41,6 @@ RUN yum update -y && \
|
||||
lksctp-tools \
|
||||
procps-ng \
|
||||
tzdata \
|
||||
nettle \
|
||||
net-tools \
|
||||
iputils \
|
||||
iproute \
|
||||
|
||||
@@ -44,7 +44,6 @@ RUN apt-get update && \
|
||||
libsctp1 \
|
||||
procps \
|
||||
tzdata \
|
||||
libnettle6 \
|
||||
liblapacke \
|
||||
libatlas3-base \
|
||||
libconfig9 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -21,62 +21,61 @@
|
||||
|
||||
#include "nr_pdcp_integrity_nia2.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <stdint.h>
|
||||
|
||||
void *nr_pdcp_integrity_nia2_init(uint8_t integrity_key[16]);
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
|
||||
unsigned char *out,
|
||||
|
||||
@@ -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 <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#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 <nettle/bignum.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
2
openair2/UTIL/ALG_DS/CMakeLists.txt
Normal file
2
openair2/UTIL/ALG_DS/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
add_subdirectory(DS)
|
||||
|
||||
2
openair2/UTIL/ALG_DS/README.md
Normal file
2
openair2/UTIL/ALG_DS/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
Algorithms and Data Structures in C for common usage
|
||||
|
||||
2
openair2/UTIL/CMakeLists.txt
Normal file
2
openair2/UTIL/CMakeLists.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
add_subdirectory(ALG_DS)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
OAISIM Security Algorithms v0.1
|
||||
|
||||
Dependencies:
|
||||
- nettle >= 2.5
|
||||
- openssl >= 1.0.1
|
||||
|
||||
Compilation:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,31 +19,15 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../../../openair3/SECU/kdf.h"
|
||||
|
||||
#include <nettle/hmac.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#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; i<n; i++) {
|
||||
for (i = 0; i < n; i++) {
|
||||
KS[i] = hton_int32(KS[i]);
|
||||
}
|
||||
|
||||
/* Exclusive-OR the input data with keystream to generate the output bit
|
||||
stream */
|
||||
for (i=0; i<n*4; i++) {
|
||||
stream_cipher->message[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;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -26,12 +27,9 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#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<D-2; i++) {
|
||||
V = EVAL ^ ( (uint64_t)hton_int32(message[2*i]) << 32 | (uint64_t)hton_int32(message[2*i+1]) );
|
||||
EVAL = OSA_MUL64(V,P,c);
|
||||
//printf ("Mi: %16X %16X\tEVAL: %16lX\n",hton_int32(message[2*i]),hton_int32(message[2*i+1]), EVAL);
|
||||
for (i = 0; i < D - 2; i++) {
|
||||
V = EVAL ^ ((uint64_t)hton_int32(message[2 * i]) << 32 | (uint64_t)hton_int32(message[2 * i + 1]));
|
||||
EVAL = OSA_MUL64(V, P, c);
|
||||
// printf ("Mi: %16X %16X\tEVAL: %16lX\n",hton_int32(message[2*i]),hton_int32(message[2*i+1]), EVAL);
|
||||
}
|
||||
|
||||
/* for D-2 */
|
||||
@@ -197,23 +194,22 @@ int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]
|
||||
if (rem_bits == 0)
|
||||
rem_bits = 64;
|
||||
|
||||
mask = osa_mask32bit(rem_bits%32);
|
||||
mask = osa_mask32bit(rem_bits % 32);
|
||||
|
||||
if (rem_bits > 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;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -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}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
|
||||
#include <openair3/SECU/secu_defs.h>
|
||||
#include <openair3/SECU/kdf.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
88
openair3/SECU/aes_128.h
Normal file
88
openair3/SECU/aes_128.h
Normal file
@@ -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 <endian.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 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
|
||||
|
||||
254
openair3/SECU/aes_128_cbc_cmac.c
Normal file
254
openair3/SECU/aes_128_cbc_cmac.c
Normal file
@@ -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 <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "aes_128_cbc_cmac.h"
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
// code for version 3.0 or greater
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
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
|
||||
|
||||
48
openair3/SECU/aes_128_cbc_cmac.h
Normal file
48
openair3/SECU/aes_128_cbc_cmac.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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
|
||||
|
||||
62
openair3/SECU/aes_128_ctr.c
Normal file
62
openair3/SECU/aes_128_ctr.c
Normal file
@@ -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 <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
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);
|
||||
}
|
||||
33
openair3/SECU/aes_128_ctr.h
Normal file
33
openair3/SECU/aes_128_ctr.h
Normal file
@@ -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 <endian.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void aes_128_ctr(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]);
|
||||
|
||||
#endif
|
||||
@@ -19,87 +19,18 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include "common/utils/assertions.h"
|
||||
#include "openair3/SECU/sha_256_hmac.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/hmac.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
34
openair3/SECU/kdf.h
Normal file
34
openair3/SECU/kdf.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "byte_array.h"
|
||||
|
||||
void kdf(const uint8_t key[32], byte_array_t data, size_t len, uint8_t out[len]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "secu_defs.h"
|
||||
|
||||
@@ -19,84 +19,40 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -26,15 +27,8 @@
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
// test
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
96
openair3/SECU/secu_defs.c
Normal file
96
openair3/SECU/secu_defs.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "security_types.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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,
|
||||
|
||||
95
openair3/SECU/sha_256_hmac.c
Normal file
95
openair3/SECU/sha_256_hmac.c
Normal file
@@ -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 <openssl/hmac.h>
|
||||
|
||||
#if OPENSSL_VERSION_MAJOR >= 3
|
||||
// code for version 3.0 or greater
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
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
|
||||
33
openair3/SECU/sha_256_hmac.h
Normal file
33
openair3/SECU/sha_256_hmac.h
Normal file
@@ -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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
265
openair3/TEST/test_aes128_ctr.c
Normal file
265
openair3/TEST/test_aes128_ctr.c
Normal file
@@ -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 <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test_util.h"
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
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"));
|
||||
}
|
||||
@@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "test_util.h"
|
||||
|
||||
#include "secu_defs.h"
|
||||
|
||||
#include <nettle/nettle-meta.h>
|
||||
#include <nettle/aes.h>
|
||||
#include <nettle/ctr.h>
|
||||
|
||||
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"));
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user