Fix issue recovering key state, when the first HO fails (specifically, is_first_ncc was not recovered). Minor improvements in key logging.

This commit is contained in:
Pedro Alvarez 2020-10-01 12:26:21 +01:00
parent 137e554eb3
commit 2f0125ef4e
4 changed files with 27 additions and 14 deletions

View File

@ -80,6 +80,7 @@ void pdcp_entity_base::integrity_generate(uint8_t* msg, uint32_t msg_len, uint32
count,
cfg.bearer_id,
(cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink"));
log->debug_hex(k_int, 32, "Integrity gen key:");
log->debug_hex(msg, msg_len, "Integrity gen input msg:");
log->debug_hex(mac, 4, "MAC (generated)");
}
@ -117,6 +118,7 @@ bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t
count,
cfg.bearer_id,
cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink");
log->debug_hex(k_int, 32, "Integrity check key:");
log->debug_hex(msg, msg_len, "Integrity check input msg:");
if (sec_cfg.integ_algo != INTEGRITY_ALGORITHM_ID_EIA0) {
@ -152,6 +154,7 @@ void pdcp_entity_base::cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t c
count,
cfg.bearer_id,
cfg.tx_direction == SECURITY_DIRECTION_DOWNLINK ? "Downlink" : "Uplink");
log->debug_hex(k_enc, 32, "Cipher encrypt key:");
log->debug_hex(msg, msg_len, "Cipher encrypt input msg");
switch (sec_cfg.cipher_algo) {
@ -191,6 +194,7 @@ void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t cou
count,
cfg.bearer_id,
(cfg.rx_direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink");
log->debug_hex(k_enc, 32, "Cipher decrypt key:");
log->debug_hex(ct, ct_len, "Cipher decrypt input msg");
switch (sec_cfg.cipher_algo) {

View File

@ -185,6 +185,7 @@ void security_cfg_handler::generate_as_keys()
security_generate_k_up(
k_enb, sec_cfg.cipher_algo, sec_cfg.integ_algo, sec_cfg.k_up_enc.data(), sec_cfg.k_up_int.data());
log_h->info_hex(k_enb, 32, "K_eNB (k_enb)");
log_h->info_hex(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)");
log_h->info_hex(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)");
log_h->info_hex(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)");
@ -192,6 +193,8 @@ void security_cfg_handler::generate_as_keys()
void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t new_dl_earfcn)
{
log_h->info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d\n", new_pci, new_dl_earfcn);
log_h->info_hex(k_enb, 32, "Old K_eNB (k_enb)");
// Generate K_enb*
uint8_t k_enb_star[32];
srslte::security_generate_k_enb_star(k_enb, new_pci, new_dl_earfcn, k_enb_star);
@ -200,11 +203,6 @@ void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t n
memcpy(k_enb, k_enb_star, 32);
generate_as_keys();
log_h->info("Regenerating KeNB with PCI=0x%02x, DL-EARFCN=%d\n", new_pci, new_dl_earfcn);
log_h->info_hex(sec_cfg.k_rrc_enc.data(), 32, "RRC Encryption Key (k_rrc_enc)");
log_h->info_hex(sec_cfg.k_rrc_int.data(), 32, "RRC Integrity Key (k_rrc_int)");
log_h->info_hex(sec_cfg.k_up_enc.data(), 32, "UP Encryption Key (k_up_enc)");
}
/*****************************

View File

@ -110,9 +110,10 @@ private:
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 = {};
bool old_is_first_ncc = {};
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

@ -239,8 +239,8 @@ void usim::generate_as_keys(uint8_t* k_asme_, uint32_t count_ul, srslte::as_secu
void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::as_security_config_t* sec_cfg)
{
usim_log->info("Generating AS Keys HO. PCI 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, ncc);
usim_log->info_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "Original HO K_RRC_enc");
usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "Original HO K_RRC_int");
usim_log->info_hex(k_enb, 32, "Old K_eNB");
uint8_t* enb_star_key = k_enb;
if (ncc < 0) {
@ -251,9 +251,11 @@ void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::a
while (current_ncc != (uint32_t)ncc) {
uint8_t* sync = NULL;
if (is_first_ncc) {
usim_log->debug("Using K_enb_initial for sync. 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, current_ncc);
sync = k_enb_initial;
is_first_ncc = false;
} else {
usim_log->debug("Using NH for sync. 0x%02x, DL-EARFCN %d, NCC %d\n", pci, earfcn, current_ncc);
sync = nh;
}
// Generate NH
@ -280,6 +282,7 @@ void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::a
security_generate_k_up(
k_enb, sec_cfg->cipher_algo, sec_cfg->integ_algo, sec_cfg->k_up_enc.data(), sec_cfg->k_up_int.data());
usim_log->info_hex(k_enb, 32, "HO K_eNB");
usim_log->info_hex(sec_cfg->k_rrc_enc.data(), sec_cfg->k_rrc_enc.size(), "HO K_RRC_enc");
usim_log->info_hex(sec_cfg->k_rrc_int.data(), sec_cfg->k_rrc_int.size(), "HO K_RRC_int");
}
@ -287,8 +290,14 @@ void usim::generate_as_keys_ho(uint32_t pci, uint32_t earfcn, int ncc, srslte::a
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;
usim_log->info_hex(k_enb, 32, "Old K_eNB");
usim_log->info_hex(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc");
usim_log->info_hex(as_ctx.k_rrc_enc.data(), as_ctx.k_rrc_enc.size(), "Old K_RRC_enc");
usim_log->info_hex(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int");
usim_log->info_hex(as_ctx.k_rrc_int.data(), as_ctx.k_rrc_int.size(), "Old K_RRC_int");
old_is_first_ncc = is_first_ncc;
old_as_ctx = as_ctx;
old_ncc = current_ncc;
memcpy(old_k_enb, k_enb, 32);
return;
}
@ -296,8 +305,9 @@ void usim::store_keys_before_ho(const srslte::as_security_config_t& as_ctx)
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;
is_first_ncc = old_is_first_ncc;
*as_ctx = old_as_ctx;
current_ncc = old_ncc;
memcpy(k_enb, old_k_enb, 32);
return;
}