diff --git a/lib/include/srslte/upper/pdcp.h b/lib/include/srslte/upper/pdcp.h index f771bb03c..12b3af2fd 100644 --- a/lib/include/srslte/upper/pdcp.h +++ b/lib/include/srslte/upper/pdcp.h @@ -54,6 +54,7 @@ public: void config_security_all(as_security_config_t sec_cfg); void enable_integrity(uint32_t lcid, srslte_direction_t direction); void enable_encryption(uint32_t lcid, srslte_direction_t direction); + void enable_security_timed(uint32_t lcid, srslte_direction_t direction, uint32_t sn); bool get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); // RLC interface diff --git a/lib/include/srslte/upper/pdcp_entity_base.h b/lib/include/srslte/upper/pdcp_entity_base.h index 135d244ac..6650efa2d 100644 --- a/lib/include/srslte/upper/pdcp_entity_base.h +++ b/lib/include/srslte/upper/pdcp_entity_base.h @@ -83,6 +83,7 @@ public: } else { integrity_direction = direction; } + log->debug("LCID=%d, integrity=%s\n", lcid, srslte_direction_text[integrity_direction]); } void enable_encryption(srslte_direction_t direction = DIRECTION_TXRX) @@ -95,6 +96,22 @@ public: } else { encryption_direction = direction; } + log->debug("LCID=%d encryption=%s\n", lcid, srslte_direction_text[integrity_direction]); + } + + void enable_security_timed(srslte_direction_t direction, uint32_t sn) + { + switch (direction) { + case DIRECTION_TX: + enable_security_tx_sn = sn; + break; + case DIRECTION_RX: + enable_security_rx_sn = sn; + break; + default: + log->error("Timed security activation for direction %s not supported.\n", srslte_direction_text[direction]); + break; + } } void config_security(as_security_config_t sec_cfg_); @@ -119,6 +136,9 @@ protected: srslte_direction_t integrity_direction = DIRECTION_NONE; srslte_direction_t encryption_direction = DIRECTION_NONE; + int32_t enable_security_tx_sn = -1; // TX SN at which security will be enabled + int32_t enable_security_rx_sn = -1; // RX SN at which security will be enabled + pdcp_config_t cfg = {1, PDCP_RB_IS_DRB, SECURITY_DIRECTION_DOWNLINK, diff --git a/lib/include/srslte/upper/pdcp_entity_lte.h b/lib/include/srslte/upper/pdcp_entity_lte.h index 6a36e220e..fe43efd76 100644 --- a/lib/include/srslte/upper/pdcp_entity_lte.h +++ b/lib/include/srslte/upper/pdcp_entity_lte.h @@ -60,9 +60,6 @@ public: void write_sdu(unique_byte_buffer_t sdu, bool blocking); void get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn); - uint32_t get_ul_count(); - uint32_t get_last_submitted_rx_count(); - // RLC interface void write_pdu(unique_byte_buffer_t pdu); diff --git a/lib/src/upper/pdcp.cc b/lib/src/upper/pdcp.cc index bbc6c2dd1..365295335 100644 --- a/lib/src/upper/pdcp.cc +++ b/lib/src/upper/pdcp.cc @@ -225,6 +225,13 @@ void pdcp::enable_encryption(uint32_t lcid, srslte_direction_t direction) } } +void pdcp::enable_security_timed(uint32_t lcid, srslte_direction_t direction, uint32_t sn) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->enable_security_timed(direction, sn); + } +} + bool pdcp::get_bearer_status(uint32_t lcid, uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) { if (not valid_lcid(lcid)) { diff --git a/lib/src/upper/pdcp_entity_lte.cc b/lib/src/upper/pdcp_entity_lte.cc index a59dad332..2f64df338 100644 --- a/lib/src/upper/pdcp_entity_lte.cc +++ b/lib/src/upper/pdcp_entity_lte.cc @@ -96,6 +96,13 @@ void pdcp_entity_lte::reset() // GW/RRC interface void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking) { + // check for pending security config in transmit direction + if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast(tx_count)) { + enable_integrity(DIRECTION_TX); + enable_encryption(DIRECTION_TX); + enable_security_tx_sn = -1; + } + log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU, SN=%d, integrity=%s, encryption=%s", @@ -136,11 +143,21 @@ void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) return; } + // Pull out SN + uint32_t sn = read_data_header(pdu); + + // check for pending security config in receive direction + if (enable_security_rx_sn != -1 && enable_security_rx_sn == static_cast(sn)) { + enable_integrity(DIRECTION_RX); + enable_encryption(DIRECTION_RX); + enable_security_rx_sn = -1; + } + log->info_hex(pdu->msg, pdu->N_bytes, "%s Rx PDU SN=%d (%d B, integrity=%s, encryption=%s)", rrc->get_rb_name(lcid).c_str(), - read_data_header(pdu), + sn, pdu->N_bytes, srslte_direction_text[integrity_direction], srslte_direction_text[encryption_direction]); @@ -303,15 +320,6 @@ void pdcp_entity_lte::handle_am_drb_pdu(srslte::unique_byte_buffer_t pdu) /**************************************************************************** * Security functions ***************************************************************************/ -uint32_t pdcp_entity_lte::get_last_submitted_rx_count() -{ - return COUNT(rx_hfn, last_submitted_pdcp_rx_sn); -} - -uint32_t pdcp_entity_lte::get_ul_count() -{ - return tx_count; -} void pdcp_entity_lte::get_bearer_status(uint16_t* dlsn, uint16_t* dlhfn, uint16_t* ulsn, uint16_t* ulhfn) {