diff --git a/lib/include/srsran/common/security.h b/lib/include/srsran/common/security.h index fa1bd52b6..cb4e246f5 100644 --- a/lib/include/srsran/common/security.h +++ b/lib/include/srsran/common/security.h @@ -59,6 +59,28 @@ static const char integrity_algorithm_id_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20 "128-EIA2", "128-EIA3"}; +typedef enum { + CIPHERING_ALGORITHM_ID_NR_NEA0 = 0, + CIPHERING_ALGORITHM_ID_NR_128_NEA1, + CIPHERING_ALGORITHM_ID_NR_128_NEA2, + CIPHERING_ALGORITHM_ID_NR_128_NEA3, + CIPHERING_ALGORITHM_ID_NR_N_ITEMS, +} CIPHERING_ALGORITHM_ID_NR_ENUM; +static const char ciphering_algorithm_id_nr_text[CIPHERING_ALGORITHM_ID_N_ITEMS][20] = {"NEA0", + "128-NEA1", + "128-NEA2", + "128-NEA3"}; +typedef enum { + INTEGRITY_ALGORITHM_ID_NR_NIA0 = 0, + INTEGRITY_ALGORITHM_ID_NR_128_NIA1, + INTEGRITY_ALGORITHM_ID_NR_128_NIA2, + INTEGRITY_ALGORITHM_ID_NR_128_NIA3, + INTEGRITY_ALGORITHM_ID_NR_N_ITEMS, +} INTEGRITY_ALGORITHM_ID_NR_ENUM; +static const char integrity_algorithm_id_nr_text[INTEGRITY_ALGORITHM_ID_N_ITEMS][20] = {"NIA0", + "128-NIA1", + "128-NIA2", + "128-NIA3"}; typedef enum { SECURITY_DIRECTION_UPLINK = 0, SECURITY_DIRECTION_DOWNLINK = 1, @@ -87,6 +109,15 @@ struct as_security_config_t { CIPHERING_ALGORITHM_ID_ENUM cipher_algo; }; +struct nr_as_security_config_t { + as_key_t k_nr_rrc_int; + as_key_t k_nr_rrc_enc; + as_key_t k_nr_up_int; + as_key_t k_nr_up_enc; + INTEGRITY_ALGORITHM_ID_NR_ENUM integ_algo; + CIPHERING_ALGORITHM_ID_NR_ENUM cipher_algo; +}; + template void log_error(const char* format, Args&&... args) { diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_config.h b/srsgnb/hdr/stack/rrc/rrc_nr_config.h index 4167a22a5..ed65ef653 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_config.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_config.h @@ -53,8 +53,8 @@ struct rrc_nr_cfg_t { rrc_cell_list_nr_t cell_list; bool is_standalone; - std::array eea_preference_list; - std::array eia_preference_list; + std::array nea_preference_list; + std::array nia_preference_list; std::string log_name = "RRC-NR"; std::string log_level; diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h b/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h index aa7009d82..e8bb1d379 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_security_context.h @@ -24,12 +24,11 @@ class nr_security_context { public: explicit nr_security_context(const srsenb::rrc_nr_cfg_t& cfg_) : - cfg(&cfg_), logger(srslog::fetch_basic_logger("RRC_NR")) + cfg(cfg_), logger(srslog::fetch_basic_logger("RRC_NR")) {} - explicit nr_security_context(const nr_security_context& other) : logger(srslog::fetch_basic_logger("RRC_NR")) + nr_security_context(const nr_security_context& other) : cfg(other.cfg), logger(srslog::fetch_basic_logger("RRC_NR")) { - cfg = other.cfg; k_gnb_present = other.k_gnb_present; security_capabilities = other.security_capabilities; std::copy(other.k_gnb, other.k_gnb + 32, k_gnb); @@ -39,7 +38,6 @@ public: nr_security_context& operator=(const nr_security_context& other) { - cfg = other.cfg; k_gnb_present = other.k_gnb_present; security_capabilities = other.security_capabilities; std::copy(other.k_gnb, other.k_gnb + 32, k_gnb); @@ -53,7 +51,7 @@ public: void set_ncc(uint8_t ncc_) { ncc = ncc_; } asn1::rrc_nr::security_algorithm_cfg_s get_security_algorithm_cfg() const; - const srsran::as_security_config_t& get_as_sec_cfg() const { return sec_cfg; } + const srsran::nr_as_security_config_t& get_as_sec_cfg() const { return sec_cfg; } uint8_t get_ncc() const { return ncc; } bool is_as_sec_cfg_valid() const { return k_gnb_present; } @@ -63,11 +61,11 @@ private: void generate_as_keys(); srslog::basic_logger& logger; - const srsenb::rrc_nr_cfg_t* cfg = nullptr; + const srsenb::rrc_nr_cfg_t& cfg; bool k_gnb_present = false; asn1::ngap_nr::ue_security_cap_s security_capabilities = {}; uint8_t k_gnb[32] = {}; // Provided by MME - srsran::as_security_config_t sec_cfg = {}; + srsran::nr_as_security_config_t sec_cfg = {}; uint8_t ncc = 0; }; } // namespace srsgnb diff --git a/srsgnb/src/stack/rrc/rrc_nr_security_context.cc b/srsgnb/src/stack/rrc/rrc_nr_security_context.cc index d56f4384f..cf686f949 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_security_context.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_security_context.cc @@ -31,10 +31,10 @@ bool nr_security_context::set_security_capabilities(const asn1::ngap_nr::ue_secu // Selects security algorithms (cipher_algo and integ_algo) based on capabilities and config preferences // Each position in the bitmap represents an encryption algorithm: - // “all bits equal to 0” – UE supports no other algorithm than EEA0, - // “first bit” – 128-EEA1, - // “second bit” – 128-EEA2, - // “third bit” – 128-EEA3, + // “all bits equal to 0” – UE supports no other algorithm than NEA0, + // “first bit” – 128-NEA1, + // “second bit” – 128-NEA2, + // “third bit” – 128-NEA3, // other bits reserved for future use. Value ‘1’ indicates support and value // ‘0’ indicates no support of the algorithm. // Algorithms are defined in TS 33.401 [15]. @@ -43,48 +43,48 @@ bool nr_security_context::set_security_capabilities(const asn1::ngap_nr::ue_secu bool enc_algo_found = false; bool integ_algo_found = false; - for (auto& cipher_item : cfg->eea_preference_list) { + for (const auto& cipher_item : cfg.nea_preference_list) { auto& v = security_capabilities.nrencryption_algorithms; switch (cipher_item) { - case srsran::CIPHERING_ALGORITHM_ID_EEA0: + case srsran::CIPHERING_ALGORITHM_ID_NR_NEA0: // “all bits equal to 0” – UE supports no other algorithm than EEA0, // specification does not cover the case in which EEA0 is supported with other algorithms // just assume that EEA0 is always supported even this can not be explicity signaled by S1AP - sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_EEA0; + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_NEA0; enc_algo_found = true; - logger.info("Selected EEA0 as RRC encryption algorithm"); + logger.info("Selected NEA0 as RRC encryption algorithm"); break; - case srsran::CIPHERING_ALGORITHM_ID_128_EEA1: + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1: // “first bit” – 128-EEA1, - if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_128_EEA1)) { - sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_128_EEA1; + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA1; enc_algo_found = true; - logger.info("Selected EEA1 as RRC encryption algorithm"); + logger.info("Selected NEA1 as RRC encryption algorithm"); break; } else { - logger.info("Failed to selected EEA1 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NEA1 as RRC encryption algorithm, due to unsupported algorithm"); } break; - case srsran::CIPHERING_ALGORITHM_ID_128_EEA2: + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2: // “second bit” – 128-EEA2, - if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_128_EEA2)) { - sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_128_EEA2; + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA2; enc_algo_found = true; - logger.info("Selected EEA2 as RRC encryption algorithm"); + logger.info("Selected NEA2 as RRC encryption algorithm"); break; } else { - logger.info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NEA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; - case srsran::CIPHERING_ALGORITHM_ID_128_EEA3: + case srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3: // “third bit” – 128-EEA3, - if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_128_EEA3)) { - sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_128_EEA3; + if (v.get(v.length() - srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3)) { + sec_cfg.cipher_algo = srsran::CIPHERING_ALGORITHM_ID_NR_128_NEA3; enc_algo_found = true; - logger.info("Selected EEA3 as RRC encryption algorithm"); + logger.info("Selected NEA3 as RRC encryption algorithm"); break; } else { - logger.info("Failed to selected EEA2 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NEA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; default: @@ -96,43 +96,43 @@ bool nr_security_context::set_security_capabilities(const asn1::ngap_nr::ue_secu } } - for (auto& eia_enum : cfg->eia_preference_list) { + for (const auto& eia_enum : cfg.nia_preference_list) { auto& v = security_capabilities.nrintegrity_protection_algorithms; switch (eia_enum) { - case srsran::INTEGRITY_ALGORITHM_ID_EIA0: + case srsran::INTEGRITY_ALGORITHM_ID_NR_NIA0: // Null integrity is not supported - logger.info("Skipping EIA0 as RRC integrity algorithm. Null integrity is not supported."); - sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_EIA0; + logger.info("Skipping NIA0 as RRC integrity algorithm. Null integrity is not supported."); + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_NIA0; integ_algo_found = true; break; - case srsran::INTEGRITY_ALGORITHM_ID_128_EIA1: + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1: // “first bit” – 128-EIA1, - if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_128_EIA1)) { - sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_128_EIA1; + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA1; integ_algo_found = true; - logger.info("Selected EIA1 as RRC integrity algorithm."); + logger.info("Selected NIA1 as RRC integrity algorithm."); } else { - logger.info("Failed to selected EIA1 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NIA1 as RRC encryption algorithm, due to unsupported algorithm"); } break; - case srsran::INTEGRITY_ALGORITHM_ID_128_EIA2: + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2: // “second bit” – 128-EIA2, - if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_128_EIA2)) { - sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_128_EIA2; + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA2; integ_algo_found = true; - logger.info("Selected EIA2 as RRC integrity algorithm."); + logger.info("Selected NIA2 as RRC integrity algorithm."); } else { - logger.info("Failed to selected EIA2 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NIA2 as RRC encryption algorithm, due to unsupported algorithm"); } break; - case srsran::INTEGRITY_ALGORITHM_ID_128_EIA3: + case srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3: // “third bit” – 128-EIA3, - if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_128_EIA3)) { - sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_128_EIA3; + if (v.get(v.length() - srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3)) { + sec_cfg.integ_algo = srsran::INTEGRITY_ALGORITHM_ID_NR_128_NIA3; integ_algo_found = true; - logger.info("Selected EIA3 as RRC integrity algorithm."); + logger.info("Selected NIA3 as RRC integrity algorithm."); } else { - logger.info("Failed to selected EIA3 as RRC encryption algorithm, due to unsupported algorithm"); + logger.info("Failed to selected NIA3 as RRC encryption algorithm, due to unsupported algorithm"); } break; default: @@ -166,24 +166,30 @@ void nr_security_context::set_security_key(const asn1::fixed_bitstring<256, fals void nr_security_context::generate_as_keys() { // Generate K_rrc_enc and K_rrc_int - srsran::security_generate_k_nr_rrc( - k_gnb, sec_cfg.cipher_algo, sec_cfg.integ_algo, sec_cfg.k_rrc_enc.data(), sec_cfg.k_rrc_int.data()); + srsran::security_generate_k_nr_rrc(k_gnb, + (srsran::CIPHERING_ALGORITHM_ID_ENUM)sec_cfg.cipher_algo, + (srsran::INTEGRITY_ALGORITHM_ID_ENUM)sec_cfg.integ_algo, + sec_cfg.k_nr_rrc_enc.data(), + sec_cfg.k_nr_rrc_int.data()); // Generate K_up_enc and K_up_int - security_generate_k_nr_up( - k_gnb, sec_cfg.cipher_algo, sec_cfg.integ_algo, sec_cfg.k_up_enc.data(), sec_cfg.k_up_int.data()); + security_generate_k_nr_up(k_gnb, + (srsran::CIPHERING_ALGORITHM_ID_ENUM)sec_cfg.cipher_algo, + (srsran::INTEGRITY_ALGORITHM_ID_ENUM)sec_cfg.integ_algo, + sec_cfg.k_nr_up_enc.data(), + sec_cfg.k_nr_up_int.data()); logger.info(k_gnb, 32, "K_gNB (k_gnb)"); - logger.info(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)"); - logger.info(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)"); - logger.info(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)"); - logger.info(sec_cfg.k_up_int.data(), 32, "UP Encryption Key (k_up_enc)"); + logger.info(sec_cfg.k_nr_rrc_enc.data(), 32, "NR RRC Encryption Key (k_nr_rrc_enc)"); + logger.info(sec_cfg.k_nr_rrc_int.data(), 32, "NR RRC Integrity Key (k_nr_rrc_int)"); + logger.info(sec_cfg.k_nr_up_enc.data(), 32, "NR UP Encryption Key (k_nr_up_enc)"); + logger.info(sec_cfg.k_nr_up_int.data(), 32, "NR UP Encryption Key (k_nr_up_enc)"); } void nr_security_context::regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn) { - logger.info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d", new_pci, new_dl_earfcn); - logger.info(k_gnb, 32, "Old K_eNB (k_enb)"); + logger.info("Regenerating KgNB with PCI=0x%02x, DL-EARFCN=%d", new_pci, new_dl_earfcn); + logger.info(k_gnb, 32, "Old K_gNB (k_enb)"); // Generate K_enb* uint8_t k_gnb_star[32]; srsran::security_generate_k_enb_star(k_gnb, new_pci, new_dl_earfcn, k_gnb_star);