From 93550b1cb084fe4bfe992525101b8a5374a45578 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 21 Sep 2020 15:11:02 +0200 Subject: [PATCH] add test code, finished authentication --- .../gnb.band78.tm1.fr1.106PRB.usrpb210.conf | 6 +- cmake_targets/CMakeLists.txt | 29 ++- executables/nr-uesoftmodem.c | 12 - openair3/NAS/COMMON/NR_NAS_defs.h | 223 +++++++++++------- openair3/NAS/COMMON/nr_common.c | 44 ++++ openair3/NAS/NR_UE/nr_user_def.h | 14 -- openair3/NAS/NR_UE/ue_process_nas.c | 66 ++---- openair3/NAS/gNB/network_process_nas.c | 60 ++++- openair3/NAS/gNB/network_process_nas.h | 16 -- openair3/TEST/test5Gnas.c | 34 +++ openair3/UICC/usim_interface.c | 52 ++-- openair3/UICC/usim_interface.h | 14 ++ 12 files changed, 355 insertions(+), 215 deletions(-) create mode 100644 openair3/NAS/COMMON/nr_common.c delete mode 100644 openair3/NAS/NR_UE/nr_user_def.h delete mode 100644 openair3/NAS/gNB/network_process_nas.h create mode 100644 openair3/TEST/test5Gnas.c diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 92af74c300..a2d3d1d63c 100755 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -275,7 +275,7 @@ THREAD_STRUCT = ( { global_log_level ="info"; global_log_verbosity ="medium"; - hw_log_level ="info"; + hw_log_level ="debug"; hw_log_verbosity ="medium"; phy_log_level ="info"; phy_log_verbosity ="medium"; @@ -288,4 +288,6 @@ THREAD_STRUCT = ( rrc_log_level ="info"; rrc_log_verbosity ="medium"; }; - +uicc: { +opc = "testopc"; +}; diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c07ab4da7e..3446749f22 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1201,6 +1201,7 @@ set(SECU_OSA_SRC ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c ) add_library(SECU_OSA ${SECU_OSA_SRC}) +target_link_libraries(SECU_OSA ${NETTLE_LIBRARIES}) set(SECU_CN_SRC ${OPENAIR3_DIR}/SECU/kdf.c @@ -1214,6 +1215,8 @@ set(SECU_CN_SRC ) add_library(SECU_CN ${SECU_CN_SRC}) +target_link_libraries(SECU_CN ${NETTLE_LIBRARIES}) + # Physical Channel Procedures Scheduling ################################" set(SCHED_SRC @@ -2269,10 +2272,12 @@ set (SHLIB_LOADER_SOURCES ) add_library(LIB_5GNAS_GNB + ${NAS_SRC}/COMMON/nr_common.c ${NAS_SRC}/gNB/network_process_nas.c ${NAS_SRC}/NR_UE/ue_process_nas.c ${OPENAIR3_DIR}//UICC/usim_interface.c ) +target_link_libraries(LIB_5GNAS_GNB SECU_CN) # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake @@ -2563,6 +2568,12 @@ add_executable(measurement_display ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) target_link_libraries (measurement_display minimal_lib) +add_executable(test5Gnas + ${OPENAIR_DIR}/openair3/TEST/test5Gnas.c +) +target_link_libraries (test5Gnas LIB_5GNAS_GNB CONFIG_LIB minimal_lib) + + # lte-softmodem is both eNB and UE implementation ################################################### @@ -2604,7 +2615,7 @@ target_link_libraries (lte-softmodem -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem ${T_LIB}) @@ -2643,7 +2654,7 @@ target_link_libraries (ocp-enb PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} -Wl,--end-group z dl) -target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) +target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB}) add_executable(cu_test ${OPENAIR2_DIR}/LAYER2/PROTO_AGENT/cu_test.c @@ -2715,7 +2726,7 @@ target_link_libraries (lte-uesoftmodem -Wl,--end-group z dl) target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-uesoftmodem ${T_LIB}) @@ -2757,7 +2768,7 @@ target_link_libraries (nr-softmodem -Wl,--end-group z dl) target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-softmodem ${T_LIB}) @@ -2797,7 +2808,7 @@ target_link_libraries (ocp-gnb -Wl,--end-group z dl) target_link_libraries (ocp-gnb ${LIBXML2_LIBRARIES}) -target_link_libraries (ocp-gnb pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (ocp-gnb pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (ocp-gnb ${LIB_LMS_LIBRARIES}) target_link_libraries (ocp-gnb ${T_LIB}) add_dependencies(ocp-gnb ldpc_orig ldpc_optim ldpc_optim8seg ldpc params_libconfig rfsimulator oai_usrpdevif rfsimulator nrscope) @@ -2841,7 +2852,7 @@ target_link_libraries (nr-uesoftmodem -Wl,--end-group z dl) target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) +target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES}) target_link_libraries (nr-uesoftmodem ${T_LIB}) @@ -3074,7 +3085,7 @@ add_executable(test_epc_generate_scenario ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario - -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) add_executable(test_epc_play_scenario @@ -3093,7 +3104,7 @@ add_executable(test_epc_play_scenario ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario - -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) @@ -3113,7 +3124,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIB} + -Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB} ) endforeach(myExe) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 7af04ffd45..fa816b506c 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -85,8 +85,6 @@ unsigned short config_frames[4] = {2,9,11,13}; #include #include "executables/softmodem-common.h" #include "executables/thread-common.h" -#include -#include // Raphael : missing pthread_cond_t nfapi_sync_cond; @@ -760,16 +758,6 @@ int main( int argc, char **argv ) { memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); configure_linux(); mlockall(MCL_CURRENT | MCL_FUTURE); - - char * resp; - nr_user_nas_t UErrc={0}; - NRUEcontext_t UEnas={0}; - int size=identityRequest((void**)&resp, &UEnas); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Request:\n" ); - size=identityResponse((void**)&resp, &UErrc); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Response:\n" ); - size=authenticationRequest((void**)&resp, &UEnas); - log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication request:\n" ); if(IS_SOFTMODEM_DOFORMS) { load_softscope("nr",PHY_vars_UE_g[0][0]); diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index 78939908c3..a84d8db4f8 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -1,3 +1,9 @@ +#ifndef NR_NAS_DEFS_H +#define NR_NAS_DEFS_H + +#include +#include +#include /* TS 24.007 possible L3 formats: TableĀ 11.1: Formats of information elements @@ -11,61 +17,87 @@ TLV-E Type, Length and Value yes yes yes */ +/* Map task id to printable name. */ +typedef struct { + int id; + char text[256]; +} text_info_t; + +static inline const char * idToText(const text_info_t* table, int size, int id) { + for(int i=0; i TS 24.007 typedef enum { SGSsessionmanagementmessages=0x2e, //LTEbox: 0xC0 ??? SGSmobilitymanagementmessages=0x7e, } Extendedprotocoldiscriminator_t; +#define FOREACH_TYPE(TYPE_DEF) \ + TYPE_DEF( Registrationrequest,0x41 )\ +TYPE_DEF( Registrationaccept,0x42 )\ +TYPE_DEF( Registrationcomplete,0x43 )\ +TYPE_DEF( Registrationreject,0x44 )\ +TYPE_DEF( DeregistrationrequestUEoriginating,0x45 )\ +TYPE_DEF( DeregistrationacceptUEoriginating,0x46 )\ +TYPE_DEF( DeregistrationrequestUEterminated,0x47 )\ +TYPE_DEF( DeregistrationacceptUEterminated,0x48 )\ +TYPE_DEF( Servicerequest,0x4c )\ +TYPE_DEF( Servicereject,0x4d )\ +TYPE_DEF( Serviceaccept,0x4e )\ +TYPE_DEF( Controlplaneservicerequest,0x4f )\ +TYPE_DEF( Networkslicespecificauthenticationcommand,0x50 )\ +TYPE_DEF( Networkslicespecificauthenticationcomplete,0x51 )\ +TYPE_DEF( Networkslicespecificauthenticationresult,0x52 )\ +TYPE_DEF( Configurationupdatecommand,0x54 )\ +TYPE_DEF( Configurationupdatecomplete,0x55 )\ +TYPE_DEF( Authenticationrequest,0x56 )\ +TYPE_DEF( Authenticationresponse,0x57 )\ +TYPE_DEF( Authenticationreject,0x58 )\ +TYPE_DEF( Authenticationfailure,0x59 )\ +TYPE_DEF( Authenticationresult,0x5a )\ +TYPE_DEF( Identityrequest,0x5b )\ +TYPE_DEF( Identityresponse,0x5c )\ +TYPE_DEF( Securitymodecommand,0x5d )\ +TYPE_DEF( Securitymodecomplete,0x5e )\ +TYPE_DEF( Securitymodereject,0x5f )\ +TYPE_DEF( SGMMstatus,0x64 )\ +TYPE_DEF( Notification,0x65 )\ +TYPE_DEF( Notificationresponse,0x66 )\ +TYPE_DEF( ULNAStransport,0x67 )\ +TYPE_DEF( DLNAStransport,0x68 )\ +TYPE_DEF( PDUsessionestablishmentrequest,0xc1 )\ +TYPE_DEF( PDUsessionestablishmentaccept,0xc2 )\ +TYPE_DEF( PDUsessionestablishmentreject,0xc3 )\ +TYPE_DEF( PDUsessionauthenticationcommand,0xc5 )\ +TYPE_DEF( PDUsessionauthenticationcomplete,0xc6 )\ +TYPE_DEF( PDUsessionauthenticationresult,0xc7 )\ +TYPE_DEF( PDUsessionmodificationrequest,0xc9 )\ +TYPE_DEF( PDUsessionmodificationreject,0xca )\ +TYPE_DEF( PDUsessionmodificationcommand,0xcb )\ +TYPE_DEF( PDUsessionmodificationcomplete,0xcc )\ +TYPE_DEF( PDUsessionmodificationcommandreject,0xcd )\ +TYPE_DEF( PDUsessionreleaserequest,0xd1 )\ +TYPE_DEF( PDUsessionreleasereject,0xd2 )\ +TYPE_DEF( PDUsessionreleasecommand,0xd3 )\ +TYPE_DEF( PDUsessionreleasecomplete,0xd4 )\ +TYPE_DEF( SGSMstatus,0xd6 )\ + +static const text_info_t message_text_info[] = { + FOREACH_TYPE(TO_TEXT) +}; + +//! Tasks id of each task typedef enum { - Registrationrequest=0x41, - Registrationaccept=0x42, - Registrationcomplete=0x43, - Registrationreject=0x44, - DeregistrationrequestUEoriginating=0x45, - DeregistrationacceptUEoriginating=0x46, - DeregistrationrequestUEterminated=0x47, - DeregistrationacceptUEterminated=0x48, - Servicerequest=0x4c, - Servicereject=0x4d, - Serviceaccept=0x4e, - Controlplaneservicerequest=0x4f, - Networkslicespecificauthenticationcommand=0x50, - Networkslicespecificauthenticationcomplete=0x51, - Networkslicespecificauthenticationresult=0x52, - Configurationupdatecommand=0x54, - Configurationupdatecomplete=0x55, - Authenticationrequest=0x56, - Authenticationresponse=0x57, - Authenticationreject=0x58, - Authenticationfailure=0x59, - Authenticationresult=0x5a, - Identityrequest=0x5b, - Identityresponse=0x5c, - Securitymodecommand=0x5d, - Securitymodecomplete=0x5e, - Securitymodereject=0x5f, - SGMMstatus=0x64, - Notification=0x65, - Notificationresponse=0x66, - ULNAStransport=0x67, - DLNAStransport=0x68, - PDUsessionestablishmentrequest=0xc1, - PDUsessionestablishmentaccept=0xc2, - PDUsessionestablishmentreject=0xc3, - PDUsessionauthenticationcommand=0xc5, - PDUsessionauthenticationcomplete=0xc6, - PDUsessionauthenticationresult=0xc7, - PDUsessionmodificationrequest=0xc9, - PDUsessionmodificationreject=0xca, - PDUsessionmodificationcommand=0xcb, - PDUsessionmodificationcomplete=0xcc, - PDUsessionmodificationcommandreject=0xcd, - PDUsessionreleaserequest=0xd1, - PDUsessionreleasereject=0xd2, - PDUsessionreleasecommand=0xd3, - PDUsessionreleasecomplete=0xd4, - SGSMstatus=0xd6, + FOREACH_TYPE(TO_ENUM) } SGSmobilitymanagementmessages_t; // TS 24.501 @@ -134,24 +166,19 @@ typedef enum { CAUSE_DEF(Protocol_error_unspecified,0x67 ) /* Map task id to printable name. */ -typedef struct { - int id; - char text[256]; -} cause_text_info_t; + #define CAUSE_TEXT(LabEl, nUmID) {nUmID, #LabEl}, -static const cause_text_info_t cause_text_info[] = { - FOREACH_CAUSE(CAUSE_TEXT) +static const text_info_t cause_text_info[] = { + FOREACH_CAUSE(TO_TEXT) }; #define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID, //! Tasks id of each task typedef enum { - FOREACH_CAUSE(CAUSE_ENUM) + FOREACH_CAUSE(TO_ENUM) } cause_id_t; - - //_table_9.11.4.2.1:_5GSM_cause_information_element #define FOREACH_CAUSE_SECU(CAUSE_SECU_DEF) \ CAUSE_SECU_DEF(Security_Operator_determined_barring,0x08 )\ @@ -198,22 +225,21 @@ typedef enum { CAUSE_SECU_DEF(Security_Message_not_compatible_with_the_protocol_state,0x65 )\ CAUSE_SECU_DEF(Security_Protocol_error_unspecified,0x6f ) -static const cause_text_info_t cause_secu_text_info[] = { - FOREACH_CAUSE_SECU(CAUSE_TEXT) +static const text_info_t cause_secu_text_info[] = { + FOREACH_CAUSE_SECU(TO_TEXT) }; - + +//! Tasks id of each task +typedef enum { + FOREACH_CAUSE_SECU(TO_ENUM) +} cause_secu_id_t; + // IEI (information element identifier) are spread in each message definition #define IEI_RAND 0x21 #define IEI_AUTN 0x20 #define IEI_EAP 0x78 #define IEI_AuthenticationResponse 0x2d -#define CAUSE_ENUM(LabEl, nUmID ) LabEl = nUmID, -//! Tasks id of each task -typedef enum { - FOREACH_CAUSE_SECU(CAUSE_ENUM) -} cause_secu_id_t; - //TS 24.501 sub layer states for UE // for network side, only 5GMMderegistered, 5GMMderegistered_initiated, 5GMMregistered, 5GMMservice_request_initiated are valid typedef enum { @@ -250,20 +276,20 @@ Identityresponse_t; typedef struct __attribute__((packed)) { Identityresponse_t common; identitytype_t mi:8; - int supiFormat:4; - int identityType:4; - int mcc1:4; - int mcc2:4; - int mcc3:4; - int mnc3:4; - int mnc2:4; - int mnc1:4; - int routing1:4; - int routing2:4; - int routing3:4; - int routing4:4; - int protectScheme:4; - int spare:4; + unsigned int supiFormat:4; + unsigned int identityType:4; + unsigned int mcc1:4; + unsigned int mcc2:4; + unsigned int mcc3:4; + unsigned int mnc3:4; + unsigned int mnc1:4; + unsigned int mnc2:4; + unsigned int routing1:4; + unsigned int routing2:4; + unsigned int routing3:4; + unsigned int routing4:4; + unsigned int protectScheme:4; + unsigned int spare:4; uint8_t hplmnId; } IdentityresponseIMSI_t; @@ -272,10 +298,10 @@ typedef struct __attribute__((packed)) { Extendedprotocoldiscriminator_t epd:8; Security_header_t sh:8; SGSmobilitymanagementmessages_t mt:8; - int ngKSI:4; - int spare:4; - int ABBALen:8; - int ABBA:16; + unsigned int ngKSI:4; + unsigned int spare:4; + unsigned int ABBALen:8; + unsigned int ABBA:16; uint8_t ieiRAND; uint8_t RAND[16]; uint8_t ieiAUTN; @@ -293,6 +319,31 @@ typedef struct { uint8_t RES[16]; } authenticationresponse_t; - - //AUTHENTICATION RESULT + + +typedef struct { + uicc_t *uicc; +} nr_user_nas_t; + +#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed") +#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1); +#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO)) +int resToresStar(uint8_t *msg, uicc_t* uicc); + +int identityResponse(void **msg, nr_user_nas_t *UE); +int authenticationResponse(void **msg, nr_user_nas_t *UE); +void UEprocessNAS(void *msg,nr_user_nas_t *UE); +void SGSabortUE(void *msg, NRUEcontext_t *UE) ; +void SGSregistrationReq(void *msg, NRUEcontext_t *UE); +void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE); +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE); +void SGSidentityResp(void *msg, NRUEcontext_t *UE); +void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE); +void SGSregistrationComplete(void *msg, NRUEcontext_t *UE); +void processNAS(void *msg, NRUEcontext_t *UE); +int identityRequest(void **msg, NRUEcontext_t *UE); +int authenticationRequest(void **msg, NRUEcontext_t *UE); +int securityModeCommand(void **msg, NRUEcontext_t *UE); + +#endif diff --git a/openair3/NAS/COMMON/nr_common.c b/openair3/NAS/COMMON/nr_common.c new file mode 100644 index 0000000000..9f5ff1d8ac --- /dev/null +++ b/openair3/NAS/COMMON/nr_common.c @@ -0,0 +1,44 @@ + +#include +#include + +void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size) { + //SNN-network-identifier in TS 24.501 + // TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning. + const char *format="5G:mnc000.mcc000.3gppnetwork.org"; + memcpy(msg,format, strlen(format)); + + if (nmc_size == 2) + memcpy(msg+7, imsiStr+3, 2); + else + memcpy(msg+6, imsiStr+3, 3); + + memcpy(msg+13, imsiStr, 3); +} + +int resToresStar(uint8_t *msg, uicc_t* uicc) { + // TS 33.220 annex B.2 => FC=0x6B in TS 33.501 annex A.4 + //input S to KDF + uint8_t S[128]= {0}; + S[0]=0x6B; + uint8_t *ptr=S+1; + servingNetworkName(ptr, uicc->imsiStr, uicc->nmc_size); + *(uint16_t *)(ptr+strlen((char *)ptr))=htons(strlen((char *)ptr)); + ptr+=strlen((char *)ptr)+sizeof(uint16_t); + // add rand + memcpy(ptr, uicc->rand, sizeof(uicc->rand) ) ; + *(uint16_t *)(ptr+sizeof(uicc->rand))=htons(sizeof(uicc->rand)); + ptr+=sizeof(uicc->rand)+sizeof(uint16_t); + // add res + memcpy(ptr, uicc->milenage_res, sizeof(uicc->milenage_res) ) ; + *(uint16_t *)(ptr+sizeof(uicc->milenage_res))=htons(sizeof(uicc->milenage_res)); + ptr+=sizeof(uicc->milenage_res)+sizeof(uint16_t); + // S is done + 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)); + memcpy(msg, out+16, 16); + return 16; +} diff --git a/openair3/NAS/NR_UE/nr_user_def.h b/openair3/NAS/NR_UE/nr_user_def.h deleted file mode 100644 index 62658a86a7..0000000000 --- a/openair3/NAS/NR_UE/nr_user_def.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef NR_USER_DEF_H -#define NR_USER_DEF_H -#include - -typedef struct { - uicc_t *uicc; -} nr_user_nas_t; - -#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed") -#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1); -#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO)) - -int identityResponse(void **msg, nr_user_nas_t *UE); -#endif diff --git a/openair3/NAS/NR_UE/ue_process_nas.c b/openair3/NAS/NR_UE/ue_process_nas.c index 88ab9456d3..74eba3e6df 100644 --- a/openair3/NAS/NR_UE/ue_process_nas.c +++ b/openair3/NAS/NR_UE/ue_process_nas.c @@ -1,46 +1,11 @@ -#include -#include -#include +#include +#include -void servingNetworkName(uint8_t * msg,nr_user_nas_t *UE) { - //SNN-network-identifier in TS 24.501 - // TS 24.501: If the MNC of the serving PLMN has two digits, then a zero is added at the beginning. - const char * format="5G:mnc000.mcc000.3gppnetwork.org"; - memcpy(msg,format, strlen(format)); - if (UE->uicc->nmc_size == 2) - memcpy(msg+7, UE->uicc->imsiStr+3, 2); - else - memcpy(msg+6, UE->uicc->imsiStr+3, 3); - memcpy(msg+13, UE->uicc->imsiStr, 3); -} - -xresToxresStar(uint8_t * msg),nr_user_nas_t *UE { - // TS 33.220 annex B.2 => FC=0x6B in TS 33.501 annex A.4 - //input S to KDF - uint8_t S[64]={0}; - S[0]=0x6B; - servingNetworkName(S+1, UE); - *(uint16_t*)(msg+strlen(msg))=htons(strlen(msg)); - msg+=strlen(msg)+sizeof(uint16_t); - // add rand - memcpy(msg, UE->uicc->rand, sizeof(UE->uicc->rand) ) ; - *(uint16_t*)(msg+sizeof(UE->uicc->rand))=htons(sizeof(UE->uicc->rand)); - msg+=sizeof(UE->uicc->rand)+sizeof(uint16_t); - msg+=strlen(msg)+sizeof(uint16_t); - // add xres - memcpy(msg, UE->uicc->xres, sizeof(UE->uicc->xres) ) ; - *(uint16_t*)(msg+sizeof(UE->uicc->xres))=htons(sizeof(UE->uicc->xres)); - msg+=sizeof(UE->uicc->xres)+sizeof(uint16_t); - // S is done - - - -} void SGSabortNet(void *msg, nr_user_nas_t *UE) { } -void nas_schedule(void) { +void ue_nas_schedule(void) { } /* @@ -54,7 +19,7 @@ void SGSauthenticationReq(void *msg, nr_user_nas_t *UE) { // AUTHENTICATION REQUEST message that contains a valid ngKSI, SQN and MAC is received // TBD verify ngKSI (we set it as '2', see gNB code) // SQN and MAC are tested in auth resp processing - nas_schedule(); + ue_nas_schedule(); } void SGSidentityReq(void *msg, nr_user_nas_t *UE) { @@ -62,7 +27,7 @@ void SGSidentityReq(void *msg, nr_user_nas_t *UE) { if (idmsg->it == SUCI ) { LOG_I(NAS,"Received Identity request, scheduling answer\n"); - nas_schedule(); + ue_nas_schedule(); } else LOG_E(NAS,"Not developped: identity request for %d\n", idmsg->it); } @@ -79,6 +44,8 @@ void UEprocessNAS(void *msg,nr_user_nas_t *UE) { else { switch (header->epd) { case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + switch (header->mt) { case Authenticationrequest: SGSauthenticationReq(msg, UE); @@ -154,7 +121,7 @@ int authenticationResponse(void **msg,nr_user_nas_t *UE) { if (UE->uicc == NULL) // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE UE->uicc=init_uicc("uicc"); - + myCalloc(resp, authenticationresponse_t); resp->epd=SGSmobilitymanagementmessages; resp->sh=0; @@ -162,17 +129,20 @@ int authenticationResponse(void **msg,nr_user_nas_t *UE) { resp->iei=IEI_AuthenticationResponse; resp->RESlen=sizeof(resp->RES); // always 16 see TS 24.501 TableĀ 8.2.2.1.1 // Verify the AUTN - uint8_t ik[16], ck[16], res[8], AUTN[16]; - milenage_generate(UE->uicc->opc, UE->uicc->amf, UE->uicc->key, - UE->uicc->sqn, UE->uicc->rand, AUTN, ik, ck, res); + // a full implementation need to test several SQN + // as the last 5bits can be any value + // and the value can also be greater and accepted (if it is in the accepted window) + uint8_t AUTN[16]; + uicc_milenage_generate(AUTN, UE->uicc); - - if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) ) { + if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) == 0 ) { // prepare and send good answer - + resToresStar(resp->RES,UE->uicc); } else { - // prepare and send autn is not compatible with us + // prepare and send autn is not compatible with our data + abort(); } + *msg=resp; return sizeof(authenticationresponse_t); } diff --git a/openair3/NAS/gNB/network_process_nas.c b/openair3/NAS/gNB/network_process_nas.c index dbb024298b..bdfa2183d6 100644 --- a/openair3/NAS/gNB/network_process_nas.c +++ b/openair3/NAS/gNB/network_process_nas.c @@ -1,11 +1,9 @@ -#include -#include -#include +#include void SGSabortUE(void *msg, NRUEcontext_t *UE) { } - - +void nas_schedule(void) { +} /* *Message reception */ @@ -16,10 +14,48 @@ void SGSregistrationReq(void *msg, NRUEcontext_t *UE) { void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE) { } -void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) { +void SGSidentityResp(void *msg, NRUEcontext_t *UE) { + // use the UE SUPI to load the USIM + IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *)msg; + char configName[100]={0}; + char * ptr= stpcpy(configName,"uicc"); + *ptr++=resp->mcc1+'0'; + *ptr++=resp->mcc2+'0'; + *ptr++=resp->mcc3+'0'; + *ptr++=resp->mnc1+'0'; + *ptr++=resp->mnc2+'0'; + if ( resp->mnc3 != 0xF ) + *ptr++=resp->mnc3 +'0'; + int respSize=ntohs(resp->common.len); + int msinByteSize=respSize-sizeof(IdentityresponseIMSI_t); + uint8_t * msin=(uint8_t *) (resp+1); + for(int i=3 ; i> 4) ; + *ptr++=(msin[i] & 0xf) +'0'; + if (digit1 != 0xf) + *ptr++=digit1 +'0'; + } + *ptr=0; + if (UE->uicc == NULL) + // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE + UE->uicc=init_uicc(configName); + //We schedule Authentication request + nas_schedule(); } -void SGSidentityResp(void *msg, NRUEcontext_t *UE) { +void SGSauthenticationResp(void *msg, NRUEcontext_t *UE) { + // Let's check the answer + authenticationresponse_t* resp=(authenticationresponse_t*) msg; + uint8_t resStarLocal[16]; + resToresStar(resStarLocal,UE->uicc); + if ( memcmp(resStarLocal, resp->RES, sizeof(resStarLocal)) == 0 ) { + LOG_I(NAS,"UE answer to authentication resquest is correct\n"); + // we will send securityModeCommand + nas_schedule(); + } else { + LOG_E(NAS,"UE authentication response not good\n"); + // To be implemented ? + } } void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE) { @@ -36,6 +72,8 @@ void processNAS(void *msg, NRUEcontext_t *UE) { else { switch (header->epd) { case SGSmobilitymanagementmessages: + LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt)); + switch (header->mt) { case Registrationrequest: SGSregistrationReq(msg, UE); @@ -92,9 +130,6 @@ int identityRequest(void **msg, NRUEcontext_t *UE) { } int authenticationRequest(void **msg, NRUEcontext_t *UE) { - if (UE->uicc == NULL) - // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE - UE->uicc=init_uicc("uicc"); myCalloc(req, authenticationrequestHeader_t); req->epd=SGSmobilitymanagementmessages; @@ -123,12 +158,11 @@ int authenticationRequest(void **msg, NRUEcontext_t *UE) { LOG_E(NAS, "can't read /dev/random\n"); fclose(h); + memcpy(UE->uicc->rand, req->RAND, sizeof(UE->uicc->rand)); // challenge/AUTN (TLV) req->ieiAUTN=IEI_AUTN; req->AUTNlen=sizeof(req->AUTN); - uint8_t ik[16], ck[16], res[8]; - milenage_generate(UE->uicc->opc, UE->uicc->amf, UE->uicc->key, - UE->uicc->sqn, req->RAND, req->AUTN, ik, ck, res); + uicc_milenage_generate( req->AUTN, UE->uicc); // EAP message (TLV-E) // not developped *msg=req; diff --git a/openair3/NAS/gNB/network_process_nas.h b/openair3/NAS/gNB/network_process_nas.h deleted file mode 100644 index 8bb4ea4e20..0000000000 --- a/openair3/NAS/gNB/network_process_nas.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NET_PROCESS_NAS_H -#define NET_PROCESS_NAS_H -#include - -void SGSabortUE(void *msg, NRUEcontext_t *UE) ; -void SGSregistrationReq(void *msg, NRUEcontext_t *UE); -void SGSderegistrationUEReq(void *msg, NRUEcontext_t *UE); -void SGSauthenticationResp(void *msg, NRUEcontext_t *UE); -void SGSidentityResp(void *msg, NRUEcontext_t *UE); -void SGSsecurityModeComplete(void *msg, NRUEcontext_t *UE); -void SGSregistrationComplete(void *msg, NRUEcontext_t *UE); -void processNAS(void *msg, NRUEcontext_t *UE); -int identityRequest(void **msg, NRUEcontext_t *UE); -int authenticationRequest(void **msg, NRUEcontext_t *UE); -int securityModeCommand(void **msg, NRUEcontext_t *UE); -#endif diff --git a/openair3/TEST/test5Gnas.c b/openair3/TEST/test5Gnas.c new file mode 100644 index 0000000000..5124ad6e4d --- /dev/null +++ b/openair3/TEST/test5Gnas.c @@ -0,0 +1,34 @@ +#include +#include + +volatile int oai_exit; + +int main(int argc, char **argv) { + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + + logInit(); + char *resp; + nr_user_nas_t UErrc= {0}; + NRUEcontext_t UEnas= {0}; + // Network generate identity request after a sucessfull radio attach + int size=identityRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Request:\n" ); + // UE process the message that it has received from phy layer in a "DL transfer" message + UEprocessNAS(resp, &UErrc); + // UE Scheduler should later call the response + size=identityResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," identity Response:\n" ); + // Now the gNB process the identity response + processNAS(resp, &UEnas); + // gNB scheduler should call the next query + size=authenticationRequest((void **)&resp, &UEnas); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication request:\n" ); + // as above + UEprocessNAS(resp, &UErrc); + size=authenticationResponse((void **)&resp, &UErrc); + log_dump(NAS, resp, size, LOG_DUMP_CHAR," authentication response:\n" ); + processNAS(resp, &UEnas); + return 0; +} diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c index 7076b284e6..15a4e2e540 100644 --- a/openair3/UICC/usim_interface.c +++ b/openair3/UICC/usim_interface.c @@ -22,6 +22,7 @@ */ #include +#include #define UICC_SECTION "uicc" #define UICC_CONFIG_HELP_OPTIONS " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\ @@ -42,29 +43,50 @@ }; const char *hexTable="0123456789abcdef"; -static inline void to_hex(char *in, uint8_t *out, bool swap) { - if (swap) - for (size_t i=0; in[i]!=0; i++) { - out+=hexTable[in[i] & 0xf]; - out+=hexTable[in[i]>>4 & 0xf]; - } else { - for (size_t i=0; in[i]!=0; i++) { - out+=hexTable[in[i]>>4 & 0xf]; - out+=hexTable[in[i] & 0xf]; - } +static inline uint8_t mkDigit(unsigned char in) { + for (int i=0; i<16; i++) + if (in==hexTable[i]) + return i; + LOG_E(SIM,"Impossible hexa input: %c\n",in); + return 0; +} + +static inline void to_hex(char *in, uint8_t *out, int size) { + for (size_t i=0; in[i]!=0 && i < size*2 ; i+=2) { + *out++=(mkDigit(in[i]) << 4) | mkDigit(in[i+1]); } } uicc_t *init_uicc(char *sectionName) { uicc_t *uicc=(uicc_t *)calloc(sizeof(uicc_t),1); paramdef_t uicc_params[] = UICC_PARAMS_DESC; + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + // we can read the IMSI from the USIM + // key, OPc, sqn, amf don't need to be read from the true USIM int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName); AssertFatal(ret >= 0, "configuration couldn't be performed"); - LOG_I(HW, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr); - to_hex(uicc->keyStr,uicc->key, false); - to_hex(uicc->opcStr,uicc->opc, false); - to_hex(uicc->sqnStr,uicc->sqn, false); - to_hex(uicc->amfStr,uicc->amf, false); + LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr); + to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) ); + to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) ); + to_hex(uicc->sqnStr,uicc->sqn, sizeof(uicc->sqn) ); + to_hex(uicc->amfStr,uicc->amf, sizeof(uicc->amf) ); return uicc; } +void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) { + // here we call usim simulation, but calling actual usim is quite simple + // the code is in open-cells.com => program_uicc open source + milenage_generate(uicc->opc, uicc->amf, uicc->key, + uicc->sqn, uicc->rand, autn, uicc->ik, uicc->ck, uicc->milenage_res); + log_dump(SIM,uicc->opc,sizeof(uicc->opc), LOG_DUMP_CHAR,"opc:"); + log_dump(SIM,uicc->amf,sizeof(uicc->amf), LOG_DUMP_CHAR,"amf:"); + log_dump(SIM,uicc->key,sizeof(uicc->key), LOG_DUMP_CHAR,"key:"); + log_dump(SIM,uicc->sqn,sizeof(uicc->sqn), LOG_DUMP_CHAR,"sqn:"); + log_dump(SIM,uicc->rand,sizeof(uicc->rand), LOG_DUMP_CHAR,"rand:"); + log_dump(SIM,uicc->ik,sizeof(uicc->ik), LOG_DUMP_CHAR,"milenage output ik:"); + log_dump(SIM,uicc->ck,sizeof(uicc->ck), LOG_DUMP_CHAR,"milenage output ck:"); + log_dump(SIM,uicc->milenage_res,sizeof(uicc->milenage_res), LOG_DUMP_CHAR,"milenage output res:"); + log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:"); +} + diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h index 5d4ae2e16b..e8f241c1e8 100644 --- a/openair3/UICC/usim_interface.h +++ b/openair3/UICC/usim_interface.h @@ -35,6 +35,14 @@ #include #include "common_lib.h" +/* 3GPP glossary +RES RESponse +XRES eXpected RESponse +HRES Hash RESponse +HXRES Hash eXpected RESponse +So, RES can be either milenage res, or received response, so hash of milenage res +*/ + typedef struct { char *imsiStr; char *keyStr; @@ -48,10 +56,16 @@ typedef struct { int nmc_size; uint8_t rand[16]; uint8_t autn[16]; + uint8_t ak[6]; + uint8_t akstar[6]; + uint8_t ck[16]; + uint8_t ik[16]; + uint8_t milenage_res[8]; } uicc_t; /* * Read the configuration file, section name variable to be able to manage several UICC */ uicc_t *init_uicc(char *sectionName); +void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc); #endif