diff --git a/CMakeLists.txt b/CMakeLists.txt index b0d99e805f..a4a4b94028 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -773,33 +773,25 @@ add_library(UTIL ${OPENAIR_DIR}/common/utils/time_stat.c ) -set(SECU_OSA_SRC - ${OPENAIR2_DIR}/UTIL/OSA/osa_key_deriver.c - ${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_include_directories(SECU_OSA PRIVATE ${OPENAIR_DIR}/common/utils/ds/) - -set(SECU_CN_SRC +set(SECURITY_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/aes_128_ecb.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 + ${OPENAIR3_DIR}/SECU/nas_stream_eea0.c ${OPENAIR3_DIR}/SECU/nas_stream_eea1.c ${OPENAIR3_DIR}/SECU/nas_stream_eia1.c ${OPENAIR3_DIR}/SECU/nas_stream_eea2.c ${OPENAIR3_DIR}/SECU/nas_stream_eia2.c ) -add_library(SECU_CN ${SECU_CN_SRC} $) -target_include_directories(SECU_CN PRIVATE ${OPENAIR_DIR}/common/utils/ds/) +add_library(SECURITY ${SECURITY_SRC} $) +target_include_directories(SECURITY PRIVATE ${OPENAIR_DIR}/common/utils/ds/) # Physical Channel Procedures Scheduling ################################" @@ -1350,8 +1342,8 @@ set(NR_PDCP_SRC #these files should not be here, will be removed at some point when the #computation is done directly inside nr_pdcp_integrity_nia1.c instead #of reusing code of osa_stream_eia.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c - ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c + #${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c + #${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c ) set(NR_SDAP_SRC @@ -1993,7 +1985,7 @@ add_library(LIB_5GNAS_GNB ) 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 SECURITY ${CRYPTO_LIBRARIES}) target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) # Simulation library @@ -2156,7 +2148,7 @@ add_dependencies(lte-softmodem oai_iqplayer) target_link_libraries(lte-softmodem PRIVATE -Wl,--start-group - lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB + lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECURITY UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${NAS_UE_LIB} ITTI SIMU SIMU_ETH -Wl,--end-group z dl) @@ -2165,7 +2157,6 @@ target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYP target_link_libraries(lte-softmodem PRIVATE ${T_LIB}) target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) - add_executable(oairu ${OPENAIR_DIR}/executables/lte-ru.c ${OPENAIR_DIR}/executables/ru_control.c @@ -2218,7 +2209,7 @@ endif() target_link_libraries(lte-uesoftmodem PRIVATE -Wl,--start-group lte_rrc nr_rrc s1ap x2ap m2ap m3ap - SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON + SECURITY UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU L2_UE L2_LTE SIMU SIMU_ETH NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${NAS_UE_LIB} ITTI ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -2258,7 +2249,7 @@ add_executable(nr-softmodem target_link_libraries(nr-softmodem PRIVATE -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY ITTI ${NAS_UE_LIB} lte_rrc nr_rrc ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU SIMU_ETH x2ap f1ap m2ap m3ap e1ap @@ -2293,9 +2284,9 @@ add_executable(nr-cuup target_link_libraries(nr-cuup PRIVATE CONFIG_LIB ITTI SCTP_CLIENT GTPV1U e1ap e1_pdcp_if f1ap SIMU_ETH - SECU_OSA SECU_CN ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) + SECURITY ${OPENSSL_LIBRARIES} crypt z sctp dl pthread) target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) - + # nr-uesoftmodem is UE implementation ####################################### @@ -2320,7 +2311,7 @@ add_executable(nr-uesoftmodem target_link_libraries(nr-uesoftmodem PRIVATE -Wl,--start-group - nr_rrc SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB + nr_rrc SECURITY UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_NR_LIB ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} SIMU SIMU_ETH @@ -2464,7 +2455,7 @@ add_executable(nr_dlsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECU_CN ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2513,7 +2504,7 @@ if (ENABLE_LDPC_T1) endif() target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECU_CN ngap -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU SIMU_ETH PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR HASHTABLE x2ap SECURITY ngap -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2552,7 +2543,7 @@ foreach(myExe s1ap ${OPENAIR3_DIR}/TEST/test_${myExe}.c ) target_link_libraries (test_${myExe} - -Wl,--start-group SECU_CN UTIL -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} CONFIG_LIB + -Wl,--start-group SECURITY UTIL -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} CONFIG_LIB ) endforeach(myExe) @@ -2573,7 +2564,7 @@ if (${T_TRACER}) ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap params_libconfig oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer oai_eth_transpro oai_mobipass coding HASHTABLE UTIL OMG_SUMO - SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL + SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1f35072552..c0c8dac7aa 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -98,9 +98,8 @@ nfapi_ue_release_request_body_t release_rntis; instance_t DUuniqInstance=0; instance_t CUuniqInstance=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) +void 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) { - return 0; } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } @@ -124,10 +123,9 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } void processSlotTX(void *arg) {} diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 3f7087afa5..15ef6a1694 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -96,9 +96,8 @@ void deref_sched_response(int _) exit(1); } -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) +void 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) { - return 0; } void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) @@ -120,10 +119,9 @@ int8_t nr_rrc_RA_succeeded(const module_id_t mod_id, const uint8_t gNB_index) { return 0; } -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } nrUE_params_t nrUE_params; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 4ee528a6fc..835ba9ef99 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -94,9 +94,8 @@ nfapi_ue_release_request_body_t release_rntis; instance_t DUuniqInstance=0; instance_t CUuniqInstance=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) +void 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) { - return 0; } extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration @@ -133,10 +132,9 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, nr_bler_struct nr_bler_data[NR_NUM_MCS]; -int nr_derive_key(int alg_type, uint8_t alg_id, - const uint8_t key[32], uint8_t **out) +void nr_derive_key(int alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) { - return 0; + (void)alg_type; } void processSlotTX(void *arg) {} diff --git a/openair2/E1AP/e1ap_api.c b/openair2/E1AP/e1ap_api.c index b67525acca..6bbc827e84 100644 --- a/openair2/E1AP/e1ap_api.c +++ b/openair2/E1AP/e1ap_api.c @@ -23,11 +23,12 @@ #include #include "e1ap_api.h" -#include "UTIL/OSA/osa_defs.h" + #include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include "openair2/RRC/NR/cucp_cuup_if.h" #include "openair2/RRC/LTE/MESSAGES/asn1_msg.h" +#include "openair3/SECU/key_nas_deriver.h" #include "openair3/ocp-gtpu/gtp_itf.h" #include "e1ap_asnc.h" #include "e1ap_common.h" @@ -120,12 +121,12 @@ static int drb_config_N3gtpu_create(e1ap_bearer_setup_req_t * const req, } // Configure DRBs - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; - nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, &kUPenc); + nr_derive_key(UP_ENC_ALG, req->cipheringAlgorithm, (uint8_t *)req->encryptionKey, kUPenc); - nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, &kUPint); + nr_derive_key(UP_INT_ALG, req->integrityProtectionAlgorithm, (uint8_t *)req->integrityProtectionKey, kUPint); nr_pdcp_e1_add_drbs(true, // set this to notify PDCP that his not UE create_tunnel_req.ue_id, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index b7de2ffad4..b52f3fb9b4 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -50,14 +50,13 @@ #include "common/openairinterface5g_limits.h" #include "executables/lte-softmodem.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" -#include "UTIL/OSA/osa_defs.h" #include "openair2/RRC/NAS/nas_config.h" #include "intertask_interface.h" #include "openair3/S1AP/s1ap_eNB.h" #include #include "pdcp.h" -# include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair3/ocp-gtpu/gtp_itf.h" #include #include "ENB_APP/enb_config.h" @@ -2028,19 +2027,6 @@ pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, // pdcp_remove_UE(ctxt_pP); } - /* Security keys */ - if (pdcp_pP->kUPenc != NULL) { - free(pdcp_pP->kUPenc); - } - - if (pdcp_pP->kRRCint != NULL) { - free(pdcp_pP->kRRCint); - } - - if (pdcp_pP->kRRCenc != NULL) { - free(pdcp_pP->kRRCenc); - } - memset(pdcp_pP, 0, sizeof(pdcp_t)); break; @@ -2105,9 +2091,11 @@ pdcp_config_set_security( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), pdcp_pP->cipheringAlgorithm, pdcp_pP->integrityProtAlgorithm); - pdcp_pP->kRRCenc = kRRCenc; - pdcp_pP->kRRCint = kRRCint; - pdcp_pP->kUPenc = kUPenc; + + kRRCenc != NULL ? memcpy(pdcp_pP->kRRCenc, kRRCenc, 32) : memset(pdcp_pP->kRRCenc, 0, 32); + kRRCint != NULL ? memcpy(pdcp_pP->kRRCint, kRRCint, 32) : memset(pdcp_pP->kRRCint, 0, 32); + kUPenc != NULL ? memcpy(pdcp_pP->kUPenc, kUPenc, 32) : memset(pdcp_pP->kUPenc, 0, 32); + /* Activate security */ pdcp_pP->security_activated = 1; } @@ -2328,18 +2316,6 @@ pdcp_free ( pdcp_t *pdcp_p = (pdcp_t *)pdcp_pP; if (pdcp_p != NULL) { - if (pdcp_p->kUPenc != NULL) { - free(pdcp_p->kUPenc); - } - - if (pdcp_p->kRRCint != NULL) { - free(pdcp_p->kRRCint); - } - - if (pdcp_p->kRRCenc != NULL) { - free(pdcp_p->kRRCenc); - } - memset(pdcp_pP, 0, sizeof(pdcp_t)); free(pdcp_pP); } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 043ac7fb4a..9f4cdefb3b 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -45,6 +45,7 @@ #include "LTE_MBMS-SessionInfoList-r9.h" #include "LTE_PMCH-InfoList-r9.h" +#include "openair3/SECU/secu_defs.h" typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *const, const srb_flag_t, const MBMS_flag_t, @@ -161,17 +162,17 @@ typedef struct pdcp_s { bool is_srb; /* Configured security algorithms */ - uint8_t cipheringAlgorithm; - uint8_t integrityProtAlgorithm; + eea_alg_id_e cipheringAlgorithm; + eia_alg_id_e integrityProtAlgorithm; /* User-Plane encryption key * Control-Plane RRC encryption key * Control-Plane RRC integrity key * These keys are configured by RRC layer */ - uint8_t *kUPenc; - uint8_t *kRRCint; - uint8_t *kRRCenc; + uint8_t kUPenc[32]; + uint8_t kRRCint[32]; + uint8_t kRRCenc[32]; uint8_t security_activated; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 6664dd2a33..a88d4028ae 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -30,7 +30,6 @@ #include "assertions.h" #include "common/utils/LOG/log.h" -#include "UTIL/OSA/osa_defs.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "executables/softmodem-common.h" @@ -39,6 +38,8 @@ #include "pdcp.h" #include "pdcp_primitives.h" +#include "openair3/SECU/secu_defs.h" + //----------------------------------------------------------------------------- static uint32_t pdcp_get_next_count_tx( @@ -110,7 +111,7 @@ pdcp_apply_security( ) { uint8_t *buffer_encrypted = NULL; - stream_cipher_t encrypt_params; + nas_stream_cipher_t encrypt_params = {0}; DevAssert(pdcp_pP != NULL); DevAssert(pdcp_pdu_buffer != NULL); @@ -156,9 +157,7 @@ pdcp_apply_security( buffer_encrypted = &pdcp_pdu_buffer[pdcp_header_len]; /* Apply ciphering if any requested */ - stream_encrypt(pdcp_pP->cipheringAlgorithm, - &encrypt_params, - &buffer_encrypted); + stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &encrypt_params, buffer_encrypted); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY, VCD_FUNCTION_OUT); @@ -180,7 +179,7 @@ pdcp_validate_security( ) { uint8_t *buffer_decrypted = NULL; - stream_cipher_t decrypt_params; + nas_stream_cipher_t decrypt_params = {0}; DevAssert(pdcp_pP != NULL); @@ -199,33 +198,36 @@ pdcp_validate_security( decrypt_params.key_length = 16; if (srb_flagP) { - LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", - rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); + LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kRRCenc;// + 128; } else { - LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", - rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); + LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kUPenc;// + 128; } /* Uncipher the block */ - stream_decrypt(pdcp_pP->cipheringAlgorithm, - &decrypt_params, - &buffer_decrypted); + stream_compute_encrypt(pdcp_pP->cipheringAlgorithm, &decrypt_params, buffer_decrypted); + if (!IS_SOFTMODEM_IQPLAYER) { if (srb_flagP) { - /* Now check the integrity of the complete PDU */ + /* Now check the integrity of the complete PDU */ decrypt_params.message = pdcp_pdu_buffer; decrypt_params.blength = sdu_buffer_size << 3; decrypt_params.key = pdcp_pP->kRRCint + 16;// 128; - if (stream_check_integrity(pdcp_pP->integrityProtAlgorithm, - &decrypt_params, - &pdcp_pdu_buffer[sdu_buffer_size]) != 0) { - LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", - rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); - return -1; + if (pdcp_pP->integrityProtAlgorithm != EIA0_ALG_ID) { + uint8_t result[4] = {0}; + stream_compute_integrity(pdcp_pP->integrityProtAlgorithm, &decrypt_params, result); + + if (memcmp(result, &pdcp_pdu_buffer[sdu_buffer_size], 4) != 0) { + LOG_E(PDCP, + "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + rb_id, + (pdcp_pP->is_ue != 0) ? "UE" : "eNB", + ((long long unsigned int *)decrypt_params.key)[0]); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); + return -1; + } } } } /* !IQPLAYER */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index b102bf3b7f..d56c22f609 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -52,8 +52,4 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, } } else LOG_W(PDCP, "%s with void list\n", __FUNCTION__); - if (kUPenc) - free(kUPenc); - if (kUPint) - free(kUPint); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c index 08ec959937..a005bbbdf6 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c @@ -26,13 +26,12 @@ #include #include -#include "UTIL/OSA/osa_defs.h" - -int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]); +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key) { - stream_cipher_t *ret; + nas_stream_cipher_t *ret; ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort(); ret->key = malloc(16); if (ret->key == NULL) abort(); @@ -47,7 +46,7 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context, unsigned char *buffer, int length, int bearer, int count, int direction) { - stream_cipher_t *ctx = integrity_context; + nas_stream_cipher_t *ctx = integrity_context; ctx->message = buffer; ctx->count = count; @@ -55,12 +54,12 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context, ctx->direction = direction; ctx->blength = length * 8; - stream_compute_integrity_eia1(ctx, out); + stream_compute_integrity(EIA1_128_ALG_ID, ctx, out); } void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context) { - stream_cipher_t *ctx = integrity_context; + nas_stream_cipher_t *ctx = integrity_context; free(ctx->key); free(ctx); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ebd2d17842..0157a3596b 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -920,10 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo } } else LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); - if (kRRCenc) - free(kRRCenc); - if (kRRCint) - free(kRRCint); } void nr_pdcp_add_drbs(eNB_flag_t enb_flag, @@ -941,10 +937,6 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); - if (kUPenc) - free(kUPenc); - if (kUPint) - free(kUPint); } /* Dummy function due to dependency from LTE libraries */ diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9128b0f50e..dc79541624 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -104,7 +104,7 @@ #include "common/ran_context.h" -#include "secu_defs.h" +#include "key_nas_deriver.h" #if !defined (msg) #define msg printf diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 022875bc68..0cdac830d0 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -73,7 +73,7 @@ #include "rrc_UE_ral.h" #endif -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" #include "pdcp.h" #include "plmn_data.h" @@ -1246,12 +1246,11 @@ rrc_ue_process_radioResourceConfigDedicated( // Establish SRBs if present // loop through SRBToAddModList if (radioResourceConfigDedicated->srb_ToAddModList) { - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); - derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + derive_key_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCint); + // Refresh SRBs rrc_pdcp_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, @@ -1397,9 +1396,9 @@ rrc_ue_process_radioResourceConfigDedicated( LOG_I(RRC,"[UE %d] default DRB = %ld\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB); } - uint8_t *kUPenc = NULL; - derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); + uint8_t kUPenc[32] = {0}; + derive_key_nas(UP_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kUPenc); + // Refresh DRBs rrc_pdcp_config_asn1_req(ctxt_pP, (LTE_SRB_ToAddModList_t *)NULL, @@ -1549,9 +1548,9 @@ rrc_ue_process_securityModeCommand( ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure; } - uint8_t *kRRCenc = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kRRCint = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kUPenc[32] = {0}; + uint8_t kRRCint[32] = {0}; pdcp_t *pdcp_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; @@ -1577,12 +1576,10 @@ rrc_ue_process_securityModeCommand( UE_rrc_inst[ctxt_pP->module_id].kenb[20], UE_rrc_inst[ctxt_pP->module_id].kenb[21], UE_rrc_inst[ctxt_pP->module_id].kenb[22], UE_rrc_inst[ctxt_pP->module_id].kenb[23], UE_rrc_inst[ctxt_pP->module_id].kenb[24], UE_rrc_inst[ctxt_pP->module_id].kenb[25], UE_rrc_inst[ctxt_pP->module_id].kenb[26], UE_rrc_inst[ctxt_pP->module_id].kenb[27], UE_rrc_inst[ctxt_pP->module_id].kenb[28], UE_rrc_inst[ctxt_pP->module_id].kenb[29], UE_rrc_inst[ctxt_pP->module_id].kenb[30], UE_rrc_inst[ctxt_pP->module_id].kenb[31]); - derive_key_rrc_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCenc); - derive_key_rrc_int(UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kRRCint); - derive_key_up_enc(UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, - UE_rrc_inst[ctxt_pP->module_id].kenb, &kUPenc); + + derive_key_nas(RRC_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kRRCint); + derive_key_nas(UP_ENC_ALG, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm, UE_rrc_inst[ctxt_pP->module_id].kenb, kUPenc); if (securityMode != 0xff) { pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0, diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index c2bf7a82f9..348e1a9fd4 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -44,7 +44,6 @@ #include "RRC/LTE/MESSAGES/asn1_msg.h" #include "LTE_RRCConnectionRequest.h" #include "LTE_RRCConnectionReestablishmentRequest.h" -//#include "ReestablishmentCause.h" #include "LTE_BCCH-BCH-Message.h" #include "LTE_UL-CCCH-Message.h" #include "LTE_DL-CCCH-Message.h" @@ -81,15 +80,14 @@ #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" -#include "UTIL/OSA/osa_defs.h" - #include "rrc_eNB_S1AP.h" #include "rrc_eNB_GTPV1U.h" #include "rrc_eNB_M2AP.h" #include "pdcp.h" +#include "openair3/SECU/key_nas_deriver.h" +#include "openair3/SECU/secu_defs.h" #include "openair3/ocp-gtpu/gtp_itf.h" -#include #include "intertask_interface.h" #include "softmodem-common.h" @@ -114,8 +112,9 @@ mui_t rrc_eNB_mui = 0; extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern int rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, security_capabilities_t *security_capabilities_pP); -extern void process_eNB_security_key (const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *security_key_pP); -extern 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); +extern void process_eNB_security_key(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *security_key_pP); extern int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, rrc_eNB_ue_context_t *ue_context, unsigned char *buffer, int buffer_size, OCTET_STRING_t *scg_group_config, OCTET_STRING_t *scg_RB_config); extern struct rrc_eNB_ue_context_s *get_first_ue_context(eNB_RRC_INST *rrc_instance_pP); @@ -5145,9 +5144,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( int drb_id; int oip_ifup = 0; int dest_ip_offset = 0; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + uint8_t kUPenc[32] = {0}; LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; @@ -5178,17 +5177,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( /* Derive the keys from kenb */ if (DRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kUPenc); + derive_key_nas(UP_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kUPenc); } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCint); + derive_key_nas(RRC_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, kRRCint); /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, SRB_configList, // NULL, diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index bc4fc6d8cd..141a70488e 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -46,12 +46,14 @@ #include "pdcp.h" #include "pdcp_primitives.h" -#include "UTIL/OSA/osa_defs.h" - #include "LTE_UERadioAccessCapabilityInformation.h" #include "openair3/ocp-gtpu/gtp_itf.h" #include + +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "RRC/LTE/rrc_eNB_GTPV1U.h" #include "TLVDecoder.h" @@ -485,9 +487,9 @@ rrc_pdcp_config_security( //------------------------------------------------------------------------------ { LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[32] = {0}; + uint8_t kRRCint[32] = {0}; + uint8_t kUPenc[32] = {0}; pdcp_t *pdcp_p = NULL; static int print_keys= 1; hashtable_rc_t h_rc; @@ -495,19 +497,13 @@ rrc_pdcp_config_security( /* Derive the keys from kenb */ if (SRB_configList != NULL) { - derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kUPenc); + derive_key_nas(UP_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kUPenc); } - derive_key_rrc_enc(ue_context_pP->ue_context.ciphering_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCenc); - derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, - ue_context_pP->ue_context.kenb, - &kRRCint); - if (!IS_SOFTMODEM_IQPLAYER) { - SET_LOG_DUMP(DEBUG_SECURITY) ; + derive_key_nas(RRC_ENC_ALG, ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.kenb, kRRCenc); + derive_key_nas(RRC_INT_ALG, ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, kRRCint); + if (!IS_SOFTMODEM_IQPLAYER) { + SET_LOG_DUMP(DEBUG_SECURITY); } @@ -953,6 +949,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char &ctxt, ue_context_p, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); + { uint8_t send_security_mode_command = true; rrc_pdcp_config_security( diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 51cf52bc63..2221843772 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -46,7 +46,9 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "asn1_msg.h" #include "../nr_rrc_proto.h" -#include "UTIL/OSA/osa_defs.h" + +#include "openair3/SECU/key_nas_deriver.h" + #include "RRC/NR/nr_rrc_extern.h" #include "NR_DL-CCCH-Message.h" #include "NR_UL-CCCH-Message.h" diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index d0d4365e70..fe47aca73b 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -29,7 +29,8 @@ #include "nr_rrc_proto.h" #include "nr_rrc_extern.h" #include "openair2/COMMON/e1ap_messages_types.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" #include @@ -38,6 +39,7 @@ #include "common/ran_context.h" #include "openair2/F1AP/f1ap_common.h" #include "openair2/E1AP/e1ap_common.h" + extern RAN_CONTEXT_t RC; void fill_e1ap_bearer_setup_resp(e1ap_bearer_setup_resp_t *resp, @@ -134,18 +136,19 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(ctxt_p, &create_tunnel_resp, 0); - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); - nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); } - nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); - nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %x\n", UE->rnti); diff --git a/openair2/RRC/NR/cucp_cuup_e1ap.c b/openair2/RRC/NR/cucp_cuup_e1ap.c index eeea7ed3a9..390ab232a7 100644 --- a/openair2/RRC/NR/cucp_cuup_e1ap.c +++ b/openair2/RRC/NR/cucp_cuup_e1ap.c @@ -29,7 +29,8 @@ #include "nr_rrc_extern.h" #include "cucp_cuup_if.h" #include "openair2/COMMON/e1ap_messages_types.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" + #include #include "common/ran_context.h" diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 7941d1642b..ff6ec0180e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -75,7 +75,7 @@ #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" #include "rrc_gNB_NGAP.h" @@ -90,6 +90,7 @@ #include "executables/softmodem-common.h" #include #include +#include #include #include #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h" @@ -1035,31 +1036,30 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *ue_context_pP, const uint8_t xid) { int drb_id; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - NR_DRB_ToAddModList_t *DRB_configList = ue_p->DRB_configList2[xid]; - NR_SRB_ToAddModList_t *SRB_configList = ue_p->SRB_configList2[xid]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_p->DRB_Release_configList2[xid]; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; + NR_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; ue_p->ue_reestablishment_timer = 0; /* Derive the keys from kgnb */ if (DRB_configList != NULL) { - nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); - nr_derive_key_up_int(ue_p->integrity_algorithm, ue_p->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kUPint); } - nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); + /* Refresh SRBs/DRBs */ - LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); - ue_id_t reestablish_ue_id = 0; if (DRB_configList && DRB_configList->list.array[0]->reestablishPDCP && *DRB_configList->list.array[0]->reestablishPDCP == NR_DRB_ToAddMod__reestablishPDCP_true) { for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { @@ -1226,16 +1226,16 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, LOG_I(NR_RRC, "[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)\n", ue_p->rnti, size); - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; /* Derive the keys from kgnb */ if (SRB_configList != NULL) { - nr_derive_key_up_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kUPenc); + nr_derive_key(UP_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kUPenc); } - nr_derive_key_rrc_enc(ue_p->ciphering_algorithm, ue_p->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_p->integrity_algorithm, ue_p->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); /* Configure SRB1 for UE */ if (*SRB_configList != NULL) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index d62a5466b3..d499fcf61e 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -47,7 +47,8 @@ #include "S1AP_NAS-PDU.h" #include "executables/softmodem-common.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "ngap_gNB_defs.h" #include "ngap_gNB_ue_context.h" #include "ngap_gNB_management_procedures.h" @@ -126,20 +127,21 @@ nr_rrc_pdcp_config_security( { NR_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; (void)SRB_configList; - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - uint8_t *kUPenc = NULL; + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + uint8_t kUPenc[16] = {0}; //uint8_t *k_kdf = NULL; static int print_keys= 1; gNB_RRC_UE_t *UE = &ue_context_pP->ue_context; /* Derive the keys from kgnb */ if (UE->Srb[1].Active || UE->Srb[2].Active) { - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); } - nr_derive_key_rrc_enc(UE->ciphering_algorithm, UE->kgnb, &kRRCenc); - nr_derive_key_rrc_int(UE->integrity_algorithm, UE->kgnb, &kRRCint); + nr_derive_key(RRC_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kRRCenc); + nr_derive_key(RRC_INT_ALG, UE->integrity_algorithm, UE->kgnb, kRRCint); + if (!IS_SOFTMODEM_IQPLAYER) { SET_LOG_DUMP(DEBUG_SECURITY) ; } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index a8d9241b7f..294ff79346 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -43,7 +43,9 @@ #include "executables/nr-softmodem.h" #include #include -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include #include "nr_pdcp/nr_pdcp_oai_api.h" #include "MESSAGES/asn1_msg.h" @@ -121,8 +123,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; protocol_ctxt_t ctxt={0}; - unsigned char *kUPenc = NULL; - unsigned char *kUPint = NULL; + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; int i; gNB_RRC_UE_t *UE = &ue_context_p->ue_context; @@ -212,8 +214,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a LOG_I(RRC, "selecting integrity algorithm %d\n", UE->integrity_algorithm); /* derive UP security key */ - nr_derive_key_up_enc(UE->ciphering_algorithm, UE->kgnb, &kUPenc); - nr_derive_key_up_int(UE->integrity_algorithm, UE->kgnb, &kUPint); + nr_derive_key(UP_ENC_ALG, UE->ciphering_algorithm, UE->kgnb, kUPenc); + nr_derive_key(UP_INT_ALG, UE->integrity_algorithm, UE->kgnb, kUPint); e_NR_CipheringAlgorithm cipher_algo; switch (UE->ciphering_algorithm) { diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a3397a8de8..028807530a 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -57,7 +57,9 @@ #include "nr-uesoftmodem.h" #include "plmn_data.h" #include "nr_pdcp/nr_pdcp_oai_api.h" -#include "UTIL/OSA/osa_defs.h" +#include "openair3/SECU/secu_defs.h" +#include "openair3/SECU/key_nas_deriver.h" + #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" @@ -1522,18 +1524,22 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete; } - uint8_t *kRRCenc = NULL; - uint8_t *kUPenc = NULL; - uint8_t *kRRCint = NULL; - nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kUPenc); - nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kRRCenc); - nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, - NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, - &kRRCint); + uint8_t kRRCenc[16] = {0}; + uint8_t kUPenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + nr_derive_key(UP_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPenc); + nr_derive_key(RRC_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCenc); + nr_derive_key(RRC_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCint); + LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB=" "%02x%02x%02x%02x" "%02x%02x%02x%02x" @@ -1868,10 +1874,16 @@ nr_rrc_ue_establish_srb2( } } - uint8_t *kRRCenc = NULL; - uint8_t *kRRCint = NULL; - nr_derive_key_rrc_enc(ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, &kRRCenc); - nr_derive_key_rrc_int(ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, &kRRCint); + uint8_t kRRCenc[16] = {0}; + uint8_t kRRCint[16] = {0}; + nr_derive_key(RRC_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCenc); + nr_derive_key(RRC_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kRRCint); // Refresh SRBs nr_pdcp_add_srbs(ctxt_pP->enb_flag, @@ -1959,12 +1971,16 @@ nr_rrc_ue_establish_srb2( } } - uint8_t *kUPenc = NULL; - uint8_t *kUPint = NULL; - - NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id]; - nr_derive_key_up_enc(ue_rrc->cipheringAlgorithm, ue_rrc->kgnb, &kUPenc); - nr_derive_key_up_int(ue_rrc->integrityProtAlgorithm, ue_rrc->kgnb, &kUPint); + uint8_t kUPenc[16] = {0}; + uint8_t kUPint[16] = {0}; + nr_derive_key(UP_ENC_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPenc); + nr_derive_key(UP_INT_ALG, + NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm, + NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, + kUPint); // Refresh DRBs nr_pdcp_add_drbs(ctxt_pP->enb_flag, diff --git a/openair2/UTIL/OSA/README b/openair2/UTIL/OSA/README deleted file mode 100644 index c605ebf379..0000000000 --- a/openair2/UTIL/OSA/README +++ /dev/null @@ -1,18 +0,0 @@ -OAISIM Security Algorithms v0.1 - -Dependencies: -- openssl >= 1.0.1 - -Compilation: - -When compiling oaisim, add SECU=1 to enable security features. The makefile will -check for required dependencies and disable this feature if not all dependencies -are met. - -OSA is based on 3GPP TS 33.401. -Note that only EEA2 and EIA2 algorithms are supported, SNOW-3G is not implemented. - -Currently the kenb used to derive kRRCint, kRRCenc and kUPenc is composed of the -UE_id. In the future this parameter can be either obtained by deriving KASME received -from core epc (in the S1AP initial context setup request) -or configurable via command line or XML file. diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h deleted file mode 100644 index c175f10c84..0000000000 --- a/openair2/UTIL/OSA/osa_defs.h +++ /dev/null @@ -1,138 +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 - */ - -/*! - * \file secu_defs.h - * \brief Openair security algorithms functions implementing 3GPP TS 33.401 - * \note HMAC computations are done by openssl library - * \author Sebastien ROUX - * \date 2013 - * \version 0.1 - * @ingroup security -*/ - -#ifndef __UTIL_OSA_OSA_DEFS__H__ -#define __UTIL_OSA_OSA_DEFS__H__ - -#define EIA0_ALG_ID 0x00 -#define EIA1_128_ALG_ID 0x01 -#define EIA2_128_ALG_ID 0x02 - -#define EEA0_ALG_ID EIA0_ALG_ID -#define EEA1_128_ALG_ID EIA1_128_ALG_ID -#define EEA2_128_ALG_ID EIA2_128_ALG_ID - -#define SECU_DIRECTION_UPLINK 0 -#define SECU_DIRECTION_DOWNLINK 1 - -typedef enum { - NAS_ENC_ALG = 0x01, - NAS_INT_ALG = 0x02, - RRC_ENC_ALG = 0x03, - RRC_INT_ALG = 0x04, - UP_ENC_ALG = 0x05, - UP_INT_ALG = 0x06 -} algorithm_type_dist_t; - -//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB); - -int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); - -int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_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); - -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); - -//#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS) - -//#define derive_key_nas_int(aLGiD, kEY, kNAS) derive_key(NAS_INT_ALG, aLGiD, kEY, kNAS) - -#define derive_key_rrc_enc(aLGiD, kEY, kNAS) \ - derive_key(RRC_ENC_ALG, aLGiD, kEY, kNAS) - -#define derive_key_rrc_int(aLGiD, kEY, kNAS) \ - derive_key(RRC_INT_ALG, aLGiD, kEY, kNAS) - -#define derive_key_up_enc(aLGiD, kEY, kNAS) \ - derive_key(UP_ENC_ALG, aLGiD, kEY, kNAS) - -#define derive_key_up_int(aLGiD, kEY, kNAS) \ - derive_key(UP_INT_ALG, aLGiD, kEY, kNAS) - -// 5G SA -#define nr_derive_key_rrc_enc(aLGiD, kEY, kRRC) \ - nr_derive_key(RRC_ENC_ALG, aLGiD, kEY, kRRC) - -#define nr_derive_key_rrc_int(aLGiD, kEY, kRRC) \ - nr_derive_key(RRC_INT_ALG, aLGiD, kEY, kRRC) - -#define nr_derive_key_up_enc(aLGiD, kEY, kUP) \ - nr_derive_key(UP_ENC_ALG, aLGiD, kEY, kUP) - -#define nr_derive_key_up_int(aLGiD, kEY, kUP) \ - nr_derive_key(UP_INT_ALG, aLGiD, kEY, kUP) - -typedef struct { - uint8_t *key; - uint32_t key_length; - uint32_t count; - uint8_t bearer; - uint8_t direction; - uint8_t *message; - /* length in bits */ - uint32_t blength; -} stream_cipher_t; - -/*! - * @brief Encrypt/Decrypt a block of data based on the provided algorithm - * @param[in] algorithm Algorithm used to encrypt the data - * Possible values are: - * - EIA0_ALG_ID for NULL encryption - * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) - * - EIA2_128_ALG_ID for 128 bits AES LTE encryption - * @param[in] stream_cipher All parameters used to compute the encrypted block of data - * @param[out] out The encrypted block of data dynamically allocated - * @return 0 if everything OK, -1 if something failed - */ -int stream_encrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out); -#define stream_decrypt stream_encrypt - -int stream_compute_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t out[4]); - -/*! - * @brief Decrypt a block of data based on the provided algorithm - * @param[in] algorithm Algorithm used to encrypt the data - * Possible values are: - * - EIA0_ALG_ID for NULL encryption - * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) - * - EIA2_128_ALG_ID for 128 bits AES LTE encryption - * @param[in] stream_cipher All parameters used to compute the decrypted block of data - * @param[out] out The decrypted block of data dynamically allocated - * @return 0 if everything OK, -1 if something failed - */ -int stream_decrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out); - -int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t *expected); -#undef SECU_DEBUG - -#endif /* __UTIL_OSA_OSA_DEFS__H__ */ diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c deleted file mode 100644 index 06c0a3f9b2..0000000000 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ /dev/null @@ -1,175 +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 "../../../openair3/SECU/kdf.h" - -#include -#include - -#include "osa_defs.h" -#include "osa_internal.h" -#include "common/utils/LOG/log.h" - -/*! - * @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 - * be found in 3GPP TS.33401 #A.7 - * @param[in] alg_type Algorithm distinguisher - * @param[in] alg_id Algorithm identifier. - * Possible values are: - * - 0 for EIA0 algorithm (Null Integrity Protection algorithm) - * - 1 for 128-EIA1 SNOW 3G - * - 2 for 128-EIA2 AES - * @param[in] key The top key used to derive other subkeys - * @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) -{ - uint8_t string[7] = {0}; - - /* FC */ - string[0] = FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - string[1] = (uint8_t)(alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - string[2] = 0x00; - string[3] = 0x01; - - /* P1 */ - string[4] = alg_id; - - /* L1 = length(P1) = 1 */ - string[5] = 0x00; - string[6] = 0x01; - -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * sizeof(string) + 1]; - int index = 0; - - for (i = 0; i < sizeof(string); i++) - index += sprintf(&payload[index], "0x%02x ", string[i]); - - LOG_D(OSA, "Key deriver input string: %s\n", payload); - } -#endif - - 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) -{ - uint8_t string[7]; - - /* FC */ - string[0] = NR_FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - string[1] = (uint8_t)(alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - string[2] = 0x00; - string[3] = 0x01; - - /* P1 */ - string[4] = alg_id; - - /* L1 = length(P1) = 1 */ - string[5] = 0x00; - string[6] = 0x01; - - 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); - - 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 s[10] = {0}; - - /* FC */ - s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; - - /* P0 = PCI */ - s[1] = (pci & 0x0000ff00) >> 8; - s[2] = (pci & 0x000000ff); - - /* L0 = length(P0) = 2 */ - s[3] = 0x00; - s[4] = 0x02; - - /* P1 = NR ARFCN */ - s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16; - s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8; - s[7] = (nr_arfcn_dl & 0x000000ff); - - /* L1 = length(P1) = 3 */ - s[8] = 0x00; - s[9] = 0x03; - - - 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 s[5] = {0}; - - /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ - s[0] = 0x1c; - - /* put sk_counter */ - s[1] = (sk_counter >> 8) & 0xff; - s[2] = sk_counter & 0xff; - - /* put length of sk_counter (2) */ - s[3] = 0x00; - s[4] = 0x02; - - byte_array_t data = {.buf = s, .len = 5}; - kdf(keNB, data, 32, skgNB); - - return 0; -} diff --git a/openair2/UTIL/OSA/osa_snow3g.c b/openair2/UTIL/OSA/osa_snow3g.c deleted file mode 100644 index c69e80a1fb..0000000000 --- a/openair2/UTIL/OSA/osa_snow3g.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include - -#include "osa_rijndael.h" -#include "osa_snow3g.h" - -static uint8_t OSA_MULx(uint8_t V, uint8_t c); -static uint8_t OSA_MULxPOW(uint8_t V, uint8_t i, uint8_t c); -static uint32_t OSA_MULalpha(uint8_t c); -static uint32_t OSA_DIValpha(uint8_t c); -static uint32_t OSA_S1(uint32_t w); -static uint32_t OSA_S2(uint32_t w); -static void osa_snow3g_clock_LFSR_initialization_mode(uint32_t F, osa_snow_3g_context_t *s3g_ctx_pP); -static void osa_snow3g_clock_LFSR_key_stream_mode(osa_snow_3g_context_t *snow_3g_context_pP); -static uint32_t osa_snow3g_clock_fsm(osa_snow_3g_context_t *snow_3g_context_pP); -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP); -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *ks, osa_snow_3g_context_t *snow_3g_context_pP); - - -/* OSA_MULx. -* Input V: an 8-bit input. -* Input c: an 8-bit input. -* Output : an 8-bit input. -* MULx maps 16 bits to 8 bits -*/ - -static uint8_t OSA_MULx(uint8_t V, uint8_t c) -{ - //If the leftmost (i.e. the most significant) bit of V equals 1 - if ( V & 0x80 ) - return ( (V << 1) ^ c); - else - return ( V << 1); -} - -/* OSA_MULxPOW. -* Input V: an 8-bit input. -* Input i: a positive integer. -* Input c: an 8-bit input. -* Output : an 8-bit output. -* MULxPOW maps 16 bits and a positive integer i to 8 bit. -*/ - -static uint8_t OSA_MULxPOW(uint8_t V, uint8_t i, uint8_t c) -{ - if ( i == 0) - return V; - else - return OSA_MULx( OSA_MULxPOW( V, i-1, c ), c); -} - -/* The function OSA_MULalpha. -* Input c: 8-bit input. -* Output : 32-bit output. -* maps 8 bits to 32 bits. -*/ - -static uint32_t OSA_MULalpha(uint8_t c) -{ - return ( ( ((uint32_t)OSA_MULxPOW(c,23, 0xa9)) << 24 ) | - ( ((uint32_t)OSA_MULxPOW(c, 245, 0xa9)) << 16 ) | - ( ((uint32_t)OSA_MULxPOW(c, 48, 0xa9)) << 8 ) | - ( ((uint32_t)OSA_MULxPOW(c, 239, 0xa9)) ) ) ; -} - - -/* The function DIV alpha. -* Input c: 8-bit input. -* Output : 32-bit output. -* maps 8 bits to 32 bit. -*/ - -static uint32_t OSA_DIValpha(uint8_t c) -{ - return ( ( ((uint32_t)OSA_MULxPOW(c, 16, 0xa9)) << 24 ) | - ( ((uint32_t)OSA_MULxPOW(c, 39, 0xa9)) << 16 ) | - ( ((uint32_t)OSA_MULxPOW(c, 6, 0xa9)) << 8 ) | - ( ((uint32_t)OSA_MULxPOW(c, 64, 0xa9)) ) ) ; -} - -/* The 32x32-bit S-Box S1 -* Input: a 32-bit input. -* Output: a 32-bit output of S1 box. -* The S-Box S1 maps a 32-bit input to a 32-bit output. -* w = w0 || w1 || w2 || w3 the 32-bit input with w0 the most and w3 the least significant byte. -* S1(w)= r0 || r1 || r2 || r3 with r0 the most and r3 the least significant byte. -*/ - -static uint32_t OSA_S1(uint32_t w) -{ - uint8_t r0=0, r1=0, r2=0, r3=0; - uint8_t srw0 = OSA_SR[ (uint8_t)((w >> 24) & 0xff) ]; - uint8_t srw1 = OSA_SR[ (uint8_t)((w >> 16) & 0xff) ]; - uint8_t srw2 = OSA_SR[ (uint8_t)((w >> 8) & 0xff) ]; - uint8_t srw3 = OSA_SR[ (uint8_t)((w) & 0xff) ]; - - r0 = ( ( OSA_MULx( srw0 , 0x1b) ) ^ - ( srw1 ) ^ - ( srw2 ) ^ - ( (OSA_MULx( srw3, 0x1b)) ^ srw3 ) - ); - - r1 = ( ( ( OSA_MULx( srw0 , 0x1b) ) ^ srw0 ) ^ - ( OSA_MULx(srw1, 0x1b) ) ^ - ( srw2 ) ^ - ( srw3 ) - ); - - r2 = ( ( srw0 ) ^ - ( ( OSA_MULx( srw1 , 0x1b) ) ^ srw1 ) ^ - ( OSA_MULx(srw2, 0x1b) ) ^ - ( srw3 ) - ); - - r3 = ( ( srw0 ) ^ - ( srw1 ) ^ - ( ( OSA_MULx( srw2 , 0x1b) ) ^ srw2 ) ^ - ( OSA_MULx( srw3, 0x1b) ) - ); - - return ( ( ((uint32_t)r0) << 24 ) | ( ((uint32_t)r1) << 16 ) | ( ((uint32_t)r2) << 8 ) | ( ((uint32_t)r3) ) ); -} - -/* The 32x32-bit S-Box S2 -* Input: a 32-bit input. -* Output: a 32-bit output of S2 box. -* The S-Box S2 maps a 32-bit input to a 32-bit output. -* Let w = w0 || w1 || w2 || w3 the 32-bit input with w0 the most and w3 the least significant byte. -* Let S2(w)= r0 || r1 || r2 || r3 with r0 the most and r3 the least significant byte. -*/ - -static uint32_t OSA_S2(uint32_t w) -{ - uint8_t r0=0, r1=0, r2=0, r3=0; - uint8_t sqw0 = OSA_SQ[ (uint8_t)((w >> 24) & 0xff) ]; - uint8_t sqw1 = OSA_SQ[ (uint8_t)((w >> 16) & 0xff) ]; - uint8_t sqw2 = OSA_SQ[ (uint8_t)((w >> 8) & 0xff) ]; - uint8_t sqw3 = OSA_SQ[ (uint8_t)((w) & 0xff) ]; - - - r0 = ( ( OSA_MULx( sqw0 , 0x69) ) ^ - ( sqw1 ) ^ - ( sqw2 ) ^ - ( (OSA_MULx( sqw3, 0x69)) ^ sqw3 ) - ); - - r1 = ( ( ( OSA_MULx( sqw0 , 0x69) ) ^ sqw0 ) ^ - ( OSA_MULx(sqw1, 0x69) ) ^ - ( sqw2 ) ^ - ( sqw3 ) - ); - - r2 = ( ( sqw0 ) ^ - ( ( OSA_MULx( sqw1 , 0x69) ) ^ sqw1 ) ^ - ( OSA_MULx(sqw2, 0x69) ) ^ - ( sqw3 ) - ); - - r3 = ( ( sqw0 ) ^ - ( sqw1 ) ^ - ( ( OSA_MULx( sqw2 , 0x69) ) ^ sqw2 ) ^ - ( OSA_MULx( sqw3, 0x69) ) - ); - - return ( ( ((uint32_t)r0) << 24 ) | ( ((uint32_t)r1) << 16 ) | ( ((uint32_t)r2) << 8 ) | ( ((uint32_t)r3) ) ); -} - -/* Clocking LFSR in initialization mode. -* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock. -* Input F: a 32-bit word comes from output of FSM. -* See section 3.4.4. -*/ - -static void osa_snow3g_clock_LFSR_initialization_mode(uint32_t F, osa_snow_3g_context_t *s3g_ctx_pP) -{ - uint32_t v = ( ( (s3g_ctx_pP->LFSR_S0 << 8) & 0xffffff00 ) ^ - ( OSA_MULalpha( (uint8_t)((s3g_ctx_pP->LFSR_S0>>24) & 0xff) ) ) ^ - ( s3g_ctx_pP->LFSR_S2 ) ^ - ( (s3g_ctx_pP->LFSR_S11 >> 8) & 0x00ffffff ) ^ - ( OSA_DIValpha( (uint8_t)( ( s3g_ctx_pP->LFSR_S11) & 0xff ) ) ) ^ - ( F ) - ); - - s3g_ctx_pP->LFSR_S0 = s3g_ctx_pP->LFSR_S1; - s3g_ctx_pP->LFSR_S1 = s3g_ctx_pP->LFSR_S2; - s3g_ctx_pP->LFSR_S2 = s3g_ctx_pP->LFSR_S3; - s3g_ctx_pP->LFSR_S3 = s3g_ctx_pP->LFSR_S4; - s3g_ctx_pP->LFSR_S4 = s3g_ctx_pP->LFSR_S5; - s3g_ctx_pP->LFSR_S5 = s3g_ctx_pP->LFSR_S6; - s3g_ctx_pP->LFSR_S6 = s3g_ctx_pP->LFSR_S7; - s3g_ctx_pP->LFSR_S7 = s3g_ctx_pP->LFSR_S8; - s3g_ctx_pP->LFSR_S8 = s3g_ctx_pP->LFSR_S9; - s3g_ctx_pP->LFSR_S9 = s3g_ctx_pP->LFSR_S10; - s3g_ctx_pP->LFSR_S10 = s3g_ctx_pP->LFSR_S11; - s3g_ctx_pP->LFSR_S11 = s3g_ctx_pP->LFSR_S12; - s3g_ctx_pP->LFSR_S12 = s3g_ctx_pP->LFSR_S13; - s3g_ctx_pP->LFSR_S13 = s3g_ctx_pP->LFSR_S14; - s3g_ctx_pP->LFSR_S14 = s3g_ctx_pP->LFSR_S15; - s3g_ctx_pP->LFSR_S15 = v; -} - -/* Clocking LFSR in keystream mode. -* LFSR Registers S0 to S15 are updated as the LFSR receives a single clock. -* See section 3.4.5. -*/ -static void osa_snow3g_clock_LFSR_key_stream_mode(osa_snow_3g_context_t *snow_3g_context_pP) -{ - - uint32_t v = ( ( (snow_3g_context_pP->LFSR_S0 << 8) & 0xffffff00 ) ^ - ( OSA_MULalpha( (uint8_t)((snow_3g_context_pP->LFSR_S0>>24) & 0xff) ) ) ^ - ( snow_3g_context_pP->LFSR_S2 ) ^ - ( (snow_3g_context_pP->LFSR_S11 >> 8) & 0x00ffffff ) ^ - ( OSA_DIValpha( (uint8_t)( ( snow_3g_context_pP->LFSR_S11) & 0xff ) ) ) - ); - - snow_3g_context_pP->LFSR_S0 = snow_3g_context_pP->LFSR_S1; - snow_3g_context_pP->LFSR_S1 = snow_3g_context_pP->LFSR_S2; - snow_3g_context_pP->LFSR_S2 = snow_3g_context_pP->LFSR_S3; - snow_3g_context_pP->LFSR_S3 = snow_3g_context_pP->LFSR_S4; - snow_3g_context_pP->LFSR_S4 = snow_3g_context_pP->LFSR_S5; - snow_3g_context_pP->LFSR_S5 = snow_3g_context_pP->LFSR_S6; - snow_3g_context_pP->LFSR_S6 = snow_3g_context_pP->LFSR_S7; - snow_3g_context_pP->LFSR_S7 = snow_3g_context_pP->LFSR_S8; - snow_3g_context_pP->LFSR_S8 = snow_3g_context_pP->LFSR_S9; - snow_3g_context_pP->LFSR_S9 = snow_3g_context_pP->LFSR_S10; - snow_3g_context_pP->LFSR_S10 = snow_3g_context_pP->LFSR_S11; - snow_3g_context_pP->LFSR_S11 = snow_3g_context_pP->LFSR_S12; - snow_3g_context_pP->LFSR_S12 = snow_3g_context_pP->LFSR_S13; - snow_3g_context_pP->LFSR_S13 = snow_3g_context_pP->LFSR_S14; - snow_3g_context_pP->LFSR_S14 = snow_3g_context_pP->LFSR_S15; - snow_3g_context_pP->LFSR_S15 = v; -} - -/* Clocking FSM. -* Produces a 32-bit word F. -* Updates FSM registers R1, R2, R3. -* See Section 3.4.6. -*/ - -static uint32_t osa_snow3g_clock_fsm(osa_snow_3g_context_t *snow_3g_context_pP) -{ - uint32_t F = ( ( snow_3g_context_pP->LFSR_S15 + snow_3g_context_pP->FSM_R1 ) & 0xffffffff ) ^ snow_3g_context_pP->FSM_R2 ; - uint32_t r = ( snow_3g_context_pP->FSM_R2 + ( snow_3g_context_pP->FSM_R3 ^ snow_3g_context_pP->LFSR_S5 ) ) & 0xffffffff ; - - snow_3g_context_pP->FSM_R3 = OSA_S2(snow_3g_context_pP->FSM_R2); - snow_3g_context_pP->FSM_R2 = OSA_S1(snow_3g_context_pP->FSM_R1); - snow_3g_context_pP->FSM_R1 = r; - - return F; -} - -/* Initialization. - * Input k[4]: Four 32-bit words making up 128-bit key. - * Input IV[4]: Four 32-bit words making 128-bit initialization variable. - * Output: All the LFSRs and FSM are initialized for key generation. - * See Section 4.1. - */ - -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP) -{ - - uint8_t i = 0; - uint32_t F = 0x0; - - snow_3g_context_pP->LFSR_S15 = k[3] ^ IV[0]; - snow_3g_context_pP->LFSR_S14 = k[2]; - snow_3g_context_pP->LFSR_S13 = k[1]; - snow_3g_context_pP->LFSR_S12 = k[0] ^ IV[1]; - - snow_3g_context_pP->LFSR_S11 = k[3] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S10 = k[2] ^ 0xffffffff ^ IV[2]; - snow_3g_context_pP->LFSR_S9 = k[1] ^ 0xffffffff ^ IV[3]; - snow_3g_context_pP->LFSR_S8 = k[0] ^ 0xffffffff; - - snow_3g_context_pP->LFSR_S7 = k[3]; - snow_3g_context_pP->LFSR_S6 = k[2]; - snow_3g_context_pP->LFSR_S5 = k[1]; - snow_3g_context_pP->LFSR_S4 = k[0]; - - snow_3g_context_pP->LFSR_S3 = k[3] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S2 = k[2] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S1 = k[1] ^ 0xffffffff; - snow_3g_context_pP->LFSR_S0 = k[0] ^ 0xffffffff; - - snow_3g_context_pP->FSM_R1 = 0x0; - snow_3g_context_pP->FSM_R2 = 0x0; - snow_3g_context_pP->FSM_R3 = 0x0; - - for(i=0; i<32; i++) { - F = osa_snow3g_clock_fsm(snow_3g_context_pP); - osa_snow3g_clock_LFSR_initialization_mode(F, snow_3g_context_pP); - } - -} - -/* Generation of Keystream. -* input n: number of 32-bit words of keystream. -* input z: space for the generated keystream, assumes -* memory is allocated already. -* output: generated keystream which is filled in z -* See section 4.2. -*/ - -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *ks, osa_snow_3g_context_t *snow_3g_context_pP) -{ - uint32_t t = 0; - uint32_t F = 0x0; - - osa_snow3g_clock_fsm(snow_3g_context_pP); /* Clock FSM once. Discard the output. */ - osa_snow3g_clock_LFSR_key_stream_mode(snow_3g_context_pP); /* Clock LFSR in keystream mode once. */ - - for ( t=0; tLFSR_S0; /* STEP 2 */ - - /* Note that ks[t] corresponds to z_{t+1} in section 4.2*/ - - osa_snow3g_clock_LFSR_key_stream_mode(snow_3g_context_pP); /* STEP 3 */ - } -} - diff --git a/openair2/UTIL/OSA/osa_snow3g.h b/openair2/UTIL/OSA/osa_snow3g.h deleted file mode 100644 index 5da81d23f3..0000000000 --- a/openair2/UTIL/OSA/osa_snow3g.h +++ /dev/null @@ -1,77 +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 - */ - -/*! \file snow3g.h -* \brief -* \author Open source Adapted from Specification of the 3GPP Confidentiality and -* Integrity Algorithms UEA2 & UIA2. Document 2: SNOW 3G Specification -* \integrators Kharbach Othmane, GAUTHIER Lionel. -* \date 2014 -* \version -* \note -* \bug -* \warning -*/ -#ifndef OSA_SNOW3G_H_ -#define OSA_SNOW3G_H_ - -typedef struct osa_snow_3g_context_s { - uint32_t LFSR_S0; - uint32_t LFSR_S1; - uint32_t LFSR_S2; - uint32_t LFSR_S3; - uint32_t LFSR_S4; - uint32_t LFSR_S5; - uint32_t LFSR_S6; - uint32_t LFSR_S7; - uint32_t LFSR_S8; - uint32_t LFSR_S9; - uint32_t LFSR_S10; - uint32_t LFSR_S11; - uint32_t LFSR_S12; - uint32_t LFSR_S13; - uint32_t LFSR_S14; - uint32_t LFSR_S15; - - /* FSM : The Finite State Machine has three 32-bit registers R1, R2 and R3. - */ - uint32_t FSM_R1; - uint32_t FSM_R2; - uint32_t FSM_R3; -} osa_snow_3g_context_t; - -/* Initialization. -* Input k[4]: Four 32-bit words making up 128-bit key. -* Input IV[4]: Four 32-bit words making 128-bit initialization variable. -* Output: All the LFSRs and FSM are initialized for key generation. -*/ -void osa_snow3g_initialize(uint32_t k[4], uint32_t IV[4], osa_snow_3g_context_t *snow_3g_context_pP); - -/* Generation of Keystream. -* input n: number of 32-bit words of keystream. -* input z: space for the generated keystream, assumes -* memory is allocated already. -* output: generated keystream which is filled in z -*/ - -void osa_snow3g_generate_key_stream(uint32_t n, uint32_t *z, osa_snow_3g_context_t *snow_3g_context_pP); - -#endif diff --git a/openair2/UTIL/OSA/osa_stream_eea.c b/openair2/UTIL/OSA/osa_stream_eea.c deleted file mode 100644 index 61f003bc32..0000000000 --- a/openair2/UTIL/OSA/osa_stream_eea.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include -#include - -#include "common/utils/LOG/log.h" -#include "byte_array.h" -#include "openair3//SECU//aes_128_ctr.h" - -#include "assertions.h" -#include "osa_defs.h" -#include "osa_snow3g.h" -#include "osa_internal.h" - -int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out) -{ - uint8_t *data = NULL; - - uint32_t byte_length; - - 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"); - - byte_length = (stream_cipher->blength + 7) >> 3; - - if (*out == NULL) { - /* User did not provide output buffer */ - data = malloc(byte_length); - *out = data; - } else { - data = *out; - } - - memcpy(data, stream_cipher->message, byte_length); - - return 0; -} - -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; - uint32_t *KS; - 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; - 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*/ - K[3] = hton_int32(K[3]); - K[2] = hton_int32(K[2]); - K[1] = hton_int32(K[1]); - K[0] = hton_int32(K[0]); - /* Prepare the initialization vector (IV) for SNOW 3G initialization as in - section 3.4. */ - IV[3] = stream_cipher->count; - IV[2] = ((((uint32_t)stream_cipher->bearer) << 3) | ((((uint32_t)stream_cipher->direction) & 0x1) << 2)) << 24; - IV[1] = IV[3]; - IV[0] = IV[2]; - - /* 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); - - if (zero_bit > 0) { - KS[n - 1] = KS[n - 1] & (uint32_t)(0xFFFFFFFF << (8 - zero_bit)); - } - - 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); - } - - if (zero_bit > 0) { - 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)); - } - - free(KS); - *out = stream_cipher->message; - return 0; -} - -int stream_encrypt_eea2(stream_cipher_t *stream_cipher, uint8_t **out) -{ - DevAssert(stream_cipher != 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); - - if (*out == NULL) { - *out = calloc(1, (stream_cipher->blength >> 3) + 1); - DevAssert(*out != NULL && "Memory exhausted"); - } - - 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; -} - -int stream_encrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **out) -{ - if (algorithm == EEA0_ALG_ID) { - return stream_encrypt_eea0(stream_cipher, out); - } else if (algorithm == EEA1_128_ALG_ID) { - return stream_encrypt_eea1(stream_cipher, out); - } else if (algorithm == EEA2_128_ALG_ID) { - return stream_encrypt_eea2(stream_cipher, out); - } - - LOG_E(OSA, "Provided encryption algorithm is currently not supported = %u\n", algorithm); - return -1; -} diff --git a/openair2/UTIL/OSA/osa_stream_eia.c b/openair2/UTIL/OSA/osa_stream_eia.c deleted file mode 100644 index da4fd23e18..0000000000 --- a/openair2/UTIL/OSA/osa_stream_eia.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include -#include -#include -#include -#include - -#include "assertions.h" -#include "common/utils/LOG/log.h" - -#include "openair3/SECU/aes_128_cbc_cmac.h" - -#include "osa_defs.h" -#include "osa_snow3g.h" -#include "osa_internal.h" - -// see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1 - -/* OSA_MUL64x. - * Input V: a 64-bit input. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling - * function. - * See section 4.3.2 for details. - */ -uint64_t OSA_MUL64x(uint64_t V, uint64_t c) -{ - if (V & 0x8000000000000000) - return (V << 1) ^ c; - else - return V << 1; -} -/* OSA_MUL64xPOW. - * Input V: a 64-bit input. - * Input i: a positive integer. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling -function. - * See section 4.3.3 for details. - */ -uint64_t OSA_MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) -{ - if (i == 0) - return V; - else - return OSA_MUL64x(OSA_MUL64xPOW(V, i - 1, c), c); -} -/* OSA_MUL64. - * Input V: a 64-bit input. - * Input P: a 64-bit input. - * Input c: a 64-bit input. - * Output : a 64-bit output. - * A 64-bit memory is allocated which is to be freed by the calling - * function. - * See section 4.3.4 for details. - */ -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); - } - - 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. - */ -uint32_t osa_mask32bit(int n) -{ - uint32_t mask = 0x0; - - if (n % 32 == 0) - return 0xffffffff; - - while (n--) - 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 - * @param[out] out For EIA2 the output string is 32 bits long - */ -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; - - 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*/ - K[3] = hton_int32(K[3]); - K[2] = hton_int32(K[2]); - K[1] = hton_int32(K[1]); - K[0] = hton_int32(K[0]); - /* Prepare the Initialization Vector (IV) for SNOW3G initialization as in - 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[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 ("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]); - 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); - /* Calculation */ - 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 D-2 */ - rem_bits = stream_cipher->blength % 64; - - if (rem_bits == 0) - rem_bits = 64; - - 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); - } else { - M_D_2 = ((uint64_t)hton_int32(message[2 * (D - 2)]) & mask) << 32; - } - - V = EVAL ^ M_D_2; - EVAL = OSA_MUL64(V, P, c); - /* for D-1 */ - EVAL ^= stream_cipher->blength; - /* Multiply by Q */ - EVAL = OSA_MUL64(EVAL, Q, c); - MAC_I = (uint32_t)(EVAL >> 32) ^ z[4]; - // printf ("MAC_I:%16X\n",MAC_I); - MAC_I = hton_int32(MAC_I); - memcpy(out, &MAC_I, 4); - return 0; -} - -int stream_compute_integrity_eia2(stream_cipher_t *stream_cipher, uint8_t out[4]) -{ - DevAssert(stream_cipher != 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); - - 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); - - const size_t m_length = stream_cipher->blength >> 3; - - 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; -} - -int stream_compute_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t out[4]) -{ - if (algorithm == EIA1_128_ALG_ID) { - LOG_D(OSA, "EIA1 algorithm applied for integrity\n"); - return stream_compute_integrity_eia1(stream_cipher, out); - } else if (algorithm == EIA2_128_ALG_ID) { - LOG_D(OSA, "EIA2 algorithm applied for integrity\n"); - return stream_compute_integrity_eia2(stream_cipher, out); - } - - LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", algorithm); - return -1; -} - -int stream_check_integrity(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t *expected) -{ - uint8_t result[4]; - - if (algorithm != EIA0_ALG_ID) { - if (stream_compute_integrity(algorithm, stream_cipher, result) != 0) { - return -1; - } - - if (memcmp(result, expected, 4) != 0) { - 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]); - return -1; - } - } - - /* Integrity verification succeeded */ - return 0; -} diff --git a/openair3/COMMON/common_types.h b/openair3/COMMON/common_types.h index 80cc20df63..51f1f83391 100644 --- a/openair3/COMMON/common_types.h +++ b/openair3/COMMON/common_types.h @@ -23,8 +23,6 @@ #include "commonDef.h" -#include "security_types.h" - #include "queue.h" #ifndef COMMON_TYPES_H_ diff --git a/openair3/COMMON/security_types.h b/openair3/COMMON/security_types.h index 5494ffd994..d78534e176 100644 --- a/openair3/COMMON/security_types.h +++ b/openair3/COMMON/security_types.h @@ -42,14 +42,6 @@ #define AUTN_LENGTH_BITS (128) #define AUTN_LENGTH_OCTETS (AUTN_LENGTH_BITS/8) -/* Some methods to convert a string to an int64_t */ -/* -#define STRING_TO_64BITS(sTRING, cONTAINER) \ - sscanf(sTRING, "%" SCN64, cONTAINER) -#define STRING_TO_U64BITS(sTRING, cONTAINER) \ - sscanf(sTRING, "%" SCNu64, cONTAINER) -*/ - /* Converts a string to 128 bits gmplib integer holder */ # define STRING_TO_XBITS(sTRING, lENGTH, cONTAINER, rET) \ do { \ @@ -63,18 +55,6 @@ STRING_TO_XBITS(sTRING, 16, cONTAINER, rET) # define STRING_TO_256BITS(sTRING, cONTAINER, rET) \ STRING_TO_XBITS(sTRING, 32, cONTAINER, rET) -# define STRING_TO_RAND STRING_TO_128BITS -# define STRING_TO_AUTH_KEY STRING_TO_128BITS -# define STRING_TO_AUTH_RES STRING_TO_128BITS -# define STRING_TO_AUTN STRING_TO_128BITS -# define STRING_TO_KASME STRING_TO_256BITS -# define STRING_TO_XRES(sTRING, lENGTH, cONTAINER, rET) \ -do { \ - STRING_TO_XBITS(sTRING, lENGTH, (cONTAINER)->data, rET); \ - if (rET != -1) \ - (cONTAINER)->size = lENGTH; \ -} while(0) - /* RES amd XRES can have a variable length of 4-16 octets */ typedef struct { uint8_t size; @@ -107,28 +87,4 @@ typedef struct eutran_vector_s { uint8_t kasme[KASME_LENGTH_OCTETS]; } eutran_vector_t; -#define FC_KASME (0x10) -#define FC_KENB (0x11) -#define FC_NH (0x12) -#define FC_KENB_STAR (0x13) -/* 33401 #A.7 Algorithm for key derivation function. - * This FC should be used for: - * - NAS Encryption algorithm - * - NAS Integrity algorithm - * - RRC Encryption algorithm - * - RRC Integrity algorithm - * - User Plane Encryption algorithm - */ -#define FC_ALG_KEY_DER (0x15) -#define FC_KASME_TO_CK (0x16) - -typedef enum { - NAS_ENC_ALG = 0x01, - NAS_INT_ALG = 0x02, - RRC_ENC_ALG = 0x03, - RRC_INT_ALG = 0x04, - UP_ENC_ALG = 0x05, - UP_INT_ALG = 0x06 -} algorithm_type_dist_t; - #endif /* SECURITY_TYPES_H_ */ diff --git a/openair3/NAS/COMMON/API/NETWORK/nas_message.c b/openair3/NAS/COMMON/API/NETWORK/nas_message.c index 02fa4ad6ca..44c730038c 100644 --- a/openair3/NAS/COMMON/API/NETWORK/nas_message.c +++ b/openair3/NAS/COMMON/API/NETWORK/nas_message.c @@ -53,8 +53,6 @@ Description Defines the layer 3 messages supported by the NAS sublayer #include "secu_defs.h" #include "emmData.h" -//#define DEBUG_NAS_MESSAGE - /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ @@ -1019,7 +1017,8 @@ static int _nas_message_decrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); + /* Decode the first octet (security header type or EPS bearer identity, * and protocol discriminator) */ DECODE_U8(dest, *(uint8_t*)(&header), size); @@ -1054,7 +1053,8 @@ static int _nas_message_decrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); + /* Decode the first octet (security header type or EPS bearer identity, * and protocol discriminator) */ DECODE_U8(dest, *(uint8_t*)(&header), size); @@ -1186,8 +1186,7 @@ static int _nas_message_encrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea1(&stream_cipher, (unsigned char *)dest); - + stream_compute_encrypt(EEA1_128_ALG_ID, &stream_cipher, (unsigned char *)dest); LOG_FUNC_RETURN (length); } @@ -1217,7 +1216,7 @@ static int _nas_message_encrypt( stream_cipher.message = (unsigned char *)src; /* length in bits */ stream_cipher.blength = length << 3; - nas_stream_encrypt_eea2(&stream_cipher, (unsigned char *)dest); + stream_compute_encrypt(EEA2_128_ALG_ID, &stream_cipher, (unsigned char *)dest); LOG_FUNC_RETURN (length); @@ -1356,10 +1355,8 @@ static uint32_t _nas_message_get_mac( stream_cipher.message = (unsigned char *)buffer; /* length in bits */ stream_cipher.blength = length << 3; + stream_compute_integrity(EIA1_128_ALG_ID, &stream_cipher, mac); - nas_stream_encrypt_eia1( - &stream_cipher, - mac); LOG_TRACE(DEBUG, "NAS_SECURITY_ALGORITHMS_EIA1 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d", mac[0], mac[1], mac[2],mac[3], @@ -1402,10 +1399,8 @@ static uint32_t _nas_message_get_mac( stream_cipher.message = (unsigned char *)buffer; /* length in bits */ stream_cipher.blength = length << 3; + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); - nas_stream_encrypt_eia2( - &stream_cipher, - mac); LOG_TRACE(DEBUG, "NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x(%u) for length %d direction %d, count %d", mac[0], mac[1], mac[2],mac[3], diff --git a/openair3/NAS/COMMON/milenage.h b/openair3/NAS/COMMON/milenage.h index c5762a0d69..c71ad76fe8 100644 --- a/openair3/NAS/COMMON/milenage.h +++ b/openair3/NAS/COMMON/milenage.h @@ -29,10 +29,11 @@ #ifndef MILENAGE_H #define MILENAGE_H + #include +#include "openair3/SECU/aes_128_ecb.h" -#define u8 uint8_t /** milenage_f1 - Milenage f1 and f1* algorithms @opc: OPc = 128-bit value derived from OP and K @@ -45,16 +46,29 @@ Returns: true on success, false on failure */ -void aes_128_encrypt_block(const u8* key, const u8* in, u8* out) { - AES_KEY k; - u8 tmp[16]; - AES_set_encrypt_key(key, 128, &k); - AES_encrypt(in, tmp, &k); +void aes_128_encrypt_block(const uint8_t *key, const uint8_t *in, uint8_t *out) +{ + abort(); + assert(0 != 0 && "Here we are!"); + // Precondition: key, in and out occupy 16 bytes + aes_128_t k_iv = {.type = NONE_INITIALIZATION_VECTOR}; + memcpy(k_iv.key, key, sizeof(k_iv.key)); + + byte_array_t msg = {.buf = (uint8_t *)in, .len = 16}; + uint8_t tmp[16] = {0}; + aes_128_ecb(&k_iv, msg, sizeof(tmp), tmp); memcpy(out, tmp, sizeof(tmp)); } -static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, - const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s) { - u8 tmp1[16], tmp2[16], tmp3[16]; + +static bool milenage_f1(const uint8_t *opc, + const uint8_t *k, + const uint8_t *_rand, + const uint8_t *sqn, + const uint8_t *amf, + uint8_t *mac_a, + uint8_t *mac_s) +{ + uint8_t tmp1[16], tmp2[16], tmp3[16]; int i; /* tmp1 = TEMP = E_K(RAND XOR OP_C) */ @@ -62,10 +76,10 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, tmp1[i] = _rand[i] ^ opc[i]; aes_128_encrypt_block(k, tmp1, tmp1); - AES_KEY kTab; - uint8_t cyphered[16]; - AES_set_encrypt_key(k, 128, &kTab); - AES_encrypt(tmp1, cyphered, &kTab); + + uint8_t cyphered[16] = {0}; + aes_128_encrypt_block(k, tmp1, cyphered); + /* tmp2 = IN1 = SQN || AMF || SQN || AMF */ memcpy(tmp2, sqn, 6); memcpy(tmp2 + 6, amf, 2); @@ -97,7 +111,6 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, return true; } - /** milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms @opc: OPc = 128-bit value derived from OP and K @@ -110,9 +123,16 @@ static bool milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand, @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL Returns: true on success, false on failure */ -static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, - u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar) { - u8 tmp1[16], tmp2[16], tmp3[16]; +static bool milenage_f2345(const uint8_t *opc, + const uint8_t *k, + const uint8_t *_rand, + uint8_t *res, + uint8_t *ck, + uint8_t *ik, + uint8_t *ak, + uint8_t *akstar) +{ + uint8_t tmp1[16], tmp2[16], tmp3[16]; int i; /* tmp2 = TEMP = E_K(RAND XOR OP_C) */ @@ -186,7 +206,6 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, return true; } - /** milenage_generate - Generate AKA AUTN,IK,CK,RES @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) @@ -200,11 +219,18 @@ static bool milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand, @res: Buffer for RES = 64-bit signed response (f2), or %NULL @res_len: Max length for res; set to used length or 0 on failure */ -static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, - const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik, - u8 *ck, u8 *res) { +static bool milenage_generate(const uint8_t *opc, + const uint8_t *amf, + const uint8_t *k, + const uint8_t *sqn, + const uint8_t *_rand, + uint8_t *autn, + uint8_t *ik, + uint8_t *ck, + uint8_t *res) +{ int i; - u8 mac_a[8], ak[6]; + uint8_t mac_a[8], ak[6]; if (!milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) || !milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) @@ -219,7 +245,6 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, return true; } - /** milenage_auts - Milenage AUTS validation @opc: OPc = 128-bit operator variant algorithm configuration field (encr.) @@ -232,10 +257,10 @@ static bool milenage_generate(const u8 *opc, const u8 *amf, const u8 *k, #define p(a) printf("%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", (int)((a)[0]), (int)((a)[1]), (int)((a)[2]), (int)((a)[3]),(int)((a)[4]), (int)((a)[5])); // valid code but put in comment as it is not used right now #if 0 -static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts, - u8 *sqn) { - u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ - u8 ak[6], mac_s[8]; +static bool milenage_auts(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, const uint8_t *auts, + uint8_t *sqn) { + uint8_t amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + uint8_t ak[6], mac_s[8]; int i; if (!milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) @@ -262,8 +287,8 @@ static bool milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 @kc: Buffer for Kc = 64-bit Kc Returns: 0 on success, -1 on failure */ -static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc) { - u8 res[8], ck[16], ik[16]; +static bool gsm_milenage(const uint8_t *opc, const uint8_t *k, const uint8_t *_rand, uint8_t *sres, uint8_t *kc) { + uint8_t res[8], ck[16], ik[16]; int i; if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL)) @@ -298,12 +323,12 @@ static bool gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, @auts: 112-bit buffer for AUTS Returns: 0 on success, -1 on failure, or -2 on synchronization failure */ -static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand, - const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len, - u8 *auts) { +static int milenage_check(const uint8_t *opc, const uint8_t *k, const uint8_t *sqn, const uint8_t *_rand, + const uint8_t *autn, uint8_t *ik, uint8_t *ck, uint8_t *res, size_t *res_len, + uint8_t *auts) { int i; - u8 mac_a[8], ak[6], rx_sqn[6]; - const u8 *amf; + uint8_t mac_a[8], ak[6], rx_sqn[6]; + const uint8_t *amf; if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) return -1; @@ -315,7 +340,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_ rx_sqn[i] = autn[i] ^ ak[i]; if (memcmp(rx_sqn, sqn, 6) <= 0) { - u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ + uint8_t auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak)) return -1; @@ -342,7 +367,7 @@ static int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_ return 0; } -static void milenage_opc_gen(const u8 *k, const u8 *op, u8 *opc) { +static void milenage_opc_gen(const uint8_t *k, const uint8_t *op, uint8_t *opc) { int i; /* Encrypt OP using K */ aes_128_encrypt_block(k, op, opc); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e57e3800de..4d3078493f 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -40,6 +40,7 @@ #include "aka_functions.h" #include "secu_defs.h" #include "kdf.h" +#include "key_nas_deriver.h" #include "PduSessionEstablishRequest.h" #include "PduSessionEstablishmentAccept.h" #include "RegistrationAccept.h" @@ -50,6 +51,7 @@ #include #include #include "openair2/SDAP/nr_sdap/nr_sdap.h" +#include "openair3/SECU/nas_stream_eia2.h" uint8_t *registration_request_buf; uint32_t registration_request_len; @@ -597,9 +599,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ @@ -702,9 +702,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ @@ -861,9 +859,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t * stream_cipher.blength = (initialNasMsg->length - 6) << 3; // only for Type of integrity protection algorithm: 128-5G-IA2 (2) - nas_stream_encrypt_eia2( - &stream_cipher, - mac); + stream_compute_integrity(EIA2_128_ALG_ID, &stream_cipher, mac); printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); for(int i = 0; i < 4; i++){ diff --git a/openair3/SECU/aes_128.h b/openair3/SECU/aes_128.h index 7f7e550419..4155c96d7f 100644 --- a/openair3/SECU/aes_128.h +++ b/openair3/SECU/aes_128.h @@ -62,9 +62,10 @@ typedef struct{ }; } iv8_t; -typedef enum{ +typedef enum { AES_INITIALIZATION_VECTOR_8, AES_INITIALIZATION_VECTOR_16, + NONE_INITIALIZATION_VECTOR, AES_INITIALIZATION_VECTOR_END, } iv_e; diff --git a/openair3/SECU/aes_128_ecb.c b/openair3/SECU/aes_128_ecb.c new file mode 100644 index 0000000000..2969166dc1 --- /dev/null +++ b/openair3/SECU/aes_128_ecb.c @@ -0,0 +1,53 @@ +/* + * 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 "aes_128_ecb.h" +#include "common/utils/assertions.h" +#include +#include +#include + +void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]) +{ + DevAssert(k_iv != NULL); + DevAssert(k_iv->type == NONE_INITIALIZATION_VECTOR); + + // Create and initialise the context + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + DevAssert(ctx != NULL); + + // Initialise the encryption operation. + int rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, k_iv->key, NULL); + DevAssert(rc == 1); + + int len_ev = 0; + rc = EVP_EncryptUpdate(ctx, out, &len_ev, msg.buf, msg.len); + DevAssert(!(len_ev > len_out) && "Buffer overflow"); + + // Finalise the encryption. Normally ciphertext bytes may be written at + // this stage, but this does not occur in GCM mode + rc = EVP_EncryptFinal_ex(ctx, out + len_ev, &len_ev); + DevAssert(rc == 1); + + // Get the tag + // rc == EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) + EVP_CIPHER_CTX_free(ctx); +} diff --git a/openair3/SECU/aes_128_ecb.h b/openair3/SECU/aes_128_ecb.h new file mode 100644 index 0000000000..254bdac6b9 --- /dev/null +++ b/openair3/SECU/aes_128_ecb.h @@ -0,0 +1,30 @@ +/* + * 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_ECB_OAI_H +#define AES_128_ECB_OAI_H + +#include "aes_128.h" +#include "common/utils/ds/byte_array.h" + +void aes_128_ecb(const aes_128_t* k_iv, byte_array_t msg, size_t len_out, uint8_t out[len_out]); + +#endif diff --git a/openair3/SECU/key_nas_deriver.c b/openair3/SECU/key_nas_deriver.c index 18cdb3d000..8a7b32ee2f 100644 --- a/openair3/SECU/key_nas_deriver.c +++ b/openair3/SECU/key_nas_deriver.c @@ -19,16 +19,84 @@ * contact@openairinterface.org */ +#include "aes_128.h" +#include "aes_128_cbc_cmac.h" + +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" +#include "kdf.h" +#include "key_nas_deriver.h" +#include "nas_stream_eea1.h" +#include "nas_stream_eea2.h" +#include "nas_stream_eia1.h" +#include "nas_stream_eia2.h" +#include "secu_defs.h" +#include "snow3g.h" +#include +#include +#include #include #include #include #include -#include "security_types.h" -#include "secu_defs.h" -#include "kdf.h" +#define FC_KENB (0x11) +#define FC_NH (0x12) +#define FC_KENB_STAR (0x13) +/* 33401 #A.7 Algorithm for key derivation function. + * This FC should be used for: + * - NAS Encryption algorithm + * - NAS Integrity algorithm + * - RRC Encryption algorithm + * - RRC Integrity algorithm + * - User Plane Encryption algorithm + */ +#define FC_ALG_KEY_DER (0x15) +#define FC_KASME_TO_CK (0x16) + +#define NR_FC_ALG_KEY_DER (0x69) +#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70) + +// #define SECU_DEBUG 1 + +static void derive_key_common(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t FC, uint8_t out[32]) +{ + uint8_t s[7]; +#if defined(SECU_DEBUG) + int i; +#endif + + /* FC */ + s[0] = FC; + + /* P0 = algorithm type distinguisher */ + s[1] = (uint8_t)(alg_type & 0xFF); + + /* L0 = length(P0) = 1 */ + s[2] = 0x00; + s[3] = 0x01; + + /* P1 */ + s[4] = alg_id; + + /* L1 = length(P1) = 1 */ + s[5] = 0x00; + s[6] = 0x01; + +#if defined(SECU_DEBUG) + printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n", __FUNCTION__, FC_ALG_KEY_DER, alg_type, alg_id); + + for (i = 0; i < 7; i ++) { + printf("0x%02x ", s[i]); + } + + printf("\n"); +#endif + + byte_array_t data = {.len = 7, .buf = s}; + kdf(kasme, data, 32, out); +} -#define SECU_DEBUG 1 /*! * @brief Derive the kNASenc from kasme and perform truncate on the generated key to * reduce his size to 128 bits. Definition of the derivation function can @@ -41,50 +109,144 @@ * - 2 for 128-EIA2 AES * @param[in] kasme Key for MME as provided by AUC * @param[out] knas Pointer to reference where output of KDF will be stored. + */ +void derive_key_nas(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t kasme[32], uint8_t knas[32]) +{ + derive_key_common(alg_type, alg_id, kasme, FC_ALG_KEY_DER, knas); +} + +void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]) +{ + uint8_t tmp[32] = {0}; + derive_key_common(alg_type, alg_id, key, NR_FC_ALG_KEY_DER, tmp); + + // Only the last 16 bytes are needed in 5G + memcpy(out, &tmp[16], 16); +} + +/*! + * @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 + * be found in 3GPP TS.33401 #A.7 + * @param[in] alg_type Algorithm distinguisher + * @param[in] alg_id Algorithm identifier. + * Possible values are: + * - 0 for EIA0 algorithm (Null Integrity Protection algorithm) + * - 1 for 128-EIA1 SNOW 3G + * - 2 for 128-EIA2 AES + * @param[in] key The top key used to derive other subkeys + * @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_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t kasme[32], uint8_t *knas) + +#ifndef NAS_UE +void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB) { - uint8_t s[7]; - uint8_t out[32]; -#if defined(SECU_DEBUG) - int i; + 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; + + byte_array_t data = {.buf = s, .len = 7}; + kdf(kasme, data, 32, keNB); +} #endif - /* FC */ - s[0] = FC_ALG_KEY_DER; - - /* P0 = algorithm type distinguisher */ - s[1] = (uint8_t)(nas_alg_type & 0xFF); - - /* L0 = length(P0) = 1 */ - s[2] = 0x00; - s[3] = 0x01; - - /* P1 */ - s[4] = nas_enc_alg_id; - - /* L1 = length(P1) = 1 */ - s[5] = 0x00; - s[6] = 0x01; - -#if defined(SECU_DEBUG) - printf("%s FC %d nas_alg_type distinguisher %d nas_enc_alg_identity %d\n", - __FUNCTION__, FC_ALG_KEY_DER, nas_alg_type, nas_enc_alg_id); - - for (i = 0; i < 7; i ++) { - printf("0x%02x ", s[i]); +void 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; + 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; + data.len = 10; } - printf("\n"); -#endif + kdf(kenb_32, data, 32, kenb_star); - //kdf(kasme, 32, s, 7, out, 32); - byte_array_t data = {.len = 7, .buf = s}; - kdf(kasme, data, 32, out); + // 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. +} - memcpy(knas, &out[31-16+1], 16); +void 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 s[10] = {0}; - return 0; + /* FC */ + s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; + + /* P0 = PCI */ + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); + + /* L0 = length(P0) = 2 */ + s[3] = 0x00; + s[4] = 0x02; + + /* P1 = NR ARFCN */ + s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16; + s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8; + s[7] = (nr_arfcn_dl & 0x000000ff); + + /* L1 = length(P1) = 3 */ + s[8] = 0x00; + s[9] = 0x03; + + byte_array_t data = {.buf = s, .len = 10}; + const uint32_t len_key = 32; + kdf(key, data, len_key, key_ng_ran_star); +} + +void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) +{ + uint8_t s[5] = {0}; + + /* FC is 0x1c (see 3gpp 33.401 annex A.15) */ + s[0] = 0x1c; + + /* put sk_counter */ + s[1] = (sk_counter >> 8) & 0xff; + s[2] = sk_counter & 0xff; + + /* put length of sk_counter (2) */ + s[3] = 0x00; + s[4] = 0x02; + + byte_array_t data = {.buf = s, .len = 5}; + kdf(keNB, data, 32, skgNB); } diff --git a/openair3/SECU/key_nas_deriver.h b/openair3/SECU/key_nas_deriver.h new file mode 100644 index 0000000000..4e84c5f3be --- /dev/null +++ b/openair3/SECU/key_nas_deriver.h @@ -0,0 +1,33 @@ +#ifndef KEY_NAS_DERIVER_H +#define KEY_NAS_DERIVER_H + +#include +#include +#include + +typedef enum { + NAS_ENC_ALG = 0x01, + NAS_INT_ALG = 0x02, + RRC_ENC_ALG = 0x03, + RRC_INT_ALG = 0x04, + UP_ENC_ALG = 0x05, + UP_INT_ALG = 0x06 +} algorithm_type_dist_t; + +void derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB); + +void 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); + +void derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, const uint8_t kasme[32], uint8_t knas[32]); + +void derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB); + +void nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t out[16]); + +void 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); + +#endif diff --git a/openair3/SECU/nas_stream_eea0.c b/openair3/SECU/nas_stream_eea0.c new file mode 100644 index 0000000000..e4be5c7508 --- /dev/null +++ b/openair3/SECU/nas_stream_eea0.c @@ -0,0 +1,44 @@ +/* + * 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 "nas_stream_eea0.h" + +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" + +#include + +void nas_stream_encrypt_eea0(nas_stream_cipher_t const *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"); + + uint32_t byte_length = (stream_cipher->blength + 7) >> 3; + memcpy(out, stream_cipher->message, byte_length); +} diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair3/SECU/nas_stream_eea0.h similarity index 59% rename from openair2/UTIL/OSA/osa_internal.h rename to openair3/SECU/nas_stream_eea0.h index d66a429472..80ada528b5 100644 --- a/openair2/UTIL/OSA/osa_internal.h +++ b/openair3/SECU/nas_stream_eea0.h @@ -19,32 +19,14 @@ * contact@openairinterface.org */ -#ifndef OSA_INTERNAL_H_ -#define OSA_INTERNAL_H_ +#ifndef OAI_NAS_STREAM_EEA0_H +#define OAI_NAS_STREAM_EEA0_H -#define FC_KENB (0x11) -#define FC_NH (0x12) -#define FC_KENB_STAR (0x13) -/* 33401 #A.7 Algorithm for key derivation function. - * This FC should be used for: - * - NAS Encryption algorithm - * - NAS Integrity algorithm - * - RRC Encryption algorithm - * - RRC Integrity algorithm - * - User Plane Encryption algorithm - */ -#define FC_ALG_KEY_DER (0x15) -#define FC_KASME_TO_CK (0x16) +#include "secu_defs.h" -#define NR_FC_ALG_KEY_DER (0x69) -#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70) +#include +#include + +void nas_stream_encrypt_eea0(nas_stream_cipher_t const *stream_cipher, uint8_t *out); -#ifndef hton_int32 -# define hton_int32(x) \ -(((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \ -((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24)) #endif - -// #define SECU_DEBUG - -#endif /* OSA_INTERNAL_H_ */ diff --git a/openair3/SECU/nas_stream_eea1.c b/openair3/SECU/nas_stream_eea1.c index e70d49ea2c..a4e4b84ca4 100644 --- a/openair3/SECU/nas_stream_eea1.c +++ b/openair3/SECU/nas_stream_eea1.c @@ -26,13 +26,10 @@ #include "assertions.h" #include "conversions.h" -#include "secu_defs.h" +#include "nas_stream_eea1.h" #include "snow3g.h" -// #define SECU_DEBUG - - -int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out) +void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out) { snow_3g_context_t snow_3g_context; int n ; @@ -106,6 +103,4 @@ int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out) if (zero_bit > 0) { out[ceil_index - 1] = stream_cipher->message[ceil_index - 1]; } - - return 0; } diff --git a/openair3/SECU/nas_stream_eea1.h b/openair3/SECU/nas_stream_eea1.h new file mode 100644 index 0000000000..d713dc60d3 --- /dev/null +++ b/openair3/SECU/nas_stream_eea1.h @@ -0,0 +1,32 @@ +/* + * 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 OAI_NAS_STREAM_EEA1_H +#define OAI_NAS_STREAM_EEA1_H + +#include "secu_defs.h" + +#include +#include + +void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *out); + +#endif diff --git a/openair3/SECU/nas_stream_eea2.c b/openair3/SECU/nas_stream_eea2.c index 4eeb24b775..dbdc040883 100644 --- a/openair3/SECU/nas_stream_eea2.c +++ b/openair3/SECU/nas_stream_eea2.c @@ -28,9 +28,9 @@ #include "aes_128_ctr.h" #include "assertions.h" #include "conversions.h" -#include "secu_defs.h" +#include "nas_stream_eea2.h" -int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) +void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out) { DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->key != NULL); @@ -53,6 +53,4 @@ int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out) const size_t len_out = byte_lenght; byte_array_t msg = {.buf = stream_cipher->message, .len = byte_lenght}; aes_128_ctr(&p, msg, len_out, out); - - return 0; } diff --git a/openair2/UTIL/OSA/osa_rijndael.h b/openair3/SECU/nas_stream_eea2.h similarity index 96% rename from openair2/UTIL/OSA/osa_rijndael.h rename to openair3/SECU/nas_stream_eea2.h index fcffac5dbf..c6133c987d 100644 --- a/openair2/UTIL/OSA/osa_rijndael.h +++ b/openair3/SECU/nas_stream_eea2.h @@ -1,3 +1,4 @@ + /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,7 +20,12 @@ * contact@openairinterface.org */ +#ifndef OAI_NAS_STREAM_EEA2_H +#define OAI_NAS_STREAM_EEA2_H + +#include "secu_defs.h" #include + /* Rijndael S-box OSA_SR */ static const uint8_t OSA_SR[256] = { @@ -53,3 +59,7 @@ static const uint8_t OSA_SQ[256] = { 0x04, 0xC8, 0x9D, 0xE7, 0x14, 0xB1, 0x87, 0x9C, 0xDF, 0x6F, 0xF9, 0xDA, 0x2A, 0xC4, 0x59, 0x16, 0x74, 0x91, 0xAB, 0x26, 0x61, 0x76, 0x34, 0x2B, 0xAD, 0x99, 0xFB, 0x72, 0xEC, 0x33, 0x12, 0xDE, 0x98, 0x3B, 0xC0, 0x9B, 0x3E, 0x18, 0x10, 0x3A, 0x56, 0xE1, 0x77, 0xC9, 0x1E, 0x9E, 0x95, 0xA3, 0x90, 0x19, 0xA8, 0x6C, 0x09, 0xD0, 0xF0, 0x86}; + +void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *out); + +#endif diff --git a/openair3/SECU/nas_stream_eia1.c b/openair3/SECU/nas_stream_eia1.c index 629d40d612..f080db7aac 100644 --- a/openair3/SECU/nas_stream_eia1.c +++ b/openair3/SECU/nas_stream_eia1.c @@ -25,7 +25,7 @@ #include #include // double ceil(double x); -#include "secu_defs.h" +#include "nas_stream_eia1.h" #include "assertions.h" #include "conversions.h" @@ -33,12 +33,6 @@ #define SECU_DEBUG -uint64_t MUL64x(uint64_t V, uint64_t c); -uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c); -uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c); -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); - - // see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1 /* MUL64x. @@ -49,7 +43,7 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out * function. * See section 4.3.2 for details. */ -uint64_t MUL64x(uint64_t V, uint64_t c) +static uint64_t MUL64x(uint64_t V, uint64_t c) { if ( V & 0x8000000000000000 ) return (V << 1) ^ c; @@ -65,7 +59,7 @@ uint64_t MUL64x(uint64_t V, uint64_t c) function. * See section 4.3.3 for details. */ -uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) +static uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) { if ( i == 0) return V; @@ -81,7 +75,7 @@ uint64_t MUL64xPOW(uint64_t V, uint32_t i, uint64_t c) * function. * See section 4.3.4 for details. */ -uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) +static uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) { uint64_t result = 0; int i = 0; @@ -99,7 +93,7 @@ uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) * Output : a 32 bit mask. * Prepares a 32 bit mask with required number of 1 bits on the MSB side. */ -uint32_t mask32bit(int n) +static uint32_t mask32bit(int n) { uint32_t mask=0x0; @@ -118,7 +112,7 @@ uint32_t mask32bit(int n) * @param[in] stream_cipher Structure containing various variables to setup encoding * @param[out] out For EIA1 the output string is 32 bits long */ -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) +void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t out[4]) { snow_3g_context_t snow_3g_context; uint32_t K[4],IV[4], z[5]; @@ -218,5 +212,4 @@ int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) //printf ("MAC_I:%16X\n",MAC_I); MAC_I = hton_int32(MAC_I); memcpy(out, &MAC_I, 4); - return 0; } diff --git a/openair3/SECU/nas_stream_eia1.h b/openair3/SECU/nas_stream_eia1.h new file mode 100644 index 0000000000..58a7f8be99 --- /dev/null +++ b/openair3/SECU/nas_stream_eia1.h @@ -0,0 +1,29 @@ +/* + * 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 OAI_NAS_STREAM_EIA1_H +#define OAI_NAS_STREAM_EIA1_H + +#include "secu_defs.h" + +void nas_stream_encrypt_eia1(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]); + +#endif diff --git a/openair3/SECU/nas_stream_eia2.c b/openair3/SECU/nas_stream_eia2.c index 4c7951a0f5..2655c8ad81 100644 --- a/openair3/SECU/nas_stream_eia2.c +++ b/openair3/SECU/nas_stream_eia2.c @@ -25,7 +25,7 @@ #include #include -#include "secu_defs.h" +#include "nas_stream_eia2.h" #include #include "aes_128_cbc_cmac.h" @@ -40,7 +40,7 @@ * @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]) +void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t out[4]) { DevAssert(stream_cipher != NULL); DevAssert(stream_cipher->message != NULL); @@ -49,7 +49,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) DevAssert((stream_cipher->blength & 0x7) == 0); aes_128_t k_iv = {0}; - memcpy(&k_iv.key, stream_cipher->key, sizeof(k_iv.key)); + 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; @@ -59,8 +59,7 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) uint8_t result[16] = {0}; byte_array_t msg = {.buf = stream_cipher->message, .len = m_length }; aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result); - + memcpy(out, result, 4); - return 0; } diff --git a/openair3/SECU/nas_stream_eia2.h b/openair3/SECU/nas_stream_eia2.h new file mode 100644 index 0000000000..1349408fb7 --- /dev/null +++ b/openair3/SECU/nas_stream_eia2.h @@ -0,0 +1,29 @@ +/* + * 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 OAI_NAS_STREAM_EIA2_H +#define OAI_NAS_STREAM_EIA2_H + +#include "secu_defs.h" + +void nas_stream_encrypt_eia2(nas_stream_cipher_t const* stream_cipher, uint8_t out[4]); + +#endif diff --git a/openair3/SECU/secu_defs.c b/openair3/SECU/secu_defs.c index 00cf23187e..4a6782de97 100644 --- a/openair3/SECU/secu_defs.c +++ b/openair3/SECU/secu_defs.c @@ -19,78 +19,48 @@ * 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) +#include "common/utils/assertions.h" +#include "common/utils/LOG/log.h" + +#include "nas_stream_eea0.h" +#include "nas_stream_eea1.h" +#include "nas_stream_eea2.h" + +#include "nas_stream_eia1.h" +#include "nas_stream_eia2.h" + +void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t out[4]) { - 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; + if (alg == EIA0_ALG_ID) { + LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg); + } else if (alg == EIA1_128_ALG_ID) { + LOG_D(OSA, "EIA1 algorithm applied for integrity\n"); + nas_stream_encrypt_eia1(stream_cipher, out); + } else if (alg == EIA2_128_ALG_ID) { + LOG_D(OSA, "EIA2 algorithm applied for integrity\n"); + nas_stream_encrypt_eia2(stream_cipher, out); } 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; + LOG_E(OSA, "Provided integrity algorithm is currently not supported = %u\n", alg); + DevAssert(0 != 0 && "Unknown Algorithm type"); + } +} + +void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const* stream_cipher, uint8_t* out) +{ + if (alg == EEA0_ALG_ID) { + LOG_D(OSA, "EEA0 algorithm applied for encryption\n"); + nas_stream_encrypt_eea0(stream_cipher, out); + } else if (alg == EEA1_128_ALG_ID) { + LOG_D(OSA, "EEA1 algorithm applied for encryption\n"); + nas_stream_encrypt_eea1(stream_cipher, out); + } else if (alg == EEA2_128_ALG_ID) { + LOG_D(OSA, "EEA2 algorithm applied for encryption\n"); + nas_stream_encrypt_eea2(stream_cipher, out); + } else { + LOG_E(OSA, "Provided encrypt algorithm is currently not supported = %u\n", alg); + DevAssert(0 != 0 && "Unknown Algorithm type"); } - - kdf (kenb_32, data, 32, kenb_star); - - // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143) - // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8 - // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This - // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the - // EARFCN-DL. - return 0; } diff --git a/openair3/SECU/secu_defs.h b/openair3/SECU/secu_defs.h index 7817db30d3..7b96544bd5 100644 --- a/openair3/SECU/secu_defs.h +++ b/openair3/SECU/secu_defs.h @@ -22,47 +22,9 @@ #ifndef SECU_DEFS_H_ #define SECU_DEFS_H_ -#include "security_types.h" #include #include -#define EIA0_ALG_ID 0x00 -#define EIA1_128_ALG_ID 0x01 -#define EIA2_128_ALG_ID 0x02 - -#define EEA0_ALG_ID 0x00 -#define EEA1_128_ALG_ID 0x01 -#define EEA2_128_ALG_ID 0x02 - -#define SECU_DIRECTION_UPLINK 0 -#define SECU_DIRECTION_DOWNLINK 1 - -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, - const bool is_rel8_only, uint8_t * kenb_star); - -int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t kasme[32], uint8_t *knas); - -#define derive_key_nas_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(NAS_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_nas_int(aLGiD, kASME, kNAS) \ - derive_key_nas(NAS_INT_ALG, aLGiD, kASME, kNAS) - -#define derive_key_rrc_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(RRC_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_rrc_int(aLGiD, kASME, kNAS) \ - derive_key_nas(RRC_INT_ALG, aLGiD, kASME, kNAS) - -#define derive_key_up_enc(aLGiD, kASME, kNAS) \ - derive_key_nas(UP_ENC_ALG, aLGiD, kASME, kNAS) - -#define derive_key_up_int(aLGiD, kASME, kNAS) \ - derive_key_nas(UP_INT_ALG, aLGiD, kASME, kNAS) - #define SECU_DIRECTION_UPLINK 0 #define SECU_DIRECTION_DOWNLINK 1 @@ -77,14 +39,34 @@ typedef struct { uint32_t blength; } nas_stream_cipher_t; -int nas_stream_encrypt_eea1(nas_stream_cipher_t *stream_cipher, uint8_t *out); +/*! + * @brief Encrypt/Decrypt a block of data based on the provided algorithm + * @param[in] algorithm Algorithm used to encrypt the data + * Possible values are: + * - EIA0_ALG_ID for NULL encryption + * - EIA1_128_ALG_ID for SNOW-3G encryption (not avalaible right now) + * - EIA2_128_ALG_ID for 128 bits AES LTE encryption + * @param[in] stream_cipher All parameters used to compute the encrypted block of data + * @param[out] out The encrypted block of data + */ -int nas_stream_encrypt_eia1(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); +typedef enum { + EIA0_ALG_ID = 0x00, + EIA1_128_ALG_ID = 0x01, + EIA2_128_ALG_ID = 0x02, + END_EIA0_ALG_ID, +} eia_alg_id_e; -int nas_stream_encrypt_eea2(nas_stream_cipher_t *stream_cipher, uint8_t *out); +void stream_compute_integrity(eia_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t out[4]); -int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]); +typedef enum { + EEA0_ALG_ID = 0x00, + EEA1_128_ALG_ID = 0x01, + EEA2_128_ALG_ID = 0x02, -#undef SECU_DEBUG + END_EEA_ALG_ID +} eea_alg_id_e; + +void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const *stream_cipher, uint8_t *out); #endif /* SECU_DEFS_H_ */ diff --git a/openair3/TEST/test_secu_knas_encrypt_eea1.c b/openair3/TEST/test_secu_knas_encrypt_eea1.c index aa1b57a6ba..03708a9575 100644 --- a/openair3/TEST/test_secu_knas_encrypt_eea1.c +++ b/openair3/TEST/test_secu_knas_encrypt_eea1.c @@ -52,8 +52,7 @@ void eea1_encrypt(uint8_t direction, uint32_t count, nas_cipher->blength = length; nas_cipher->message = message; - if (nas_stream_encrypt_eea1(nas_cipher, result) != 0) - fail("Fail: nas_stream_encrypt_eea1\n"); + stream_compute_encrypt(EEA1_128_ALG_ID, nas_cipher, result); if (compare_buffer(result, byte_length, expected, byte_length) != 0) { fail("Fail: eea1_encrypt\n"); diff --git a/openair3/TEST/test_secu_knas_encrypt_eea2.c b/openair3/TEST/test_secu_knas_encrypt_eea2.c index 78a2b6fecc..e559149f99 100644 --- a/openair3/TEST/test_secu_knas_encrypt_eea2.c +++ b/openair3/TEST/test_secu_knas_encrypt_eea2.c @@ -25,7 +25,6 @@ #include #include "test_util.h" - #include "secu_defs.h" static @@ -52,8 +51,7 @@ void eea2_encrypt(uint8_t direction, uint32_t count, nas_cipher->blength = length; nas_cipher->message = message; - if (nas_stream_encrypt_eea2(nas_cipher, result) != 0) - fail("Fail: nas_stream_encrypt_eea2\n"); + nas_stream_encrypt_eea2(nas_cipher, result); if (compare_buffer(result, byte_length, expected, byte_length) != 0) { fail("Fail: eea2_encrypt\n");