Added some functions to save and restore AS keys for the case of failed handover in the USIM

master
Pedro Alvarez 4 years ago
parent 81ab4c1a65
commit 86f4d469c6

@ -78,6 +78,8 @@ class usim_interface_rrc
public: public:
virtual void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg) = 0; virtual void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg) = 0;
virtual void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg) = 0; virtual void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg) = 0;
virtual void store_keys_before_ho(const srslte::as_security_config_t& as_cfg) = 0;
virtual void restore_keys_from_failed_ho(srslte::as_security_config_t* as_cfg) = 0;
}; };
// GW interface for NAS // GW interface for NAS

@ -84,14 +84,16 @@ public:
// RRC interface // RRC interface
void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg); void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg);
void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg); void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg);
void store_keys_before_ho(const srslte::as_security_config_t& as_ctx);
void restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx);
private: private:
srslte::log* log = nullptr; srslte::log* log = nullptr;
// User data // User data
// 3GPP 33.102 v10.0.0 Annex H // 3GPP 33.102 v10.0.0 Annex H
uint64_t imsi = 0; uint64_t imsi = 0;
uint64_t imei = 0; uint64_t imei = 0;
std::string imsi_str; std::string imsi_str;
std::string imei_str; std::string imei_str;
@ -108,6 +110,11 @@ private:
uint8_t k_enb_star[KEY_LEN] = {}; uint8_t k_enb_star[KEY_LEN] = {};
uint8_t auts[AKA_AUTS_LEN] = {}; uint8_t auts[AKA_AUTS_LEN] = {};
// Helpers to restore security context if HO fails
uint8_t old_k_enb[32] = {};
uint8_t old_ncc = {};
srslte::as_security_config_t old_as_ctx = {};
uint32_t current_ncc = 0; uint32_t current_ncc = 0;
bool initiated = false; bool initiated = false;

@ -63,6 +63,8 @@ public:
// RRC interface // RRC interface
void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg); void generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg);
void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg); void generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg);
void store_keys_before_ho(const srslte::as_security_config_t& as_ctx);
void restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx);
private: private:
auth_result_t gen_auth_res_milenage(uint8_t* rand, auth_result_t gen_auth_res_milenage(uint8_t* rand,
@ -107,6 +109,11 @@ private:
uint8_t k_enb[32] = {}; uint8_t k_enb[32] = {};
uint8_t k_enb_star[32] = {}; uint8_t k_enb_star[32] = {};
// Helpers to restore security context if HO fails
uint8_t old_k_enb[32] = {};
uint8_t old_ncc = {};
srslte::as_security_config_t old_as_ctx = {};
uint32_t current_ncc = 0; uint32_t current_ncc = 0;
bool is_first_ncc = false; bool is_first_ncc = false;

@ -367,8 +367,7 @@ proc_outcome_t rrc::si_acquire_proc::react(si_acq_timer_expired ev)
*************************************/ *************************************/
rrc::serving_cell_config_proc::serving_cell_config_proc(rrc* parent_) : rrc::serving_cell_config_proc::serving_cell_config_proc(rrc* parent_) :
rrc_ptr(parent_), rrc_ptr(parent_), log_h(srslte::logmap::get("RRC"))
log_h(srslte::logmap::get("RRC"))
{} {}
/* /*
@ -762,8 +761,7 @@ void rrc::plmn_search_proc::then(const srslte::proc_state_t& result) const
*************************************/ *************************************/
rrc::connection_request_proc::connection_request_proc(rrc* parent_) : rrc::connection_request_proc::connection_request_proc(rrc* parent_) :
rrc_ptr(parent_), rrc_ptr(parent_), log_h(srslte::logmap::get("RRC"))
log_h(srslte::logmap::get("RRC"))
{} {}
proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t cause_, proc_outcome_t rrc::connection_request_proc::init(srslte::establishment_cause_t cause_,
@ -1195,7 +1193,6 @@ proc_outcome_t rrc::connection_reest_proc::init(asn1::rrc::reest_cause_e cause)
// configure lower layers to consider the SCell(s), if configured, to be in deactivated state; // configure lower layers to consider the SCell(s), if configured, to be in deactivated state;
rrc_ptr->phy->set_activation_deactivation_scell(0); rrc_ptr->phy->set_activation_deactivation_scell(0);
// 1> apply the default physical channel configuration as specified in 9.2.4; // 1> apply the default physical channel configuration as specified in 9.2.4;
// Note: this is done by the MAC Reset procedure // Note: this is done by the MAC Reset procedure
@ -1241,7 +1238,7 @@ srslte::proc_outcome_t rrc::connection_reest_proc::cell_criteria()
// Upon selecting a suitable E-UTRA cell, the UE shall: // Upon selecting a suitable E-UTRA cell, the UE shall:
Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n", Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
rrc_ptr->t311.time_elapsed()); rrc_ptr->t311.time_elapsed());
// Note: Not explicitly defined in the specs, but UE should apply SIB1 and SIB2 configuration in order to attempt // Note: Not explicitly defined in the specs, but UE should apply SIB1 and SIB2 configuration in order to attempt
// a PRACH to a different cell // a PRACH to a different cell
Info("Applying SIB2 configuration\n"); Info("Applying SIB2 configuration\n");
@ -1503,6 +1500,7 @@ srslte::proc_outcome_t rrc::ho_proc::init(const asn1::rrc::rrc_conn_recfg_s& rrc
rrc_ptr->apply_rr_config_dedicated(&recfg_r8.rr_cfg_ded, true); rrc_ptr->apply_rr_config_dedicated(&recfg_r8.rr_cfg_ded, true);
} }
rrc_ptr->usim->store_keys_before_ho(rrc_ptr->sec_cfg);
// Security procedure // Security procedure
int ncc = -1; int ncc = -1;
if (recfg_r8.security_cfg_ho_present) { if (recfg_r8.security_cfg_ho_present) {
@ -1582,7 +1580,7 @@ srslte::proc_outcome_t rrc::ho_proc::react(t304_expiry ev)
Info("HO preparation timed out. Reverting RRC security config from source cell.\n"); Info("HO preparation timed out. Reverting RRC security config from source cell.\n");
// revert security settings from source cell for reestablishment according to Sec 5.3.7.4 // revert security settings from source cell for reestablishment according to Sec 5.3.7.4
rrc_ptr->generate_as_keys(); rrc_ptr->usim->restore_keys_from_failed_ho(&rrc_ptr->sec_cfg);
rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg); rrc_ptr->pdcp->config_security_all(rrc_ptr->sec_cfg);

@ -263,9 +263,7 @@ void pcsc_usim::generate_nas_keys(uint8_t* k_asme,
RRC interface RRC interface
*******************************************************************************/ *******************************************************************************/
void pcsc_usim::generate_as_keys(uint8_t* k_asme, void pcsc_usim::generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg)
uint32_t count_ul,
srslte::as_security_config_t* sec_cfg)
{ {
if (!initiated) { if (!initiated) {
ERROR("USIM not initiated!\n"); ERROR("USIM not initiated!\n");
@ -334,6 +332,24 @@ void pcsc_usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srsl
k_enb, sec_cfg->cipher_algo, sec_cfg->integ_algo, sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data()); k_enb, sec_cfg->cipher_algo, sec_cfg->integ_algo, sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data());
} }
void pcsc_usim::store_keys_before_ho(const srslte::as_security_config_t& as_ctx)
{
INFO("Storing AS Keys pre-handover. NCC=%d\n", current_ncc);
old_as_ctx = as_ctx;
old_ncc = current_ncc;
memcpy(old_k_enb, k_enb, 32);
return;
}
void pcsc_usim::restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx)
{
INFO("Restoring Keys from failed handover. NCC=%d\n", old_ncc);
*as_ctx = old_as_ctx;
current_ncc = old_ncc;
memcpy(k_enb, old_k_enb, 32);
return;
}
/******************************************************************************* /*******************************************************************************
Helpers Helpers
*******************************************************************************/ *******************************************************************************/

@ -284,6 +284,24 @@ void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::a
usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RRC_int"); usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RRC_int");
} }
void usim::store_keys_before_ho(const srslte::as_security_config_t& as_ctx)
{
usim_log->info("Storing AS Keys pre-handover. NCC=%d\n", current_ncc);
old_as_ctx = as_ctx;
old_ncc = current_ncc;
memcpy(old_k_enb, k_enb, 32);
return;
}
void usim::restore_keys_from_failed_ho(srslte::as_security_config_t* as_ctx)
{
usim_log->info("Restoring Keys from failed handover. NCC=%d\n", old_ncc);
*as_ctx = old_as_ctx;
current_ncc = old_ncc;
memcpy(k_enb, old_k_enb, 32);
return;
}
/******************************************************************************* /*******************************************************************************
Helpers Helpers
*******************************************************************************/ *******************************************************************************/

Loading…
Cancel
Save