diff --git a/srsepc/epc.conf.example b/srsepc/epc.conf.example index 12562f1f0..55004d5c2 100644 --- a/srsepc/epc.conf.example +++ b/srsepc/epc.conf.example @@ -13,6 +13,10 @@ # apn: Set Access Point Name (APN) # mme_bind_addr: IP bind addr to listen for eNB S1-MME connnections # dns_addr: DNS server address for the UEs +# encryption_algo: Preferred encryption algorithm for NAS layer +# (default: EEA0, support: EEA1, EEA2) +# integrity_algo: Preferred integrity protection algorithm for NAS +# (default: EIA1, support: EIA1, EIA2 (EIA0 not support) # ##################################################################### [mme] @@ -24,6 +28,8 @@ mnc = 01 mme_bind_addr = 127.0.1.100 apn = srsapn dns_addr = 8.8.8.8 +encryption_algo = EEA0 +integrity_algo = EIA1 ##################################################################### # HSS configuration diff --git a/srsepc/hdr/mme/s1ap_common.h b/srsepc/hdr/mme/s1ap_common.h index e5c198748..200c172e1 100644 --- a/srsepc/hdr/mme/s1ap_common.h +++ b/srsepc/hdr/mme/s1ap_common.h @@ -95,6 +95,8 @@ typedef struct{ std::string mme_apn; bool pcap_enable; std::string pcap_filename; + srslte::CIPHERING_ALGORITHM_ID_ENUM encryption_algo; + srslte::INTEGRITY_ALGORITHM_ID_ENUM integrity_algo; } s1ap_args_t; typedef struct{ diff --git a/srsepc/src/main.cc b/srsepc/src/main.cc index b34114363..32c3be05a 100644 --- a/srsepc/src/main.cc +++ b/srsepc/src/main.cc @@ -85,6 +85,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) { string mnc; string mme_bind_addr; string mme_apn; + string encryption_algo; + string integrity_algo; string spgw_bind_addr; string sgi_if_addr; string sgi_if_name; @@ -113,6 +115,8 @@ parse_args(all_args_t *args, int argc, char* argv[]) { ("mme.mme_bind_addr", bpo::value(&mme_bind_addr)->default_value("127.0.0.1"), "IP address of MME for S1 connnection") ("mme.dns_addr", bpo::value(&dns_addr)->default_value("8.8.8.8"), "IP address of the DNS server for the UEs") ("mme.apn", bpo::value(&mme_apn)->default_value(""), "Set Access Point Name (APN) for data services") + ("mme.encryption_algo", bpo::value(&encryption_algo)->default_value("EEA0"), "Set preferred encryption algorithm for NAS layer ") + ("mme.integrity_algo", bpo::value(&integrity_algo)->default_value("EIA1"), "Set preferred integrity protection algorithm for NAS") ("hss.db_file", bpo::value(&hss_db_file)->default_value("ue_db.csv"), ".csv file that stores UE's keys") ("hss.auth_algo", bpo::value(&hss_auth_algo)->default_value("milenage"), "HSS uthentication algorithm.") ("spgw.gtpu_bind_addr", bpo::value(&spgw_bind_addr)->default_value("127.0.0.1"), "IP address of SP-GW for the S1-U connection") @@ -215,6 +219,31 @@ parse_args(all_args_t *args, int argc, char* argv[]) { cout << "Error parsing mme.mnc:" << mnc << " - must be a 2 or 3-digit string." << endl; } + if(boost::iequals(encryption_algo, "eea0")){ + args->mme_args.s1ap_args.encryption_algo = srslte::CIPHERING_ALGORITHM_ID_EEA0; + } else if (boost::iequals(encryption_algo, "eea1")){ + args->mme_args.s1ap_args.encryption_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA1; + } else if (boost::iequals(encryption_algo, "eea2")){ + args->mme_args.s1ap_args.encryption_algo = srslte::CIPHERING_ALGORITHM_ID_128_EEA2; + } else{ + args->mme_args.s1ap_args.encryption_algo = srslte::CIPHERING_ALGORITHM_ID_EEA0; + cout << "Error parsing mme.encryption_algo:" << encryption_algo << " - must be EEA0, EEA1, or EEA2." << endl; + cout << "Using default mme.encryption_algo: EEA0" << endl; + } + + if (boost::iequals(integrity_algo, "eia0")){ + args->mme_args.s1ap_args.integrity_algo = srslte::INTEGRITY_ALGORITHM_ID_EIA0; + cout << "Warning parsing mme.integrity_algo:" << encryption_algo << " - EIA0 will not supported by UEs use EIA1 or EIA2" << endl; + } else if (boost::iequals(integrity_algo, "eia1")) { + args->mme_args.s1ap_args.integrity_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA1; + } else if (boost::iequals(integrity_algo, "eia2")) { + args->mme_args.s1ap_args.integrity_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA2; + } else { + args->mme_args.s1ap_args.integrity_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA1; + cout << "Error parsing mme.integrity_algo:" << encryption_algo << " - must be EIA0, EIA1, or EIA2." << endl; + cout << "Using default mme.integrity_algo: EIA1" << endl; + } + args->mme_args.s1ap_args.mme_bind_addr = mme_bind_addr; args->mme_args.s1ap_args.mme_name = mme_name; args->mme_args.s1ap_args.dns_addr = dns_addr; diff --git a/srsepc/src/mme/s1ap_nas_transport.cc b/srsepc/src/mme/s1ap_nas_transport.cc index 320eee347..98db74143 100644 --- a/srsepc/src/mme/s1ap_nas_transport.cc +++ b/srsepc/src/mme/s1ap_nas_transport.cc @@ -1655,13 +1655,14 @@ s1ap_nas_transport::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, //Pack NAS PDU LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sm_cmd; - // FIXME Selection based on UE caps and network preferences - - ue_emm_ctx->security_ctxt.cipher_algo = srslte::CIPHERING_ALGORITHM_ID_EEA0; - ue_emm_ctx->security_ctxt.integ_algo = srslte::INTEGRITY_ALGORITHM_ID_128_EIA1; + // FIXME: Selection based on UE caps and network preferences + ue_emm_ctx->security_ctxt.cipher_algo = m_s1ap->m_s1ap_args.encryption_algo; + ue_emm_ctx->security_ctxt.integ_algo = m_s1ap->m_s1ap_args.integrity_algo; + + sm_cmd.selected_nas_sec_algs.type_of_eea = (LIBLTE_MME_TYPE_OF_CIPHERING_ALGORITHM_ENUM) ue_emm_ctx->security_ctxt.cipher_algo; + sm_cmd.selected_nas_sec_algs.type_of_eia = (LIBLTE_MME_TYPE_OF_INTEGRITY_ALGORITHM_ENUM) ue_emm_ctx->security_ctxt.integ_algo; - sm_cmd.selected_nas_sec_algs.type_of_eea = LIBLTE_MME_TYPE_OF_CIPHERING_ALGORITHM_EEA0; - sm_cmd.selected_nas_sec_algs.type_of_eia = LIBLTE_MME_TYPE_OF_INTEGRITY_ALGORITHM_128_EIA1; + m_s1ap_log->info("Using security algorithms: EEA%d, EIA%d \n", (int) ue_emm_ctx->security_ctxt.cipher_algo, (int) ue_emm_ctx->security_ctxt.integ_algo); sm_cmd.nas_ksi.tsc_flag=LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; sm_cmd.nas_ksi.nas_ksi=ue_emm_ctx->security_ctxt.eksi;