From 6d401bc79f5ee82823d7a1083cc433a801a392f7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 13 Apr 2021 10:16:58 +0100 Subject: [PATCH] handover - check if UE integrity and encryption algorithms are supported in the target eNB, and report handover failure if not. --- srsenb/hdr/stack/rrc/rrc_mobility.h | 5 +++-- srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 2 -- srsenb/src/stack/rrc/rrc_mobility.cc | 26 +++++++++++++++----------- srsenb/test/upper/rrc_mobility_test.cc | 15 ++++++++------- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 3efd607a4..50e4b66d8 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -60,9 +60,10 @@ private: const enb_cell_common& target_cell, uint32_t src_dl_earfcn, uint32_t src_pci); - void apply_ho_prep_cfg(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep, + bool apply_ho_prep_cfg(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep, const asn1::s1ap::ho_request_s& ho_req_msg, - std::vector& erabs_failed_to_setup); + std::vector& erabs_failed_to_setup, + asn1::s1ap::cause_c& cause); rrc::ue* rrc_ue = nullptr; rrc* rrc_enb = nullptr; diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 1809df990..124f1beee 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -147,8 +147,6 @@ bool security_cfg_handler::set_security_capabilities(const asn1::s1ap::ue_securi } if (not integ_algo_found || not enc_algo_found) { - // TODO: if no security algorithm found abort radio connection and issue - // encryption-and-or-integrity-protection-algorithms-not-supported message logger.error("Did not find a matching integrity or encryption algorithm with the UE"); return false; } diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index aff8ab4d7..b42890433 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -678,6 +678,7 @@ void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cancel(const ho_cancel_ev */ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& ho_req) { + asn1::s1ap::cause_c cause; // in case of failure const auto& rrc_container = ho_req.transparent_container->rrc_container; std::vector not_admitted_erabs; auto& fwd_tunnels = get_state()->pending_tunnels; @@ -688,7 +689,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& asn1::rrc::ho_prep_info_s hoprep; if (hoprep.unpack(bref) != asn1::SRSASN_SUCCESS) { rrc_enb->logger.error("Failed to decode HandoverPreparationinformation in S1AP SourceENBToTargetENBContainer"); - asn1::s1ap::cause_c cause; cause.set_protocol().value = asn1::s1ap::cause_protocol_opts::transfer_syntax_error; trigger(ho_failure_ev{cause}); return; @@ -696,7 +696,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& if (hoprep.crit_exts.type().value != c1_or_crit_ext_opts::c1 or hoprep.crit_exts.c1().type().value != ho_prep_info_s::crit_exts_c_::c1_c_::types_opts::ho_prep_info_r8) { rrc_enb->logger.error("Only release 8 supported"); - asn1::s1ap::cause_c cause; cause.set_protocol().value = asn1::s1ap::cause_protocol_opts::semantic_error; trigger(ho_failure_ev{cause}); return; @@ -705,7 +704,10 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& /* Setup UE current state in TeNB based on HandoverPreparation message */ const ho_prep_info_r8_ies_s& hoprep_r8 = hoprep.crit_exts.c1().ho_prep_info_r8(); - apply_ho_prep_cfg(hoprep_r8, *ho_req.ho_req_msg, not_admitted_erabs); + if (not apply_ho_prep_cfg(hoprep_r8, *ho_req.ho_req_msg, not_admitted_erabs, cause)) { + trigger(ho_failure_ev{cause}); + return; + } /* Prepare Handover Request Acknowledgment - Handover Command */ dl_dcch_msg_s dl_dcch_msg; @@ -733,7 +735,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& srsran::unique_byte_buffer_t ho_cmd_pdu = srsran::make_byte_buffer(); if (ho_cmd_pdu == nullptr) { logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); - asn1::s1ap::cause_c cause; cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::no_radio_res_available_in_target_cell; trigger(ho_failure_ev{cause}); return; @@ -741,7 +742,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& asn1::bit_ref bref2{ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()}; if (dl_dcch_msg.pack(bref2) != asn1::SRSASN_SUCCESS) { logger.error("Failed to pack HandoverCommand"); - asn1::s1ap::cause_c cause; cause.set_protocol().value = asn1::s1ap::cause_protocol_opts::transfer_syntax_error; trigger(ho_failure_ev{cause}); return; @@ -756,7 +756,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& bref2 = {ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()}; if (ho_cmd.pack(bref2) != asn1::SRSASN_SUCCESS) { logger.error("Failed to pack HandoverCommand"); - asn1::s1ap::cause_c cause; cause.set_protocol().value = asn1::s1ap::cause_protocol_opts::transfer_syntax_error; trigger(ho_failure_ev{cause}); return; @@ -819,7 +818,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& /// If the target eNB does not admit at least one non-GBR E-RAB, ..., it shall send the HANDOVER FAILURE message ... if (admitted_erabs.empty()) { - asn1::s1ap::cause_c cause; cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::unspecified; if (not not_admitted_erabs.empty()) { cause = not_admitted_erabs[0].cause; @@ -835,7 +833,6 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& std::move(ho_cmd_pdu), admitted_erabs, not_admitted_erabs)) { - asn1::s1ap::cause_c cause; cause.set_protocol().value = asn1::s1ap::cause_protocol_opts::transfer_syntax_error; trigger(ho_failure_ev{cause}); return; @@ -848,9 +845,10 @@ void rrc::ue::rrc_mobility::handle_ho_failure(const ho_failure_ev& ev) failure_cause = ev.cause; } -void rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho_prep, +bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho_prep, const asn1::s1ap::ho_request_s& ho_req_msg, - std::vector& erabs_failed_to_setup) + std::vector& erabs_failed_to_setup, + asn1::s1ap::cause_c& cause) { const ue_cell_ded* target_cell = rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX); const cell_cfg_t& target_cell_cfg = target_cell->cell_common->cell_cfg; @@ -892,7 +890,11 @@ void rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& // Regenerate AS Keys // See TS 33.401, Sec. 7.2.8.4.3 - rrc_ue->ue_security_cfg.set_security_capabilities(ho_req_msg.protocol_ies.ue_security_cap.value); + if (not rrc_ue->ue_security_cfg.set_security_capabilities(ho_req_msg.protocol_ies.ue_security_cap.value)) { + cause.set_radio_network().value = + asn1::s1ap::cause_radio_network_opts::encryption_and_or_integrity_protection_algorithms_not_supported; + return false; + } rrc_ue->ue_security_cfg.set_security_key(ho_req_msg.protocol_ies.security_context.value.next_hop_param); rrc_ue->ue_security_cfg.set_ncc(ho_req_msg.protocol_ies.security_context.value.next_hop_chaining_count); rrc_ue->ue_security_cfg.regenerate_keys_handover(target_cell_cfg.pci, target_cell_cfg.dl_earfcn); @@ -926,6 +928,8 @@ void rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& // Save source UE MAC configuration as a base rrc_ue->mac_ctrl.handle_ho_prep(ho_prep); + + return true; } void rrc::ue::rrc_mobility::handle_recfg_complete(wait_recfg_comp& s, const recfg_complete_ev& ev) diff --git a/srsenb/test/upper/rrc_mobility_test.cc b/srsenb/test/upper/rrc_mobility_test.cc index e1df237c0..c9167141d 100644 --- a/srsenb/test/upper/rrc_mobility_test.cc +++ b/srsenb/test/upper/rrc_mobility_test.cc @@ -279,11 +279,19 @@ int test_s1ap_tenb_mobility(mobility_test_params test_params) if (test_params.fail_at == mobility_test_params::test_event::wrong_qos) { erab.erab_level_qos_params.qci = 10; } + ho_req.protocol_ies.ue_security_cap.value.integrity_protection_algorithms.set(14, true); asn1::s1ap::sourceenb_to_targetenb_transparent_container_s container; container.target_cell_id.cell_id.from_number(0x19C02); if (test_params.fail_at == mobility_test_params::test_event::wrong_target_cell) { container.target_cell_id.cell_id.from_number(0x19C03); } + container.erab_info_list_present = true; + container.erab_info_list.resize(1); + container.erab_info_list[0].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); + container.erab_info_list[0].value.erab_info_list_item().erab_id = 5; + container.erab_info_list[0].value.erab_info_list_item().dl_forwarding_present = true; + container.erab_info_list[0].value.erab_info_list_item().dl_forwarding.value = + asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed; uint8_t ho_prep_container[] = { 0x0a, 0x10, 0x0b, 0x81, 0x80, 0x00, 0x01, 0x80, 0x00, 0xf3, 0x02, 0x08, 0x00, 0x00, 0x15, 0x80, 0x00, 0x14, 0x06, 0xa4, 0x02, 0xf0, 0x04, 0x04, 0xf0, 0x00, 0x14, 0x80, 0x4a, 0x00, 0x00, 0x00, 0x02, 0x12, 0x31, 0xb6, @@ -293,13 +301,6 @@ int test_s1ap_tenb_mobility(mobility_test_params test_params) 0x5c, 0xe1, 0x86, 0x35, 0x39, 0x80, 0x0e, 0x06, 0xa4, 0x40, 0x0f, 0x22, 0x78}; // 0a100b818000018000f3020800001580001406a402f00404f00014804a000000021231b6f83ea06f05e465141d39d0544c00025400200460000000100100c000000000020500041400670dfbc46606500f00080020800c14ca2d5ce1863539800e06a4400f2278 container.rrc_container.resize(sizeof(ho_prep_container)); - container.erab_info_list_present = true; - container.erab_info_list.resize(1); - container.erab_info_list[0].load_info_obj(ASN1_S1AP_ID_ERAB_INFO_LIST_ITEM); - container.erab_info_list[0].value.erab_info_list_item().erab_id = 5; - container.erab_info_list[0].value.erab_info_list_item().dl_forwarding_present = true; - container.erab_info_list[0].value.erab_info_list_item().dl_forwarding.value = - asn1::s1ap::dl_forwarding_opts::dl_forwarding_proposed; memcpy(container.rrc_container.data(), ho_prep_container, sizeof(ho_prep_container)); asn1::s1ap::cause_c cause; int rnti = tester.rrc.start_ho_ue_resource_alloc(ho_req, container, cause);