Added PDCP_SN_LEN constants. Added bearer_id and direction back to the pdcp_entity_base.

master
Pedro Alvarez 5 years ago committed by Andre Puschmann
parent 8e1b9b9f5b
commit 2081b22465

@ -92,19 +92,14 @@ public:
// bool do_rohc;
};
enum class srslte_nr_sn_len_t {
SN_12 = 12,
SN_18 = 18
};
const uint8_t PDCP_SN_LEN_5 = 5;
const uint8_t PDCP_SN_LEN_12 = 12;
const uint8_t PDCP_SN_LEN_18 = 18;
class srslte_pdcp_config_nr_t
{
public:
srslte_pdcp_config_nr_t(uint8_t bearer_id_ = 0,
bool is_control_ = false,
bool is_data_ = false,
uint8_t direction_ = SECURITY_DIRECTION_UPLINK,
srslte_nr_sn_len_t sn_len_ = srslte_nr_sn_len_t::SN_12) :
srslte_pdcp_config_nr_t(uint8_t bearer_id_, bool is_control_, bool is_data_, uint8_t direction_, uint8_t sn_len_) :
bearer_id(bearer_id_),
direction(direction_),
is_control(is_control_),
@ -113,11 +108,11 @@ public:
{
}
uint32_t bearer_id;
uint8_t direction;
bool is_control;
bool is_data;
srslte_nr_sn_len_t sn_len;
uint32_t bearer_id;
uint8_t direction;
bool is_control;
bool is_data;
uint8_t sn_len;
};
class mac_interface_timers

@ -87,13 +87,15 @@ public:
protected:
byte_buffer_pool* pool = byte_buffer_pool::get_instance();
srslte::log* log = nullptr;
srslte::log* log = nullptr;
bool active = false;
uint32_t lcid = 0;
bool rb_is_control = false;
bool do_integrity = false;
bool do_encryption = false;
uint32_t bearer_id = 0;
uint32_t direction = 0;
uint8_t sn_len = 0;
uint8_t sn_len_bytes = 0;
@ -108,15 +110,10 @@ protected:
CIPHERING_ALGORITHM_ID_ENUM cipher_algo = CIPHERING_ALGORITHM_ID_EEA0;
INTEGRITY_ALGORITHM_ID_ENUM integ_algo = INTEGRITY_ALGORITHM_ID_EIA0;
void integrity_generate(
uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* mac);
bool integrity_verify(
uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* mac);
void
cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* ct);
void
cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* msg);
void integrity_generate(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* mac);
bool integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* mac);
void cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* ct);
void cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg);
};
inline uint32_t pdcp_entity_base::HFN(uint32_t count)

@ -72,7 +72,7 @@ private:
srsue::rrc_interface_pdcp* rrc = nullptr;
srsue::gw_interface_pdcp* gw = nullptr;
srslte_pdcp_config_nr_t cfg;
srslte_pdcp_config_nr_t cfg = {0, false, false, 0, PDCP_SN_LEN_12};
uint16_t sn_len_bytes = 0;
@ -84,6 +84,9 @@ private:
// Constants: 3GPP TS 38.323 v15.2.0, section 7.2
uint32_t window_size = 0;
// Packing/Unpacking Helper functions
uint32_t get_rcvd_sn(const unique_byte_buffer_t& pdu);
};
} // namespace srslte

@ -53,8 +53,7 @@ void pdcp_entity_base::config_security(uint8_t* k_rrc_enc_,
/****************************************************************************
* Security functions
***************************************************************************/
void pdcp_entity_base::integrity_generate(
uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* mac)
void pdcp_entity_base::integrity_generate(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* mac)
{
uint8_t *k_int;
@ -99,8 +98,7 @@ void pdcp_entity_base::integrity_generate(
log->debug_hex(msg, msg_len, " Message");
}
bool pdcp_entity_base::integrity_verify(
uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* mac)
bool pdcp_entity_base::integrity_verify(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* mac)
{
uint8_t mac_exp[4] = {};
bool is_valid = true;
@ -163,8 +161,7 @@ bool pdcp_entity_base::integrity_verify(
return is_valid;
}
void pdcp_entity_base::cipher_encrypt(
uint8_t* msg, uint32_t msg_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* ct)
void pdcp_entity_base::cipher_encrypt(uint8_t* msg, uint32_t msg_len, uint32_t count, uint8_t* ct)
{
byte_buffer_t ct_tmp;
uint8_t *k_enc;
@ -197,8 +194,7 @@ void pdcp_entity_base::cipher_encrypt(
}
}
void pdcp_entity_base::cipher_decrypt(
uint8_t* ct, uint32_t ct_len, uint32_t count, uint32_t bearer_id, uint32_t direction, uint8_t* msg)
void pdcp_entity_base::cipher_decrypt(uint8_t* ct, uint32_t ct_len, uint32_t count, uint8_t* msg)
{
byte_buffer_t msg_tmp;
uint8_t *k_enc;

@ -122,7 +122,7 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking)
pdcp_pack_control_pdu(tx_count, sdu.get());
if (do_integrity) {
integrity_generate(
sdu->msg, sdu->N_bytes - 4, tx_count, cfg.bearer_id, cfg.direction, &sdu->msg[sdu->N_bytes - 4]);
sdu->msg, sdu->N_bytes - 4, tx_count, &sdu->msg[sdu->N_bytes - 4]);
}
}
@ -135,12 +135,7 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking)
}
if (do_encryption) {
cipher_encrypt(&sdu->msg[sn_len_bytes],
sdu->N_bytes - sn_len_bytes,
tx_count,
cfg.bearer_id,
cfg.direction,
&sdu->msg[sn_len_bytes]);
cipher_encrypt(&sdu->msg[sn_len_bytes], sdu->N_bytes - sn_len_bytes, tx_count, &sdu->msg[sn_len_bytes]);
log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU (encrypted)", rrc->get_rb_name(lcid).c_str());
}
tx_count++;
@ -181,18 +176,13 @@ void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu)
if (cfg.is_control) {
uint32_t sn = *pdu->msg & 0x1F;
if (do_encryption) {
cipher_decrypt(&pdu->msg[sn_len_bytes],
pdu->N_bytes - sn_len_bytes,
sn,
cfg.bearer_id,
cfg.direction,
&(pdu->msg[sn_len_bytes]));
cipher_decrypt(&pdu->msg[sn_len_bytes], pdu->N_bytes - sn_len_bytes, sn, &(pdu->msg[sn_len_bytes]));
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
if (do_integrity) {
if (not integrity_verify(
pdu->msg, pdu->N_bytes - 4, sn, cfg.bearer_id, cfg.direction, &(pdu->msg[pdu->N_bytes - 4]))) {
pdu->msg, pdu->N_bytes - 4, sn, &(pdu->msg[pdu->N_bytes - 4]))) {
log->error_hex(pdu->msg, pdu->N_bytes, "%s Dropping PDU", rrc->get_rb_name(lcid).c_str());
goto exit;
}
@ -229,7 +219,7 @@ void pdcp_entity_lte::handle_um_drb_pdu(const srslte::unique_byte_buffer_t &pdu)
uint32_t count = (rx_hfn << cfg.sn_len) | sn;
if (do_encryption) {
cipher_decrypt(pdu->msg, pdu->N_bytes, count, cfg.bearer_id, cfg.direction, pdu->msg);
cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg);
log->debug_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
}
@ -291,7 +281,7 @@ void pdcp_entity_lte::handle_am_drb_pdu(const srslte::unique_byte_buffer_t &pdu)
}
// FIXME Check if PDU is not due to re-establishment of lower layers?
cipher_decrypt(pdu->msg, pdu->N_bytes, count, cfg.bearer_id, cfg.direction, pdu->msg);
cipher_decrypt(pdu->msg, pdu->N_bytes, count, pdu->msg);
log->debug_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", rrc->get_rb_name(lcid).c_str());
if (!discard) {

@ -73,7 +73,13 @@ void pdcp_entity_nr::write_sdu(unique_byte_buffer_t sdu, bool blocking)
rrc->get_rb_name(lcid).c_str(),
(do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");
// TODO
// Start discard timer TODO
//
uint32_t count = tx_next;
//integrity_generate(sdu);
}
@ -106,13 +112,14 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
rcvd_count = COUNT(rcvd_hfn, rcvd_sn);
// Integrity check
bool is_valid = integrity_check(pdu);
uint8_t mac[4];
bool is_valid = integrity_verify(pdu->msg, pdu->N_bytes, rcvd_count, mac);
if (!is_valid) {
return; // Invalid packet, drop.
}
// Decripting
cipher_decript(pdu);
cipher_decrypt(pdu->msg, pdu->N_bytes, rcvd_count, pdu->msg);
// Check valid rcvd_count
if (rcvd_count < rx_deliv /*|| check_received_before() TODO*/) {
@ -129,12 +136,27 @@ void pdcp_entity_nr::write_pdu(unique_byte_buffer_t pdu)
// Deliver to upper layers (TODO support in order delivery)
if (is_control()) {
rrc->write_pdu(pdu);
rrc->write_pdu(lcid, std::move(pdu));
} else {
gw->write_pdu(pdu);
gw->write_pdu(lcid, std::move(pdu));
}
// Not clear how to update RX_DELIV without reception buffer (TODO)
// TODO handle reordering timers
}
uint32_t pdcp_entity_nr::get_rcvd_sn(const unique_byte_buffer_t& pdu)
{
uint32_t rcvd_sn = 0;
switch (sn_len) {
case PDCP_SN_LEN_12:
pdu->msg;
case PDCP_SN_LEN_18:
pdu->msg;
default:
log->error("Cannot extract RCVD_SN, invalid SN length configured: %d\n", (int)sn_len);
}
return rcvd_sn;
}
} // namespace srslte

Loading…
Cancel
Save