diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 60faea607..3c8cfa886 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -138,7 +138,7 @@ public: virtual void paging(LIBLTE_RRC_S_TMSI_STRUCT *ue_identiy) = 0; virtual bool is_attached() = 0; virtual void write_pdu(uint32_t lcid, srslte::byte_buffer_t *pdu) = 0; - virtual uint32_t get_ul_count() = 0; + virtual uint32_t get_k_enb_count() = 0; virtual bool get_k_asme(uint8_t *k_asme_, uint32_t n) = 0; virtual uint32_t get_ipv4_addr() = 0; virtual bool get_ipv6_addr(uint8_t *ipv6_addr) = 0; diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 2c633ef38..7d8cc8b01 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -85,7 +85,8 @@ public: void paging(LIBLTE_RRC_S_TMSI_STRUCT *ue_identiy); void set_barring(barring_t barring); void write_pdu(uint32_t lcid, byte_buffer_t *pdu); - uint32_t get_ul_count(); + void set_k_enb_count(); + uint32_t get_k_enb_count(); bool is_attached(); bool get_k_asme(uint8_t *k_asme_, uint32_t n); uint32_t get_ipv4_addr(); @@ -125,6 +126,7 @@ private: uint8_t k_asme[32]; uint32_t tx_count; uint32_t rx_count; + uint32_t k_enb_count; srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo; srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo; LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 97643886a..cf2338b3f 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -388,14 +388,17 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { } } -uint32_t nas::get_ul_count() { - // UL count for RRC key derivation depends on ESM information transfer procedure - if (cfg.apn.empty()) { - // No ESM info transfer has been sent - return ctxt.tx_count - 1; - } else { - return ctxt.tx_count - 2; - } +void nas::set_k_enb_count() { + // UL count for RRC key derivation depends on UL count of the Authentication Request or Service Request. + // This function should be called after sending these messages, for later derivation of the keys. + ctxt.k_enb_count = ctxt.tx_count; + return; +} + +uint32_t nas::get_k_enb_count() { + // UL count for RRC key derivation depends on UL count of the Authentication Request or Service Request. + // On the special case of Service Request without authentication, the UL count for the SR must be used. + return ctxt.k_enb_count; } bool nas::get_k_asme(uint8_t *k_asme_, uint32_t n) { @@ -886,6 +889,7 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const nas_log->info("Network authentication successful\n"); send_authentication_response(res, res_len, sec_hdr_type); nas_log->info_hex(ctxt.k_asme, 32, "Generated k_asme:\n"); + set_k_enb_count(); auth_request = true; } else if (auth_result == AUTH_SYNCH_FAILURE) { nas_log->error("Network authentication synchronization failure.\n"); @@ -1214,6 +1218,7 @@ void nas::gen_service_request(byte_buffer_t *msg) { } ctxt.tx_count++; + set_k_enb_count(); } void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg) { diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index d8c8a4644..ff7471571 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2075,8 +2075,8 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { uint8_t k_asme[32]; nas->get_k_asme(k_asme, 32); rrc_log->debug_hex(k_asme, 32, " UE K_asme"); - rrc_log->debug("Generating K_enb. UL NAS COUNT %d\n", nas->get_ul_count()); - usim->generate_as_keys(k_asme, nas->get_ul_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); + rrc_log->debug("Generating K_enb. UL NAS COUNT %d\n", nas->get_k_enb_count()); + usim->generate_as_keys(k_asme, nas->get_k_enb_count(), k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); rrc_log->debug_hex(k_rrc_enc, 32, "RRC encryption key - k_rrc_enc"); rrc_log->debug_hex(k_rrc_int, 32, "RRC integrity key - k_rrc_int"); rrc_log->debug_hex(k_up_enc, 32, "UP encryption key - k_up_enc");