Added usim features for key derivation

master
David Rupprecht 4 years ago committed by David Rupprecht
parent 306bb6b38b
commit 1b19ee40e7

@ -60,6 +60,10 @@ struct k_enb_context_t {
uint32_t ncc; uint32_t ncc;
}; };
struct k_gnb_context_t {
as_key_t sk_gnb;
};
struct as_security_config_t { struct as_security_config_t {
as_key_t k_rrc_int; as_key_t k_rrc_int;
as_key_t k_rrc_enc; as_key_t k_rrc_enc;

@ -280,6 +280,13 @@ public:
virtual bool is_config_pending() = 0; virtual bool is_config_pending() = 0;
}; };
class usim_interface_rrc_nr
{
public:
virtual void generate_nr_context(uint16_t sk_counter, srslte::as_security_config_t* sec_cfg) = 0;
virtual void update_nr_context(srslte::as_security_config_t* sec_cfg) = 0;
};
// PDCP interface for RLC // PDCP interface for RLC
class pdcp_interface_rlc class pdcp_interface_rlc
{ {

@ -55,6 +55,7 @@ public:
pdcp_interface_rrc* pdcp_, pdcp_interface_rrc* pdcp_,
gw_interface_rrc* gw_, gw_interface_rrc* gw_,
rrc_eutra_interface_rrc_nr* rrc_eutra_, rrc_eutra_interface_rrc_nr* rrc_eutra_,
usim_interface_rrc_nr* usim_,
srslte::timer_handler* timers_, srslte::timer_handler* timers_,
stack_interface_rrc* stack_, stack_interface_rrc* stack_,
const rrc_nr_args_t& args_); const rrc_nr_args_t& args_);
@ -110,6 +111,7 @@ public:
uint32_t sk_counter_r15, uint32_t sk_counter_r15,
bool nr_radio_bearer_cfg1_r15_present, bool nr_radio_bearer_cfg1_r15_present,
asn1::dyn_octstring nr_radio_bearer_cfg1_r15); asn1::dyn_octstring nr_radio_bearer_cfg1_r15);
void configure_sk_counter(uint16_t sk_counter);
bool is_config_pending(); bool is_config_pending();
// STACK interface // STACK interface
void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell); void cell_search_completed(const rrc_interface_phy_lte::cell_search_ret_t& cs_ret, const phy_cell_t& found_cell);
@ -131,6 +133,7 @@ private:
pdcp_interface_rrc* pdcp = nullptr; pdcp_interface_rrc* pdcp = nullptr;
gw_interface_rrc* gw = nullptr; gw_interface_rrc* gw = nullptr;
rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr; rrc_eutra_interface_rrc_nr* rrc_eutra = nullptr;
usim_interface_rrc_nr* usim = nullptr;
stack_interface_rrc* stack = nullptr; stack_interface_rrc* stack = nullptr;
srslte::log_ref log_h; srslte::log_ref log_h;
@ -185,6 +188,7 @@ private:
srslte::proc_outcome_t init(const bool endc_release_and_add_r15, srslte::proc_outcome_t init(const bool endc_release_and_add_r15,
const asn1::rrc_nr::rrc_recfg_s& rrc_recfg, const asn1::rrc_nr::rrc_recfg_s& rrc_recfg,
const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg, const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg,
bool sk_counter_r15_present,
const uint32_t sk_counter_r15, const uint32_t sk_counter_r15,
const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg); const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg);
srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; } srslte::proc_outcome_t step() { return srslte::proc_outcome_t::yield; }

@ -54,7 +54,7 @@ public:
std::string reader; std::string reader;
}; };
class usim_base : public usim_interface_nas, public usim_interface_rrc class usim_base : public usim_interface_nas, public usim_interface_rrc, public usim_interface_rrc_nr
{ {
public: public:
usim_base(srslte::log* log_); usim_base(srslte::log* log_);
@ -92,6 +92,10 @@ public:
void store_keys_before_ho(const srslte::as_security_config_t& as_ctx) final; void store_keys_before_ho(const srslte::as_security_config_t& as_ctx) final;
void restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx) final; void restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx) final;
// NR RRC interface
void generate_nr_context(uint16_t sk_counter, srslte::as_security_config_t* sec_cfg) final;
void update_nr_context(srslte::as_security_config_t* sec_cfg) final;
// Helpers // Helpers
std::string get_mcc_str(const uint8_t* imsi_vec); std::string get_mcc_str(const uint8_t* imsi_vec);
virtual std::string get_mnc_str(const uint8_t* imsi_vec, std::string mcc_str) = 0; virtual std::string get_mnc_str(const uint8_t* imsi_vec, std::string mcc_str) = 0;
@ -120,6 +124,7 @@ protected:
// Current K_eNB context (K_eNB, NH and NCC) // Current K_eNB context (K_eNB, NH and NCC)
srslte::k_enb_context_t k_enb_ctx = {}; srslte::k_enb_context_t k_enb_ctx = {};
srslte::k_gnb_context_t k_gnb_ctx = {};
// Helpers to restore security context if HO fails // Helpers to restore security context if HO fails
srslte::k_enb_context_t old_k_enb_ctx = {}; srslte::k_enb_context_t old_k_enb_ctx = {};

@ -12,6 +12,7 @@
#include "srsue/hdr/stack/rrc/rrc_nr.h" #include "srsue/hdr/stack/rrc/rrc_nr.h"
#include "srslte/common/security.h" #include "srslte/common/security.h"
#include "srsue/hdr/stack/upper/usim.h"
#define Error(fmt, ...) rrc_ptr->log_h->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define Error(fmt, ...) rrc_ptr->log_h->error("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
#define Warning(fmt, ...) rrc_ptr->log_h->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define Warning(fmt, ...) rrc_ptr->log_h->warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__)
@ -35,6 +36,7 @@ void rrc_nr::init(phy_interface_rrc_nr* phy_,
pdcp_interface_rrc* pdcp_, pdcp_interface_rrc* pdcp_,
gw_interface_rrc* gw_, gw_interface_rrc* gw_,
rrc_eutra_interface_rrc_nr* rrc_eutra_, rrc_eutra_interface_rrc_nr* rrc_eutra_,
usim_interface_rrc_nr* usim_,
srslte::timer_handler* timers_, srslte::timer_handler* timers_,
stack_interface_rrc* stack_, stack_interface_rrc* stack_,
const rrc_nr_args_t& args_) const rrc_nr_args_t& args_)
@ -45,6 +47,7 @@ void rrc_nr::init(phy_interface_rrc_nr* phy_,
gw = gw_; gw = gw_;
mac = mac_; mac = mac_;
rrc_eutra = rrc_eutra_; rrc_eutra = rrc_eutra_;
usim = usim_;
timers = timers_; timers = timers_;
stack = stack_; stack = stack_;
args = args_; args = args_;
@ -368,8 +371,12 @@ bool rrc_nr::rrc_reconfiguration(bool endc_release_and_add_r15,
} }
log_rrc_message("RRC NR Reconfiguration", Rx, nr_radio_bearer_cfg1_r15, radio_bearer_cfg, "Radio Bearer Config R15"); log_rrc_message("RRC NR Reconfiguration", Rx, nr_radio_bearer_cfg1_r15, radio_bearer_cfg, "Radio Bearer Config R15");
if (not conn_recfg_proc.launch( if (not conn_recfg_proc.launch(endc_release_and_add_r15,
endc_release_and_add_r15, rrc_recfg, cell_group_cfg, sk_counter_r15, radio_bearer_cfg)) { rrc_recfg,
cell_group_cfg,
sk_counter_r15_present,
sk_counter_r15,
radio_bearer_cfg)) {
log_h->error("Unable to launch NR RRC configuration procedure\n"); log_h->error("Unable to launch NR RRC configuration procedure\n");
return false; return false;
} else { } else {
@ -436,6 +443,11 @@ void rrc_nr::phy_set_cells_to_meas(uint32_t carrier_freq_r15)
fake_measurement_timer.run(); fake_measurement_timer.run();
} }
void rrc_nr::configure_sk_counter(uint16_t sk_counter)
{
log_h->info("[NR] Configure new SK counter %d. Update Key for secondary gnb\n", sk_counter);
usim->generate_nr_context(sk_counter, &sec_cfg);
}
bool rrc_nr::is_config_pending() bool rrc_nr::is_config_pending()
{ {
if (conn_recfg_proc.is_busy()) { if (conn_recfg_proc.is_busy()) {
@ -600,6 +612,14 @@ bool rrc_nr::apply_drb_add_mod(const drb_to_add_mod_s& drb_cfg)
bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg) bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg)
{ {
// TODO derive correct keys
if (security_cfg.key_to_use_present) {
if (security_cfg.key_to_use.value != security_cfg_s::key_to_use_opts::options::secondary) {
log_h->warning("Only secondary key supported yet\n");
}
}
if (security_cfg.security_algorithm_cfg_present) { if (security_cfg.security_algorithm_cfg_present) {
switch (security_cfg.security_algorithm_cfg.ciphering_algorithm) { switch (security_cfg.security_algorithm_cfg.ciphering_algorithm) {
case ciphering_algorithm_e::nea0: case ciphering_algorithm_e::nea0:
@ -638,11 +658,8 @@ bool rrc_nr::apply_security_cfg(const security_cfg_s& security_cfg)
break; break;
} }
} }
usim->update_nr_context(&sec_cfg);
} }
// TODO derive correct keys
if (security_cfg.key_to_use_present) {
}
// TODO derive correct keys
// Apply security config for all known NR lcids // Apply security config for all known NR lcids
for (auto& lcid : lcid_rb) { for (auto& lcid : lcid_rb) {
@ -677,6 +694,7 @@ rrc_nr::connection_reconf_no_ho_proc::connection_reconf_no_ho_proc(rrc_nr* paren
proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool endc_release_and_add_r15, proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool endc_release_and_add_r15,
const asn1::rrc_nr::rrc_recfg_s& rrc_recfg, const asn1::rrc_nr::rrc_recfg_s& rrc_recfg,
const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg, const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg,
bool sk_counter_r15_present,
const uint32_t sk_counter_r15, const uint32_t sk_counter_r15,
const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg) const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg)
{ {
@ -687,6 +705,11 @@ proc_outcome_t rrc_nr::connection_reconf_no_ho_proc::init(const bool
return proc_outcome_t::error; return proc_outcome_t::error;
} }
if (sk_counter_r15_present) {
Info("Applying Cell Group Cfg\n");
rrc_ptr->configure_sk_counter((uint16_t)sk_counter_r15);
}
Info("Applying Radio Bearer Cfg\n"); Info("Applying Radio Bearer Cfg\n");
if (!rrc_ptr->apply_radio_bearer_cfg(radio_bearer_cfg)) { if (!rrc_ptr->apply_radio_bearer_cfg(radio_bearer_cfg)) {
return proc_outcome_t::error; return proc_outcome_t::error;

@ -125,7 +125,8 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_)
#ifdef HAVE_5GNR #ifdef HAVE_5GNR
mac_nr_args_t mac_nr_args; mac_nr_args_t mac_nr_args;
mac_nr.init(mac_nr_args, nullptr, &rlc); mac_nr.init(mac_nr_args, nullptr, &rlc);
rrc_nr.init(nullptr, &mac_nr, &rlc, &pdcp, gw, &rrc, task_sched.get_timer_handler(), nullptr, args.rrc_nr); rrc_nr.init(
nullptr, &mac_nr, &rlc, &pdcp, gw, &rrc, usim.get(), task_sched.get_timer_handler(), nullptr, args.rrc_nr);
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc); rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &rrc_nr, args.rrc);
#else #else
rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, args.rrc); rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, args.rrc);

@ -83,7 +83,8 @@ int ue_stack_nr::init(const stack_args_t& args_)
rrc_args.log_hex_limit = args.log.rrc_hex_limit; rrc_args.log_hex_limit = args.log.rrc_hex_limit;
rrc_args.coreless.drb_lcid = 4; rrc_args.coreless.drb_lcid = 4;
rrc_args.coreless.ip_addr = "192.168.1.3"; rrc_args.coreless.ip_addr = "192.168.1.3";
rrc->init(phy, mac.get(), rlc.get(), pdcp.get(), gw, nullptr, task_sched.get_timer_handler(), this, rrc_args); rrc->init(
phy, mac.get(), rlc.get(), pdcp.get(), gw, nullptr, nullptr, task_sched.get_timer_handler(), this, rrc_args);
rrc->init_core_less(); rrc->init_core_less();
running = true; running = true;
start(STACK_MAIN_THREAD_PRIO); start(STACK_MAIN_THREAD_PRIO);

@ -175,10 +175,10 @@ void usim_base::generate_as_keys(uint8_t* k_asme_, uint32_t count_ul, srslte::as
k_enb_ctx.is_first_ncc = true; k_enb_ctx.is_first_ncc = true;
log->debug_hex(k_enb_ctx.k_enb.data(), 32, "Initial K_eNB"); log->debug_hex(k_enb_ctx.k_enb.data(), 32, "Initial K_eNB");
log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "K_RRC_enc");
log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "K_RRC_enc");
log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "K_RRC_int");
log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "K_RRC_int"); log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "K_RRC_int");
log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "K_RRC_enc");
log->debug_hex(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "K_UP_int");
log->debug_hex(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "K_UP_enc");
} }
void usim_base::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg) void usim_base::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg)
@ -265,4 +265,48 @@ void usim_base::restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx
return; return;
} }
/*
* NR RRC Interface
*/
void usim_base::generate_nr_context(uint16_t sk_counter, srslte::as_security_config_t* sec_cfg)
{
if (!initiated) {
log->error("USIM not initiated!\n");
return;
}
log->info("Generating Keys. SCG Counter %d\n", sk_counter);
srslte::security_generate_sk_gnb(k_enb_ctx.k_enb.data(), k_gnb_ctx.sk_gnb.data(), sk_counter);
log->info_hex(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb");
update_nr_context(sec_cfg);
}
void usim_base::update_nr_context(srslte::as_security_config_t* sec_cfg)
{
if (!initiated) {
log->error("USIM not initiated!\n");
return;
}
log->info_hex(k_gnb_ctx.sk_gnb.data(), 32, "k_sk_gnb");
// Generate K_rrc_enc and K_rrc_int
security_generate_k_nr_rrc(k_gnb_ctx.sk_gnb.data(),
sec_cfg->cipher_algo,
sec_cfg->integ_algo,
sec_cfg->k_rrc_enc.data(),
sec_cfg->k_rrc_int.data());
// Generate K_up_enc and K_up_int
security_generate_k_nr_up(k_gnb_ctx.sk_gnb.data(),
sec_cfg->cipher_algo,
sec_cfg->integ_algo,
sec_cfg->k_up_enc.data(),
sec_cfg->k_up_int.data());
log->debug_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "NR K_RRC_int");
log->debug_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "NR K_RRC_enc");
log->debug_hex(sec_cfg->k_up_int.data(), sec_cfg->k_up_int.size(), "NR K_UP_int");
log->debug_hex(sec_cfg->k_up_enc.data(), sec_cfg->k_up_enc.size(), "NR K_UP_enc");
}
} // namespace srsue } // namespace srsue

Loading…
Cancel
Save