From 2f0125ef4ef3200fe9128dfa4d88200af81804ba Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 1 Oct 2020 12:26:21 +0100 Subject: [PATCH] Fix issue recovering key state, when the first HO fails (specifically, is_first_ncc was not recovered). Minor improvements in key logging. --- lib/src/upper/pdcp_entity_base.cc | 4 ++++ srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 8 +++----- srsue/hdr/stack/upper/usim.h | 7 ++++--- srsue/src/stack/upper/usim.cc | 22 ++++++++++++++++------ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/src/upper/pdcp_entity_base.cc b/lib/src/upper/pdcp_entity_base.cc index ddfa8a9a2..9019876ab 100644 --- a/lib/src/upper/pdcp_entity_base.cc +++ b/lib/src/upper/pdcp_entity_base.cc @@ -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) { diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 3cc4f166c..4f0475d3d 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -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)"); } /***************************** diff --git a/srsue/hdr/stack/upper/usim.h b/srsue/hdr/stack/upper/usim.h index 2f8980e48..f8a4b9442 100644 --- a/srsue/hdr/stack/upper/usim.h +++ b/srsue/hdr/stack/upper/usim.h @@ -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; diff --git a/srsue/src/stack/upper/usim.cc b/srsue/src/stack/upper/usim.cc index b2d4950ee..e0a463bf5 100644 --- a/srsue/src/stack/upper/usim.cc +++ b/srsue/src/stack/upper/usim.cc @@ -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; }