From 84f94b26b2ac0395c62d9b71f3655c2d42024b7a Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 23 Nov 2021 12:55:23 +0000 Subject: [PATCH] gnb,rlc_nr: re-used security algo preference list from LTE. Added the ability to enable integrity/encription at the PDCP upon the security mode command. --- srsenb/src/enb_cfg_parser.cc | 50 +++++++++++++++++++++++++++++++ srsgnb/src/stack/rrc/rrc_nr.cc | 8 +++++ srsgnb/src/stack/rrc/rrc_nr_ue.cc | 21 +++++++++++-- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 67751a34e..e23b065b8 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -1224,6 +1224,56 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr args_->nr_stack.ngap.gtp_advertise_addr = args_->stack.s1ap.gtp_advertise_addr; args_->nr_stack.ngap.amf_addr = args_->stack.s1ap.mme_addr; args_->nr_stack.ngap.ngc_bind_addr = args_->stack.s1ap.gtp_bind_addr; + + // Parse EEA preference list (use same as LTE for now) + std::vector eea_pref_list; + boost::split(eea_pref_list, args_->general.eea_pref_list, boost::is_any_of(",")); + int i = 0; + for (auto it = eea_pref_list.begin(); it != eea_pref_list.end() && i < srsran::CIPHERING_ALGORITHM_ID_N_ITEMS; + it++) { + boost::trim_left(*it); + if ((*it) == "EEA0") { + rrc_nr_cfg_->nea_preference_list[i] = srsran::CIPHERING_ALGORITHM_ID_NR_NEA0; + i++; + } else if ((*it) == "EEA1") { + rrc_nr_cfg_->nea_preference_list[i] = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1; + i++; + } else if ((*it) == "EEA2") { + rrc_nr_cfg_->nea_preference_list[i] = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2; + i++; + } else if ((*it) == "EEA3") { + rrc_nr_cfg_->nea_preference_list[i] = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3; + i++; + } else { + fprintf(stderr, "Failed to parse EEA prefence list %s \n", args_->general.eea_pref_list.c_str()); + return SRSRAN_ERROR; + } + } + + // Parse EIA preference list (use same as LTE for now) + std::vector eia_pref_list; + boost::split(eia_pref_list, args_->general.eia_pref_list, boost::is_any_of(",")); + i = 0; + for (auto it = eia_pref_list.begin(); it != eia_pref_list.end() && i < srsran::INTEGRITY_ALGORITHM_ID_N_ITEMS; + it++) { + boost::trim_left(*it); + if ((*it) == "EIA0") { + rrc_nr_cfg_->nia_preference_list[i] = srsran::INTEGRITY_ALGORITHM_ID_NR_NIA0; + i++; + } else if ((*it) == "EIA1") { + rrc_nr_cfg_->nia_preference_list[i] = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1; + i++; + } else if ((*it) == "EIA2") { + rrc_nr_cfg_->nia_preference_list[i] = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2; + i++; + } else if ((*it) == "EIA3") { + rrc_nr_cfg_->nia_preference_list[i] = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3; + i++; + } else { + fprintf(stderr, "Failed to parse EIA prefence list %s \n", args_->general.eia_pref_list.c_str()); + return SRSRAN_ERROR; + } + } } else { // NSA mode. // update EUTRA RRC params for ENDC diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc index 5a8bbc4fb..20523a282 100644 --- a/srsgnb/src/stack/rrc/rrc_nr.cc +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -85,6 +85,14 @@ int rrc_nr::init(const rrc_nr_cfg_t& cfg_, config_phy(); // if PHY is not yet initialized, config will be stored and applied on initialization config_mac(); + logger.debug("NIA preference list: NIA%d, NIA%d, NIA%d", + cfg.nia_preference_list[0], + cfg.nia_preference_list[1], + cfg.nia_preference_list[2]); + logger.debug("NEA preference list: NEA%d, NEA%d, NEA%d", + cfg.nea_preference_list[0], + cfg.nea_preference_list[1], + cfg.nea_preference_list[2]); running = true; return SRSRAN_SUCCESS; diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index 0e22134c3..828f908e3 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -984,13 +984,27 @@ void rrc_nr::ue::handle_rrc_setup_complete(const asn1::rrc_nr::rrc_setup_complet /// TS 38.331, SecurityModeCommand void rrc_nr::ue::send_security_mode_command() { + // FIXME: Currently we are using the PDCP-LTE, so we need to convert from nr_as_security_cfg to as_security_config. + // When we start using PDCP-NR we can avoid this step. + srsran::nr_as_security_config_t tmp_cnfg = sec_ctx.get_as_sec_cfg(); + srsran::as_security_config_t pdcp_cnfg = {}; + pdcp_cnfg.k_rrc_int = tmp_cnfg.k_nr_rrc_int; + pdcp_cnfg.k_rrc_enc = tmp_cnfg.k_nr_rrc_enc; + pdcp_cnfg.k_up_int = tmp_cnfg.k_nr_up_int; + pdcp_cnfg.k_up_enc = tmp_cnfg.k_nr_up_enc; + pdcp_cnfg.integ_algo = (srsran::INTEGRITY_ALGORITHM_ID_ENUM)tmp_cnfg.integ_algo; + pdcp_cnfg.cipher_algo = (srsran::CIPHERING_ALGORITHM_ID_ENUM)tmp_cnfg.cipher_algo; + + // Setup SRB1 security/integrity. Encryption is set on completion + parent->pdcp->config_security(rnti, srb_to_lcid(srsran::nr_srb::srb1), pdcp_cnfg); + parent->pdcp->enable_integrity(rnti, srb_to_lcid(srsran::nr_srb::srb1)); + asn1::rrc_nr::dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg.msg.set_c1().set_security_mode_cmd().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); security_mode_cmd_ies_s& ies = dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.set_security_mode_cmd(); ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm_present = true; - ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm.value = integrity_prot_algorithm_opts::nia0; - ies.security_cfg_smc.security_algorithm_cfg.ciphering_algorithm.value = ciphering_algorithm_opts::nea0; + ies.security_cfg_smc.security_algorithm_cfg = sec_ctx.get_security_algorithm_cfg(); if (send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg) != SRSRAN_SUCCESS) { send_rrc_release(); @@ -1000,7 +1014,8 @@ void rrc_nr::ue::send_security_mode_command() /// TS 38.331, SecurityModeComplete void rrc_nr::ue::handle_security_mode_complete(const asn1::rrc_nr::security_mode_complete_s& msg) { - // TODO: handle SecurityModeComplete + parent->logger.info("SecurityModeComplete transaction ID: %d", msg.rrc_transaction_id); + parent->pdcp->enable_encryption(rnti, srb_to_lcid(srsran::nr_srb::srb1)); // Note: Skip UE capabilities }