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

This commit is contained in:
Pedro Alvarez 2020-09-22 19:31:48 +01:00
parent 81ab4c1a65
commit 86f4d469c6
6 changed files with 60 additions and 12 deletions

View File

@ -78,6 +78,8 @@ class usim_interface_rrc
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_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

View File

@ -84,14 +84,16 @@ public:
// 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_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:
srslte::log* log = nullptr;
// User data
// 3GPP 33.102 v10.0.0 Annex H
uint64_t imsi = 0;
uint64_t imei = 0;
uint64_t imsi = 0;
uint64_t imei = 0;
std::string imsi_str;
std::string imei_str;
@ -108,6 +110,11 @@ private:
uint8_t k_enb_star[KEY_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;
bool initiated = false;

View File

@ -63,6 +63,8 @@ public:
// 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_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:
auth_result_t gen_auth_res_milenage(uint8_t* rand,
@ -107,6 +109,11 @@ private:
uint8_t k_enb[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;
bool is_first_ncc = false;

View File

@ -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_ptr(parent_),
log_h(srslte::logmap::get("RRC"))
rrc_ptr(parent_), 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_ptr(parent_),
log_h(srslte::logmap::get("RRC"))
rrc_ptr(parent_), log_h(srslte::logmap::get("RRC"))
{}
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;
rrc_ptr->phy->set_activation_deactivation_scell(0);
// 1> apply the default physical channel configuration as specified in 9.2.4;
// 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:
Info("Cell Selection criteria passed after %dms. Sending RRC Connection Reestablishment Request\n",
rrc_ptr->t311.time_elapsed());
// 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
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->usim->store_keys_before_ho(rrc_ptr->sec_cfg);
// Security procedure
int ncc = -1;
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");
// 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);

View File

@ -263,9 +263,7 @@ void pcsc_usim::generate_nas_keys(uint8_t* k_asme,
RRC interface
*******************************************************************************/
void pcsc_usim::generate_as_keys(uint8_t* k_asme,
uint32_t count_ul,
srslte::as_security_config_t* sec_cfg)
void pcsc_usim::generate_as_keys(uint8_t* k_asme, uint32_t count_ul, srslte::as_security_config_t* sec_cfg)
{
if (!initiated) {
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());
}
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
*******************************************************************************/

View File

@ -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");
}
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
*******************************************************************************/