diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 52b673abd..ae8264d33 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -200,6 +200,7 @@ public: uint32_t lcid, uint8_t *k_rrc_enc_, uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; }; diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 41939fff8..02cb25e90 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -244,12 +244,14 @@ public: virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0; virtual void change_lcid(uint32_t old_lcid, uint32_t new_lcid) = 0; virtual void config_security(uint32_t lcid, - uint8_t *k_enc_, - uint8_t *k_int_, + uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; - virtual void config_security_all(uint8_t *k_enc_, - uint8_t *k_int_, + virtual void config_security_all(uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; virtual void enable_integrity(uint32_t lcid) = 0; diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index 7272f5079..753f8f597 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -63,12 +63,14 @@ public: void del_bearer(uint32_t lcid); void change_lcid(uint32_t old_lcid, uint32_t new_lcid); void config_security(uint32_t lcid, - uint8_t *k_enc, - uint8_t *k_int, + uint8_t *k_rrc_enc, + uint8_t *k_rrc_int, + uint8_t *k_up_enc, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo); - void config_security_all(uint8_t *k_enc, - uint8_t *k_int, + void config_security_all(uint8_t *k_rrc_enc, + uint8_t *k_rrc_int, + uint8_t *k_up_enc, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo); void enable_integrity(uint32_t lcid); diff --git a/lib/include/srslte/upper/pdcp_entity.h b/lib/include/srslte/upper/pdcp_entity.h index 2f9fafdd9..8d4b87204 100644 --- a/lib/include/srslte/upper/pdcp_entity.h +++ b/lib/include/srslte/upper/pdcp_entity.h @@ -78,8 +78,9 @@ public: // RRC interface void write_sdu(byte_buffer_t *sdu, bool blocking); - void config_security(uint8_t *k_enc_, - uint8_t *k_int_, + void config_security(uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, INTEGRITY_ALGORITHM_ID_ENUM integ_algo_); void enable_integrity(); @@ -107,9 +108,10 @@ private: uint32_t rx_count; uint32_t tx_count; - uint8_t k_enc[32]; - uint8_t k_int[32]; - + uint8_t k_rrc_enc[32]; + uint8_t k_rrc_int[32]; + uint8_t k_up_enc[32]; + CIPHERING_ALGORITHM_ID_ENUM cipher_algo; INTEGRITY_ALGORITHM_ID_ENUM integ_algo; diff --git a/lib/include/srslte/upper/pdcp_interface.h b/lib/include/srslte/upper/pdcp_interface.h index 9c4df085e..18488248e 100644 --- a/lib/include/srslte/upper/pdcp_interface.h +++ b/lib/include/srslte/upper/pdcp_interface.h @@ -56,8 +56,9 @@ public: // RRC interface virtual void write_sdu(byte_buffer_t *sdu, bool blocking) = 0; - virtual void config_security(uint8_t *k_enc_, - uint8_t *k_int_, + virtual void config_security(uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0; virtual void enable_integrity() = 0; diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index b5cd23bf7..7fcc22f64 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -216,26 +216,25 @@ exit: } void pdcp::config_security(uint32_t lcid, - uint8_t *k_enc, - uint8_t *k_int, + uint8_t *k_rrc_enc, + uint8_t *k_rrc_int, + uint8_t *k_up_enc, CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { pthread_rwlock_rdlock(&rwlock); if (valid_lcid(lcid)) { - pdcp_array.at(lcid)->config_security(k_enc, k_int, cipher_algo, integ_algo); + pdcp_array.at(lcid)->config_security(k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); } pthread_rwlock_unlock(&rwlock); } -void pdcp::config_security_all(uint8_t *k_enc, - uint8_t *k_int, - CIPHERING_ALGORITHM_ID_ENUM cipher_algo, - INTEGRITY_ALGORITHM_ID_ENUM integ_algo) +void pdcp::config_security_all(uint8_t* k_rrc_enc, uint8_t* k_rrc_int, uint8_t* k_up_enc, + CIPHERING_ALGORITHM_ID_ENUM cipher_algo, INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { pthread_rwlock_rdlock(&rwlock); for (pdcp_map_t::iterator it = pdcp_array.begin(); it != pdcp_array.end(); ++it) { - it->second->config_security(k_enc, k_int, cipher_algo, integ_algo); + it->second->config_security(k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); } pthread_rwlock_unlock(&rwlock); } diff --git a/lib/src/upper/pdcp_entity.cc b/lib/src/upper/pdcp_entity.cc index ad1e97e12..c9c01e217 100644 --- a/lib/src/upper/pdcp_entity.cc +++ b/lib/src/upper/pdcp_entity.cc @@ -157,15 +157,17 @@ void pdcp_entity::write_sdu(byte_buffer_t *sdu, bool blocking) rlc->write_sdu(lcid, sdu, blocking); } -void pdcp_entity::config_security(uint8_t *k_enc_, - uint8_t *k_int_, +void pdcp_entity::config_security(uint8_t *k_rrc_enc_, + uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) { for(int i=0; i<32; i++) { - k_enc[i] = k_enc_[i]; - k_int[i] = k_int_[i]; + k_rrc_enc[i] = k_rrc_enc_[i]; + k_rrc_int[i] = k_rrc_int_[i]; + k_up_enc[i] = k_up_enc_[i]; } cipher_algo = cipher_algo_; integ_algo = integ_algo_; @@ -255,7 +257,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg, case INTEGRITY_ALGORITHM_ID_EIA0: break; case INTEGRITY_ALGORITHM_ID_128_EIA1: - security_128_eia1(&k_int[16], + security_128_eia1(&k_rrc_int[16], tx_count, cfg.bearer_id - 1, cfg.direction, @@ -264,7 +266,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg, mac); break; case INTEGRITY_ALGORITHM_ID_128_EIA2: - security_128_eia2(&k_int[16], + security_128_eia2(&k_rrc_int[16], tx_count, cfg.bearer_id - 1, cfg.direction, @@ -277,7 +279,7 @@ void pdcp_entity::integrity_generate( uint8_t *msg, } log->debug("Integrity gen input:\n"); - log->debug_hex(&k_int[16], 16, " K_int"); + log->debug_hex(&k_rrc_int[16], 16, " K_rrc_int"); log->debug(" Local count: %d\n", tx_count); log->debug(" Bearer ID: %d\n", cfg.bearer_id); log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Downlink" : "Uplink"); @@ -299,7 +301,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg, case INTEGRITY_ALGORITHM_ID_EIA0: break; case INTEGRITY_ALGORITHM_ID_128_EIA1: - security_128_eia1(&k_int[16], + security_128_eia1(&k_rrc_int[16], count, cfg.bearer_id - 1, (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), @@ -308,7 +310,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg, mac_exp); break; case INTEGRITY_ALGORITHM_ID_128_EIA2: - security_128_eia2(&k_int[16], + security_128_eia2(&k_rrc_int[16], count, cfg.bearer_id - 1, (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK), @@ -321,7 +323,7 @@ bool pdcp_entity::integrity_verify(uint8_t *msg, } log->debug("Integrity check input:\n"); - log->debug_hex(&k_int[16], 16, " K_int"); + log->debug_hex(&k_rrc_int[16], 16, " K_rrc_int"); log->debug(" Local count: %d\n", count); log->debug(" Bearer ID: %d\n", cfg.bearer_id); log->debug(" Direction: %s\n", (cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? "Uplink" : "Downlink"); @@ -357,6 +359,15 @@ void pdcp_entity::cipher_encrypt(uint8_t *msg, uint8_t *ct) { byte_buffer_t ct_tmp; + uint8_t *k_enc; + + // If control plane use RRC encrytion key. If data use user plane key + if (cfg.is_control) { + k_enc = k_rrc_enc; + } else { + k_enc = k_up_enc; + } + switch(cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: @@ -392,6 +403,14 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct, uint8_t *msg) { byte_buffer_t msg_tmp; + uint8_t *k_enc; + // If control plane use RRC encrytion key. If data use user plane key + if (cfg.is_control) { + k_enc = k_rrc_enc; + } else { + k_enc = k_up_enc; + } + switch(cipher_algo) { case CIPHERING_ALGORITHM_ID_EEA0: diff --git a/srsenb/hdr/upper/pdcp.h b/srsenb/hdr/upper/pdcp.h index 1dc555fee..dce3af419 100644 --- a/srsenb/hdr/upper/pdcp.h +++ b/srsenb/hdr/upper/pdcp.h @@ -57,6 +57,7 @@ public: uint32_t lcid, uint8_t *k_rrc_enc_, uint8_t *k_rrc_int_, + uint8_t *k_up_enc_, srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_); diff --git a/srsenb/src/upper/pdcp.cc b/srsenb/src/upper/pdcp.cc index 4d242bdc1..9c7a69b28 100644 --- a/srsenb/src/upper/pdcp.cc +++ b/srsenb/src/upper/pdcp.cc @@ -110,13 +110,13 @@ void pdcp::reset(uint16_t rnti) pthread_rwlock_unlock(&rwlock); } -void pdcp::config_security(uint16_t rnti, uint32_t lcid, uint8_t* k_rrc_enc_, uint8_t* k_rrc_int_, - srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, +void pdcp::config_security(uint16_t rnti, uint32_t lcid, uint8_t* k_rrc_enc_, uint8_t* k_rrc_int_, uint8_t* k_up_enc_, + srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) { pthread_rwlock_rdlock(&rwlock); if (users.count(rnti)) { - users[rnti].pdcp->config_security(lcid, k_rrc_enc_, k_rrc_int_, cipher_algo_, integ_algo_); + users[rnti].pdcp->config_security(lcid, k_rrc_enc_, k_rrc_int_, k_up_enc_, cipher_algo_, integ_algo_); users[rnti].pdcp->enable_integrity(lcid); users[rnti].pdcp->enable_encryption(lcid); } diff --git a/srsenb/src/upper/rrc.cc b/srsenb/src/upper/rrc.cc index 678162cd3..903771f4d 100644 --- a/srsenb/src/upper/rrc.cc +++ b/srsenb/src/upper/rrc.cc @@ -804,7 +804,7 @@ void rrc::configure_security(uint16_t rnti, srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) { // TODO: add k_up_enc, k_up_int support to PDCP - pdcp->config_security(rnti, lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + pdcp->config_security(rnti, lcid, k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); } /******************************************************************************* diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 0f8767e1d..2bf578d88 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -1576,7 +1576,7 @@ bool rrc::ho_prepare() usim->generate_as_keys_ho(mob_ctrl_info->target_pci, phy->get_current_earfcn(), ncc, k_rrc_enc, k_rrc_int, k_up_enc, k_up_int, cipher_algo, integ_algo); - pdcp->config_security_all(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + pdcp->config_security_all(k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); send_rrc_con_reconfig_complete(); } return true; @@ -2160,7 +2160,7 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t* pdu) security_is_activated = true; // Configure PDCP for security - pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); pdcp->enable_integrity(lcid); send_security_mode_complete(); pdcp->enable_encryption(lcid); @@ -2678,7 +2678,7 @@ void rrc::add_srb(srb_to_add_mod_s* srb_cnfg) pdcp_cfg.bearer_id = srb_cnfg->srb_id; pdcp->add_bearer(srb_cnfg->srb_id, pdcp_cfg); if(RB_ID_SRB2 == srb_cnfg->srb_id) { - pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo); + pdcp->config_security(srb_cnfg->srb_id, k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); pdcp->enable_integrity(srb_cnfg->srb_id); pdcp->enable_encryption(srb_cnfg->srb_id); } @@ -2747,7 +2747,7 @@ void rrc::add_drb(drb_to_add_mod_s* drb_cnfg) } } pdcp->add_bearer(lcid, pdcp_cfg); - pdcp->config_security(lcid, k_up_enc, k_up_int, cipher_algo, integ_algo); + pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, k_up_enc, cipher_algo, integ_algo); pdcp->enable_encryption(lcid); // Setup RLC