From e7c10270fa4d1d56aade17c4bf9d6dd1b54f23cf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sun, 1 Mar 2020 15:05:51 +0100 Subject: [PATCH] ttcn3_ss: fix security activation for PDCP --- srsue/test/ttcn3/hdr/ttcn3_helpers.h | 4 +- srsue/test/ttcn3/hdr/ttcn3_interfaces.h | 25 ++-- srsue/test/ttcn3/hdr/ttcn3_sys_interface.h | 30 ++++- srsue/test/ttcn3/hdr/ttcn3_syssim.h | 131 ++++++++++++++------- 4 files changed, 136 insertions(+), 54 deletions(-) diff --git a/srsue/test/ttcn3/hdr/ttcn3_helpers.h b/srsue/test/ttcn3/hdr/ttcn3_helpers.h index 19ed29c87..91fd7e0d4 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_helpers.h +++ b/srsue/test/ttcn3/hdr/ttcn3_helpers.h @@ -48,9 +48,11 @@ public: } timing_info_t; typedef struct { - bool rb_is_srb; uint8_t rb_id; + bool rb_is_srb; + bool ul_value_valid; uint16_t ul_value; + bool dl_value_valid; uint16_t dl_value; } pdcp_count_t; typedef std::vector pdcp_count_map_t; diff --git a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h index 624215af8..c817da660 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h +++ b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h @@ -44,37 +44,44 @@ class ss_sys_interface public: virtual void add_bcch_dlsch_pdu(const std::string cell_name, srslte::unique_byte_buffer_t pdu) = 0; virtual void add_pch_pdu(srslte::unique_byte_buffer_t pdu) = 0; + virtual void set_cell_attenuation(const ttcn3_helpers::timing_info_t timing, const std::string cell_name, - const float attenuation) = 0; + const float attenuation) = 0; + virtual void set_cell_config(const ttcn3_helpers::timing_info_t timing, const std::string cell_name, const uint32_t earfcn, const srslte_cell_t cell, - const float power) = 0; + const float power) = 0; + virtual void - add_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const srslte::pdcp_config_t pdcp_config) = 0; - virtual void del_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid) = 0; - virtual uint32_t get_tti() = 0; + add_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid, const srslte::pdcp_config_t pdcp_config) = 0; + virtual void del_srb(const ttcn3_helpers::timing_info_t timing, const uint32_t lcid) = 0; + virtual void set_as_security(const ttcn3_helpers::timing_info_t timing, - const uint32_t lcid, const std::array k_rrc_enc, const std::array k_rrc_int, const std::array k_up_enc, const srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; + const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo, + const ttcn3_helpers::pdcp_count_map_t bearers) = 0; virtual void release_as_security(const ttcn3_helpers::timing_info_t timing) = 0; - virtual ttcn3_helpers::pdcp_count_map_t get_pdcp_count() = 0; + + virtual ttcn3_helpers::pdcp_count_map_t get_pdcp_count() = 0; + virtual uint32_t get_tti() = 0; }; class ss_srb_interface { public: virtual void add_ccch_pdu(const ttcn3_helpers::timing_info_t timing, srslte::unique_byte_buffer_t pdu) = 0; + virtual void add_dcch_pdu(const ttcn3_helpers::timing_info_t timing, uint32_t lcid, srslte::unique_byte_buffer_t pdu, - bool follow_on_flag) = 0; + bool follow_on_flag) = 0; + virtual void reestablish_bearer(uint32_t lcid) = 0; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h index 4aa10f492..bf5eaaf07 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h @@ -456,22 +456,44 @@ private: std::array k_up_enc = get_key_from_string(up_enc_key_string); log->debug_hex(k_up_enc.data(), k_up_enc.size(), "K_UP_enc"); - // get LCID - uint32_t lcid = 0; + // parse ActTimeList + ttcn3_helpers::pdcp_count_map_t bearers; if (as_sec["StartRestart"]["Ciphering"].HasMember("ActTimeList")) { const Value& act_time_list = as_sec["StartRestart"]["Ciphering"]["ActTimeList"]; if (act_time_list.IsArray()) { for (Value::ConstValueIterator itr = act_time_list.Begin(); itr != act_time_list.End(); ++itr) { + ttcn3_helpers::pdcp_count_t bearer = {}; + + // obtain LCID and type if (itr->HasMember("RadioBearerId") && (*itr)["RadioBearerId"].HasMember("Srb")) { - lcid = (*itr)["RadioBearerId"]["Srb"].GetInt(); + bearer.rb_is_srb = true; + bearer.rb_id = (*itr)["RadioBearerId"]["Srb"].GetInt(); + } else if (itr->HasMember("RadioBearerId") && (*itr)["RadioBearerId"].HasMember("Drb")) { + bearer.rb_is_srb = false; + bearer.rb_id = (*itr)["RadioBearerId"]["Drb"].GetInt(); } + + // obtain UL count + if (itr->HasMember("UL")) { + bearer.ul_value = (*itr)["UL"]["SQN"]["Value"].GetInt(); + bearer.ul_value_valid = true; + } + + // obtain DL count + if (itr->HasMember("DL")) { + bearer.dl_value = (*itr)["DL"]["SQN"]["Value"].GetInt(); + bearer.dl_value_valid = true; + } + + // append to list + bearers.push_back(bearer); } } } // configure SS to use AS security syssim->set_as_security( - ttcn3_helpers::get_timing_info(document), lcid, k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); + ttcn3_helpers::get_timing_info(document), k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo, bearers); } else if (as_sec.HasMember("Release")) { // release all security configs syssim->release_as_security(ttcn3_helpers::get_timing_info(document)); diff --git a/srsue/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/test/ttcn3/hdr/ttcn3_syssim.h index 10d9b8c09..7c6a84fc3 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/test/ttcn3/hdr/ttcn3_syssim.h @@ -209,6 +209,12 @@ public: } } + // trying to apply pending PDCP config + if (not pending_bearer_config.empty()) { + log.debug("Trying to apply pending PDCP config\n"); + pending_bearer_config = try_set_pdcp_security(pending_bearer_config); + } + // process events, if any while (not event_queue.empty()) { ss_events_t ev = event_queue.wait_pop(); @@ -364,8 +370,8 @@ public: rlc.reset(); pdcp.reset(); cells.clear(); - pcell_idx = -1; - as_security_enabled = false; + pcell_idx = -1; + pending_bearer_config.clear(); } // Called from UT before starting testcase @@ -881,14 +887,6 @@ public: log.info("Adding SRB%d\n", lcid); pdcp.add_bearer(lcid, pdcp_config); rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid)); - - // Enable security for SRB2 - if (lcid == 2) { - log.info("Enabling AS security for LCID=%d\n", lcid); - pdcp.config_security(lcid, k_rrc_enc.data(), k_rrc_int.data(), k_up_enc.data(), cipher_algo, integ_algo); - pdcp.enable_encryption(lcid); - pdcp.enable_integrity(lcid); - } } void reestablish_bearer(uint32_t lcid) @@ -995,50 +993,103 @@ public: bool rb_is_um(uint32_t lcid) { return false; } void set_as_security(const ttcn3_helpers::timing_info_t timing, - const uint32_t lcid, std::array k_rrc_enc_, std::array k_rrc_int_, std::array k_up_enc_, const srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, - const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) + const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_, + const ttcn3_helpers::pdcp_count_map_t bearers_) { if (timing.now) { - set_as_security_impl(lcid, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_); + set_as_security_impl(k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_); } else { - log.debug("Scheduling AS security configuration of lcid=%d for TTI=%d\n", lcid, timing.tti); - tti_actions[timing.tti].push_back([this, lcid, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_]() { - set_as_security_impl(lcid, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_); - }); + log.debug("Scheduling AS security configuration for TTI=%d\n", timing.tti); + tti_actions[timing.tti].push_back( + [this, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_]() { + set_as_security_impl(k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_, bearers_); + }); } } - void set_as_security_impl(const uint32_t lcid, - std::array k_rrc_enc_, + void set_as_security_impl(std::array k_rrc_enc_, std::array k_rrc_int_, std::array k_up_enc_, const srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, - const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) + const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_, + const ttcn3_helpers::pdcp_count_map_t bearers) { - log.info("Setting AS security for LCID=%d\n", lcid); - pdcp.config_security(lcid, k_rrc_enc_.data(), k_rrc_int_.data(), k_up_enc_.data(), cipher_algo_, integ_algo_); - pdcp.enable_integrity(lcid); - pdcp.enable_encryption(lcid); + // store security config for later use (i.e. new bearer added) + k_rrc_enc = k_rrc_enc_; + k_rrc_int = k_rrc_int_; + k_up_enc = k_up_enc_; + cipher_algo = cipher_algo_; + integ_algo = integ_algo_; - // if SRB2 is established, also apply security config - uint32_t srb2_lcid = 2; - if (pdcp.is_lcid_enabled(2)) { - log.info("Updating AS security for LCID=%d\n", srb2_lcid); - pdcp.config_security( - srb2_lcid, k_rrc_enc_.data(), k_rrc_int_.data(), k_up_enc_.data(), cipher_algo_, integ_algo_); + // try to apply security config on bearers + pending_bearer_config = try_set_pdcp_security(bearers); + } + + /** + * Try to configure PDCP security on the list of provided bearers. + * + * The function iterates over the map of bearers and tries to set/update + * the security settings, if and only if, the current DL/UL counter match + * with the requested values in the bearer map. + * + * The function returns a map of bearers for which it could not update the + * configuration. + * + * @param bearers for which PDCP configuration should be updated + * @return list of bearers for which update could not be carried out (fully) + */ + ttcn3_helpers::pdcp_count_map_t try_set_pdcp_security(ttcn3_helpers::pdcp_count_map_t bearers) + { + ttcn3_helpers::pdcp_count_map_t update_needed_list; + + for (auto& lcid : bearers) { + uint16_t dl_sn = 0, ul_sn = 0, tmp = 0; + pdcp.get_bearer_status(lcid.rb_id, &dl_sn, &tmp, &ul_sn, &tmp); + + if (lcid.dl_value_valid) { + // make sure the current DL SN value match + if (lcid.dl_value == dl_sn) { + log.info("Setting AS security for LCID=%d in DL direction\n", lcid.rb_id); + pdcp.config_security( + lcid.rb_id, k_rrc_enc.data(), k_rrc_int.data(), k_up_enc.data(), cipher_algo, integ_algo); + pdcp.enable_integrity(lcid.rb_id, DIRECTION_TX); + pdcp.enable_encryption(lcid.rb_id, DIRECTION_TX); + lcid.dl_value_valid = false; + } else { + log.info("Delaying AS security configuration of lcid=%d. DL: %d != %d\n", lcid.rb_id, lcid.dl_value, dl_sn); + } + } else { + log.debug("Downlink AS Security already applied for lcid=%d\n", lcid.rb_id); + } + + if (lcid.ul_value_valid) { + // Check UL count + if (lcid.ul_value == ul_sn) { + log.info("Setting AS security for LCID=%d in UL direction\n", lcid.rb_id); + pdcp.config_security( + lcid.rb_id, k_rrc_enc.data(), k_rrc_int.data(), k_up_enc.data(), cipher_algo, integ_algo); + pdcp.enable_integrity(lcid.rb_id, DIRECTION_RX); + pdcp.enable_encryption(lcid.rb_id, DIRECTION_RX); + lcid.ul_value_valid = false; + } else { + log.info("Delaying AS security configuration of lcid=%d. UL: %d != %d\n", lcid.rb_id, lcid.ul_value, ul_sn); + } + } else { + log.debug("Uplink AS Security already applied for lcid=%d\n", lcid.rb_id); + } + + // re-consider if at least one direction needs reconfiguration + if (lcid.dl_value_valid || lcid.ul_value_valid) { + log.debug("Adding LCID=%d for later configuration (size=%zd)\n", lcid.rb_id, update_needed_list.size()); + update_needed_list.push_back(lcid); + } } - // store security config for later use (i.e. new bearer added) - as_security_enabled = true; - k_rrc_enc = k_rrc_enc_; - k_rrc_int = k_rrc_int_; - k_up_enc = k_up_enc_; - cipher_algo = cipher_algo_; - integ_algo = integ_algo_; + return update_needed_list; } void release_as_security(const ttcn3_helpers::timing_info_t timing) @@ -1054,7 +1105,7 @@ public: void release_as_security_impl() { log.info("Releasing AS security\n"); - as_security_enabled = false; + pending_bearer_config.clear(); } void select_cell(srslte_cell_t phy_cell) @@ -1080,7 +1131,7 @@ public: pdcp.get_bearer_status(i, &bearer.dl_value, &tmp, &bearer.ul_value, &tmp); bearer.rb_is_srb = i <= 2; bearer.rb_id = i; - log.info("PDCP count lcid=%d, dl=%d, ul=%d\n", bearer.rb_id, bearer.dl_value, bearer.ul_value); + log.debug("PDCP count lcid=%d, dl=%d, ul=%d\n", bearer.rb_id, bearer.dl_value, bearer.ul_value); bearers.push_back(bearer); } } @@ -1175,7 +1226,7 @@ private: std::map bearer_follow_on_map; ///< Indicates if for a given LCID the follow_on_flag is set or not // security config - bool as_security_enabled = false; + ttcn3_helpers::pdcp_count_map_t pending_bearer_config; ///< List of bearers with pending security configuration std::array k_rrc_enc; std::array k_rrc_int; std::array k_up_enc;