mirror of https://github.com/PentHertz/srsLTE.git
Added support for AS ciphering
This commit is contained in:
parent
516fdc27f1
commit
1a323770c9
|
@ -32,9 +32,8 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MAC_LTE_DLT 147
|
||||
#define RRC_LTE_DLT 148
|
||||
#define NAS_LTE_DLT 149
|
||||
#define MAC_LTE_DLT 147
|
||||
#define NAS_LTE_DLT 148
|
||||
|
||||
|
||||
/* This structure gets written to the start of the file */
|
||||
|
@ -74,30 +73,15 @@ typedef struct pcaprec_hdr_s {
|
|||
#define SPS_RNTI 5
|
||||
#define M_RNTI 6
|
||||
|
||||
#define MAC_LTE_START_STRING "mac-lte"
|
||||
|
||||
#define MAC_LTE_START_STRING "mac-lte"
|
||||
#define MAC_LTE_PAYLOAD_TAG 0x01
|
||||
#define MAC_LTE_RNTI_TAG 0x02
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_UEID_TAG 0x03
|
||||
/* 2 bytes, network order */
|
||||
|
||||
#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04
|
||||
/* 2 bytes, network order */
|
||||
/* SFN is stored in 12 MSB and SF in 4 LSB */
|
||||
|
||||
#define MAC_LTE_PREDFINED_DATA_TAG 0x05
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_RETX_TAG 0x06
|
||||
/* 1 byte */
|
||||
|
||||
#define MAC_LTE_CRC_STATUS_TAG 0x07
|
||||
/* 1 byte */
|
||||
|
||||
/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU
|
||||
continues until the end of the frame) */
|
||||
#define MAC_LTE_PAYLOAD_TAG 0x01
|
||||
|
||||
|
||||
/* Context information for every MAC PDU that will be logged */
|
||||
|
@ -112,7 +96,6 @@ typedef struct MAC_Context_Info_t {
|
|||
|
||||
unsigned short sysFrameNumber;
|
||||
unsigned short subFrameNumber;
|
||||
|
||||
} MAC_Context_Info_t;
|
||||
|
||||
/* Context information for every NAS PDU that will be logged */
|
||||
|
@ -121,11 +104,12 @@ typedef struct NAS_Context_Info_s {
|
|||
} NAS_Context_Info_t;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* API functions for opening/writing/closing MAC-LTE PCAP files */
|
||||
/**************************************************************************
|
||||
* API functions for opening/closing LTE PCAP files *
|
||||
**************************************************************************/
|
||||
|
||||
/* Open the file and write file header */
|
||||
inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
|
||||
inline FILE *LTE_PCAP_Open(uint32_t DLT, const char *fileName)
|
||||
{
|
||||
pcap_hdr_t file_header =
|
||||
{
|
||||
|
@ -134,7 +118,7 @@ inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
|
|||
0, /* timezone */
|
||||
0, /* sigfigs - apparently all tools do this */
|
||||
65535, /* snaplen - this should be long enough */
|
||||
MAC_LTE_DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
DLT /* Data Link Type (DLT). Set as unused value 147 for now */
|
||||
};
|
||||
|
||||
FILE *fd = fopen(fileName, "w");
|
||||
|
@ -149,9 +133,21 @@ inline FILE *MAC_LTE_PCAP_Open(const char *fileName)
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* Close the PCAP file */
|
||||
inline void LTE_PCAP_Close(FILE *fd)
|
||||
{
|
||||
if(fd)
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* API functions for writing MAC-LTE PCAP files *
|
||||
**************************************************************************/
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
inline int MAC_LTE_PCAP_WritePDU(FILE *fd, MAC_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length)
|
||||
inline int LTE_PCAP_MAC_WritePDU(FILE *fd, MAC_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length)
|
||||
{
|
||||
pcaprec_hdr_t packet_header;
|
||||
char context_header[256];
|
||||
|
@ -216,45 +212,15 @@ inline int MAC_LTE_PCAP_WritePDU(FILE *fd, MAC_Context_Info_t *context,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Close the PCAP file */
|
||||
inline void MAC_LTE_PCAP_Close(FILE *fd)
|
||||
{
|
||||
if(fd)
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* API functions for opening/writing/closing NAS-LTE PCAP files */
|
||||
/**************************************************************************
|
||||
* API functions for writing NAS-EPS PCAP files *
|
||||
**************************************************************************/
|
||||
|
||||
/* Open the file and write file header */
|
||||
inline FILE *NAS_LTE_PCAP_Open(const char *fileName)
|
||||
{
|
||||
pcap_hdr_t file_header =
|
||||
{
|
||||
0xa1b2c3d4, /* magic number */
|
||||
2, 4, /* version number is 2.4 */
|
||||
0, /* timezone */
|
||||
0, /* sigfigs - apparently all tools do this */
|
||||
65535, /* snaplen - this should be long enough */
|
||||
NAS_LTE_DLT /* Data Link Type (DLT). Set as unused value 149 for now */
|
||||
};
|
||||
|
||||
FILE *fd = fopen(fileName, "w");
|
||||
if (fd == NULL) {
|
||||
printf("Failed to open file \"%s\" for writing\n", fileName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Write the file header */
|
||||
fwrite(&file_header, sizeof(pcap_hdr_t), 1, fd);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
|
||||
inline int NAS_LTE_PCAP_WritePDU(FILE *fd, NAS_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length)
|
||||
/* Write an individual PDU (PCAP packet header + nas-context + nas-pdu) */
|
||||
inline int LTE_PCAP_NAS_WritePDU(FILE *fd, NAS_Context_Info_t *context,
|
||||
const unsigned char *PDU, unsigned int length)
|
||||
{
|
||||
pcaprec_hdr_t packet_header;
|
||||
|
||||
|
@ -281,11 +247,4 @@ inline int NAS_LTE_PCAP_WritePDU(FILE *fd, NAS_Context_Info_t *context,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Close the PCAP file */
|
||||
inline void NAS_LTE_PCAP_Close(FILE *fd)
|
||||
{
|
||||
if(fd)
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
#endif /* UEPCAP_H */
|
||||
|
|
|
@ -197,10 +197,11 @@ public:
|
|||
virtual void write_sdu(uint32_t lcid, srslte::byte_buffer_t *sdu) = 0;
|
||||
virtual void add_bearer(uint32_t lcid, srslte::srslte_pdcp_config_t cnfg = srslte::srslte_pdcp_config_t()) = 0;
|
||||
virtual void config_security(uint32_t lcid,
|
||||
uint8_t *k_rrc_enc_,
|
||||
uint8_t *k_rrc_int_,
|
||||
uint8_t *k_enc_,
|
||||
uint8_t *k_int_,
|
||||
srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
|
||||
srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo_) = 0;
|
||||
virtual void enable_integrity(uint32_t lcid) = 0;
|
||||
virtual void enable_encryption(uint32_t lcid) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -58,10 +58,11 @@ public:
|
|||
void write_sdu(uint32_t lcid, byte_buffer_t *sdu);
|
||||
void add_bearer(uint32_t lcid, srslte_pdcp_config_t cnfg = srslte_pdcp_config_t());
|
||||
void config_security(uint32_t lcid,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_enc,
|
||||
uint8_t *k_int,
|
||||
CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
INTEGRITY_ALGORITHM_ID_ENUM integ_algo);
|
||||
void enable_integrity(uint32_t lcid);
|
||||
void enable_encryption(uint32_t lcid);
|
||||
|
||||
// RLC interface
|
||||
|
|
|
@ -78,10 +78,11 @@ public:
|
|||
|
||||
// RRC interface
|
||||
void write_sdu(byte_buffer_t *sdu);
|
||||
void config_security(uint8_t *k_rrc_enc_,
|
||||
uint8_t *k_rrc_int_,
|
||||
void config_security(uint8_t *k_enc_,
|
||||
uint8_t *k_int_,
|
||||
CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
|
||||
INTEGRITY_ALGORITHM_ID_ENUM integ_algo_);
|
||||
void enable_integrity();
|
||||
void enable_encryption();
|
||||
|
||||
// RLC interface
|
||||
|
@ -102,13 +103,14 @@ private:
|
|||
bool active;
|
||||
uint32_t lcid;
|
||||
srslte_pdcp_config_t cfg;
|
||||
uint8_t sn_len_bytes;
|
||||
bool do_integrity;
|
||||
bool do_encryption;
|
||||
|
||||
uint32_t rx_count;
|
||||
uint32_t tx_count;
|
||||
uint8_t k_rrc_enc[32];
|
||||
uint8_t k_rrc_int[32];
|
||||
uint8_t k_enc[32];
|
||||
uint8_t k_int[32];
|
||||
|
||||
CIPHERING_ALGORITHM_ID_ENUM cipher_algo;
|
||||
INTEGRITY_ALGORITHM_ID_ENUM integ_algo;
|
||||
|
@ -133,6 +135,7 @@ private:
|
|||
|
||||
void run_thread();
|
||||
|
||||
uint8_t get_bearer_id(uint8_t lcid);
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -40,14 +40,14 @@ void mac_pcap::enable(bool en)
|
|||
}
|
||||
void mac_pcap::open(const char* filename, uint32_t ue_id)
|
||||
{
|
||||
pcap_file = MAC_LTE_PCAP_Open(filename);
|
||||
pcap_file = LTE_PCAP_Open(MAC_LTE_DLT, filename);
|
||||
ue_id = ue_id;
|
||||
enable_write = true;
|
||||
}
|
||||
void mac_pcap::close()
|
||||
{
|
||||
fprintf(stdout, "Saving MAC PCAP file\n");
|
||||
MAC_LTE_PCAP_Close(pcap_file);
|
||||
LTE_PCAP_Close(pcap_file);
|
||||
}
|
||||
|
||||
void mac_pcap::pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reTX, bool crc_ok, uint32_t tti,
|
||||
|
@ -65,7 +65,7 @@ void mac_pcap::pack_and_write(uint8_t* pdu, uint32_t pdu_len_bytes, uint32_t reT
|
|||
(uint16_t)(tti%10) /* Subframe number */
|
||||
};
|
||||
if (pdu) {
|
||||
MAC_LTE_PCAP_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||
LTE_PCAP_MAC_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@ void nas_pcap::enable()
|
|||
}
|
||||
void nas_pcap::open(const char* filename, uint32_t ue_id)
|
||||
{
|
||||
pcap_file = NAS_LTE_PCAP_Open(filename);
|
||||
pcap_file = LTE_PCAP_Open(NAS_LTE_DLT, filename);
|
||||
ue_id = ue_id;
|
||||
enable_write = true;
|
||||
}
|
||||
void nas_pcap::close()
|
||||
{
|
||||
fprintf(stdout, "Saving NAS PCAP file\n");
|
||||
MAC_LTE_PCAP_Close(pcap_file);
|
||||
LTE_PCAP_Close(pcap_file);
|
||||
}
|
||||
|
||||
void nas_pcap::write_nas(uint8_t *pdu, uint32_t pdu_len_bytes)
|
||||
|
@ -27,7 +27,7 @@ void nas_pcap::write_nas(uint8_t *pdu, uint32_t pdu_len_bytes)
|
|||
if (enable_write) {
|
||||
NAS_Context_Info_t context;
|
||||
if (pdu) {
|
||||
NAS_LTE_PCAP_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||
LTE_PCAP_NAS_WritePDU(pcap_file, &context, pdu, pdu_len_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,13 +99,19 @@ void pdcp::add_bearer(uint32_t lcid, srslte_pdcp_config_t cfg)
|
|||
}
|
||||
|
||||
void pdcp::config_security(uint32_t lcid,
|
||||
uint8_t *k_rrc_enc,
|
||||
uint8_t *k_rrc_int,
|
||||
uint8_t *k_enc,
|
||||
uint8_t *k_int,
|
||||
CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
|
||||
INTEGRITY_ALGORITHM_ID_ENUM integ_algo)
|
||||
{
|
||||
if(valid_lcid(lcid))
|
||||
pdcp_array[lcid].config_security(k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
|
||||
pdcp_array[lcid].config_security(k_enc, k_int, cipher_algo, integ_algo);
|
||||
}
|
||||
|
||||
void pdcp::enable_integrity(uint32_t lcid)
|
||||
{
|
||||
if(valid_lcid(lcid))
|
||||
pdcp_array[lcid].enable_integrity();
|
||||
}
|
||||
|
||||
void pdcp::enable_encryption(uint32_t lcid)
|
||||
|
|
|
@ -56,6 +56,12 @@ void pdcp_entity::init(srsue::rlc_interface_pdcp *rlc_,
|
|||
rx_count = 0;
|
||||
do_integrity = false;
|
||||
do_encryption = false;
|
||||
if(cfg.is_control) {
|
||||
cfg.sn_len = 5;
|
||||
sn_len_bytes = 1;
|
||||
} else {
|
||||
sn_len_bytes = (cfg.sn_len+7)/8;
|
||||
}
|
||||
|
||||
start(PDCP_THREAD_PRIO);
|
||||
|
||||
|
@ -87,46 +93,57 @@ bool pdcp_entity::is_active()
|
|||
void pdcp_entity::write_sdu(byte_buffer_t *sdu)
|
||||
{
|
||||
log->info_hex(sdu->msg, sdu->N_bytes,
|
||||
"TX %s SDU, do_integrity = %s, do_encryption = %s", get_rb_name(lcid),
|
||||
"TX %s SDU, SN: %d, do_integrity = %s, do_encryption = %s",
|
||||
get_rb_name(lcid), tx_count,
|
||||
(do_integrity) ? "true" : "false", (do_encryption) ? "true" : "false");
|
||||
|
||||
if (cfg.is_control) {
|
||||
pdcp_pack_control_pdu(tx_count, sdu);
|
||||
if(do_integrity)
|
||||
{
|
||||
if(do_integrity) {
|
||||
integrity_generate(sdu->msg,
|
||||
sdu->N_bytes-4,
|
||||
&sdu->msg[sdu->N_bytes-4]);
|
||||
}
|
||||
tx_count++;
|
||||
}
|
||||
|
||||
if (cfg.is_data) {
|
||||
if(12 == cfg.sn_len) {
|
||||
pdcp_pack_data_pdu_long_sn(tx_count++, sdu);
|
||||
pdcp_pack_data_pdu_long_sn(tx_count, sdu);
|
||||
} else {
|
||||
pdcp_pack_data_pdu_short_sn(tx_count++, sdu);
|
||||
pdcp_pack_data_pdu_short_sn(tx_count, sdu);
|
||||
}
|
||||
}
|
||||
|
||||
if(do_encryption) {
|
||||
cipher_encrypt(&sdu->msg[sn_len_bytes],
|
||||
sdu->N_bytes-sn_len_bytes,
|
||||
&sdu->msg[sn_len_bytes]);
|
||||
log->info_hex(sdu->msg, sdu->N_bytes, "TX %s SDU (encrypted)", get_rb_name(lcid));
|
||||
}
|
||||
tx_count++;
|
||||
|
||||
rlc->write_sdu(lcid, sdu);
|
||||
}
|
||||
|
||||
void pdcp_entity::config_security(uint8_t *k_rrc_enc_,
|
||||
uint8_t *k_rrc_int_,
|
||||
void pdcp_entity::config_security(uint8_t *k_enc_,
|
||||
uint8_t *k_int_,
|
||||
CIPHERING_ALGORITHM_ID_ENUM cipher_algo_,
|
||||
INTEGRITY_ALGORITHM_ID_ENUM integ_algo_)
|
||||
{
|
||||
do_integrity = true;
|
||||
for(int i=0; i<32; i++)
|
||||
{
|
||||
k_rrc_enc[i] = k_rrc_enc_[i];
|
||||
k_rrc_int[i] = k_rrc_int_[i];
|
||||
k_enc[i] = k_enc_[i];
|
||||
k_int[i] = k_int_[i];
|
||||
}
|
||||
cipher_algo = cipher_algo_;
|
||||
integ_algo = integ_algo_;
|
||||
}
|
||||
|
||||
void pdcp_entity::enable_integrity()
|
||||
{
|
||||
do_integrity = true;
|
||||
}
|
||||
|
||||
void pdcp_entity::enable_encryption()
|
||||
{
|
||||
do_encryption = true;
|
||||
|
@ -142,24 +159,26 @@ void pdcp_entity::integrity_generate( uint8_t *msg,
|
|||
uint32_t msg_len,
|
||||
uint8_t *mac)
|
||||
{
|
||||
uint8_t bearer;
|
||||
|
||||
switch(integ_algo)
|
||||
{
|
||||
case INTEGRITY_ALGORITHM_ID_EIA0:
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM_ID_128_EIA1:
|
||||
security_128_eia1(&k_rrc_int[16],
|
||||
security_128_eia1(&k_int[16],
|
||||
tx_count,
|
||||
lcid-1,
|
||||
get_bearer_id(lcid),
|
||||
cfg.direction,
|
||||
msg,
|
||||
msg_len,
|
||||
mac);
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM_ID_128_EIA2:
|
||||
security_128_eia2(&k_rrc_int[16],
|
||||
security_128_eia2(&k_int[16],
|
||||
tx_count,
|
||||
lcid-1,
|
||||
cfg.direction,
|
||||
get_bearer_id(lcid),
|
||||
cfg.direction,
|
||||
msg,
|
||||
msg_len,
|
||||
mac);
|
||||
|
@ -183,19 +202,19 @@ bool pdcp_entity::integrity_verify(uint8_t *msg,
|
|||
case INTEGRITY_ALGORITHM_ID_EIA0:
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM_ID_128_EIA1:
|
||||
security_128_eia1(&k_rrc_int[16],
|
||||
security_128_eia1(&k_int[16],
|
||||
count,
|
||||
lcid-1,
|
||||
( cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
get_bearer_id(lcid),
|
||||
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
msg,
|
||||
msg_len,
|
||||
mac_exp);
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM_ID_128_EIA2:
|
||||
security_128_eia2(&k_rrc_int[16],
|
||||
security_128_eia2(&k_int[16],
|
||||
count,
|
||||
lcid-1,
|
||||
( cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
get_bearer_id(lcid),
|
||||
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
msg,
|
||||
msg_len,
|
||||
mac_exp);
|
||||
|
@ -240,20 +259,20 @@ void pdcp_entity::cipher_encrypt(uint8_t *msg,
|
|||
case CIPHERING_ALGORITHM_ID_EEA0:
|
||||
break;
|
||||
case CIPHERING_ALGORITHM_ID_128_EEA1:
|
||||
security_128_eea1(&(k_rrc_enc[16]),
|
||||
security_128_eea1(&(k_enc[16]),
|
||||
tx_count,
|
||||
lcid - 1,
|
||||
cfg.direction,
|
||||
get_bearer_id(lcid),
|
||||
cfg.direction,
|
||||
msg,
|
||||
msg_len,
|
||||
ct_tmp.msg);
|
||||
memcpy(ct, ct_tmp.msg, msg_len);
|
||||
break;
|
||||
case CIPHERING_ALGORITHM_ID_128_EEA2:
|
||||
security_128_eea2(&(k_rrc_enc[16]),
|
||||
security_128_eea2(&(k_enc[16]),
|
||||
tx_count,
|
||||
lcid - 1,
|
||||
cfg.direction,
|
||||
get_bearer_id(lcid),
|
||||
cfg.direction,
|
||||
msg,
|
||||
msg_len,
|
||||
ct_tmp.msg);
|
||||
|
@ -275,19 +294,19 @@ void pdcp_entity::cipher_decrypt(uint8_t *ct,
|
|||
case CIPHERING_ALGORITHM_ID_EEA0:
|
||||
break;
|
||||
case CIPHERING_ALGORITHM_ID_128_EEA1:
|
||||
security_128_eea1(&(k_rrc_enc[16]),
|
||||
security_128_eea1(&(k_enc[16]),
|
||||
count,
|
||||
lcid - 1,
|
||||
( cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
get_bearer_id(lcid),
|
||||
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
ct,
|
||||
ct_len,
|
||||
msg_tmp.msg);
|
||||
break;
|
||||
case CIPHERING_ALGORITHM_ID_128_EEA2:
|
||||
security_128_eea2(&(k_rrc_enc[16]),
|
||||
security_128_eea2(&(k_enc[16]),
|
||||
count,
|
||||
lcid - 1,
|
||||
( cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
get_bearer_id(lcid),
|
||||
(cfg.direction == SECURITY_DIRECTION_DOWNLINK) ? (SECURITY_DIRECTION_UPLINK) : (SECURITY_DIRECTION_DOWNLINK),
|
||||
ct,
|
||||
ct_len,
|
||||
msg_tmp.msg);
|
||||
|
@ -306,39 +325,35 @@ void pdcp_entity::run_thread()
|
|||
|
||||
while(running) {
|
||||
rx_pdu_queue.read(&pdu);
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", get_rb_name(lcid));
|
||||
|
||||
// Handle SRB messages
|
||||
switch(lcid)
|
||||
{
|
||||
case RB_ID_SRB0:
|
||||
// Simply pass on to RRC
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", get_rb_name(lcid));
|
||||
rrc->write_pdu(RB_ID_SRB0, pdu);
|
||||
break;
|
||||
case RB_ID_SRB1: // Intentional fall-through
|
||||
case RB_ID_SRB2:
|
||||
uint32_t sn;
|
||||
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU", get_rb_name(lcid));
|
||||
|
||||
if (do_encryption) {
|
||||
cipher_decrypt(&(pdu->msg[1]),
|
||||
pdu->msg[0],
|
||||
pdu->N_bytes - 1,
|
||||
&(pdu->msg[1]));
|
||||
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
|
||||
rx_count,
|
||||
pdu->N_bytes - sn_len_bytes,
|
||||
&(pdu->msg[sn_len_bytes]));
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", get_rb_name(lcid));
|
||||
}
|
||||
|
||||
if (do_integrity) {
|
||||
integrity_verify(pdu->msg,
|
||||
pdu->msg[0],
|
||||
rx_count,
|
||||
pdu->N_bytes - 4,
|
||||
&(pdu->msg[pdu->N_bytes - 4]));
|
||||
}
|
||||
|
||||
pdcp_unpack_control_pdu(pdu, &sn);
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s SDU SN: %d",
|
||||
get_rb_name(lcid), sn);
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", get_rb_name(lcid), sn);
|
||||
rrc->write_pdu(lcid, pdu);
|
||||
break;
|
||||
}
|
||||
|
@ -347,18 +362,35 @@ void pdcp_entity::run_thread()
|
|||
if(lcid >= RB_ID_DRB1)
|
||||
{
|
||||
uint32_t sn;
|
||||
if (do_encryption) {
|
||||
cipher_decrypt(&(pdu->msg[sn_len_bytes]),
|
||||
rx_count,
|
||||
pdu->N_bytes - sn_len_bytes,
|
||||
&(pdu->msg[sn_len_bytes]));
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU (decrypted)", get_rb_name(lcid));
|
||||
}
|
||||
if(12 == cfg.sn_len)
|
||||
{
|
||||
pdcp_unpack_data_pdu_long_sn(pdu, &sn);
|
||||
} else {
|
||||
pdcp_unpack_data_pdu_short_sn(pdu, &sn);
|
||||
}
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU: %d", get_rb_name(lcid), sn);
|
||||
log->info_hex(pdu->msg, pdu->N_bytes, "RX %s PDU SN: %d", get_rb_name(lcid), sn);
|
||||
gw->write_pdu(lcid, pdu);
|
||||
}
|
||||
|
||||
rx_count++;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pdcp_entity::get_bearer_id(uint8_t lcid)
|
||||
{
|
||||
if(lcid <= RB_ID_SRB2) {
|
||||
return lcid - 1;
|
||||
} else {
|
||||
return lcid - RB_ID_SRB2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -1164,11 +1164,21 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) {
|
|||
cipher_algo = (CIPHERING_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.cipher_alg;
|
||||
integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) dl_dcch_msg.msg.security_mode_cmd.sec_algs.int_alg;
|
||||
|
||||
// Configure PDCP for security
|
||||
rrc_log->info("Received Security Mode Command eea: %s, eia: %s\n",
|
||||
ciphering_algorithm_id_text[cipher_algo],
|
||||
integrity_algorithm_id_text[integ_algo]);
|
||||
|
||||
// Generate AS security keys
|
||||
uint8_t k_asme[32];
|
||||
nas->get_k_asme(k_asme, 32);
|
||||
usim->generate_as_keys(k_asme, nas->get_ul_count()-1, 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");
|
||||
|
||||
// Configure PDCP for security
|
||||
pdcp->config_security(lcid, k_rrc_enc, k_rrc_int, cipher_algo, integ_algo);
|
||||
pdcp->enable_integrity(lcid);
|
||||
send_security_mode_complete(lcid, pdu);
|
||||
pdcp->enable_encryption(lcid);
|
||||
break;
|
||||
|
@ -1626,6 +1636,8 @@ void rrc::add_srb(LIBLTE_RRC_SRB_TO_ADD_MOD_STRUCT *srb_cnfg) {
|
|||
pdcp->add_bearer(srb_cnfg->srb_id, srslte_pdcp_config_t(true)); // Set PDCP config control flag
|
||||
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->enable_integrity(srb_cnfg->srb_id);
|
||||
pdcp->enable_encryption(srb_cnfg->srb_id);
|
||||
}
|
||||
|
||||
// Setup RLC
|
||||
|
@ -1692,7 +1704,8 @@ void rrc::add_drb(LIBLTE_RRC_DRB_TO_ADD_MOD_STRUCT *drb_cnfg) {
|
|||
}
|
||||
}
|
||||
pdcp->add_bearer(lcid, pdcp_cfg);
|
||||
// TODO: setup PDCP security (using k_up_enc)
|
||||
pdcp->config_security(lcid, k_up_enc, k_up_int, cipher_algo, integ_algo);
|
||||
pdcp->enable_encryption(lcid);
|
||||
|
||||
// Setup RLC
|
||||
rlc->add_bearer(lcid, srslte_rlc_config_t(&drb_cnfg->rlc_cnfg));
|
||||
|
|
Loading…
Reference in New Issue