Adjusting NAS base security function to 5G

master
David Rupprecht 3 years ago committed by David Rupprecht
parent 24cbf1a0c1
commit 3217c00cfc

@ -28,7 +28,7 @@ namespace srsue {
class nas_base class nas_base
{ {
public: public:
nas_base(srslog::basic_logger& logger_); nas_base(srslog::basic_logger& logger_, uint32_t mac_offset, uint32_t seq_offset_, uint32_t bearer_id_);
// PCAP // PCAP
void start_pcap(srsran::nas_pcap* pcap_) { pcap = pcap_; } void start_pcap(srsran::nas_pcap* pcap_) { pcap = pcap_; }
@ -61,6 +61,10 @@ protected:
bool integrity_check(srsran::byte_buffer_t* pdu); bool integrity_check(srsran::byte_buffer_t* pdu);
void cipher_encrypt(srsran::byte_buffer_t* pdu); void cipher_encrypt(srsran::byte_buffer_t* pdu);
void cipher_decrypt(srsran::byte_buffer_t* pdu); void cipher_decrypt(srsran::byte_buffer_t* pdu);
uint32_t mac_offset = 0;
uint32_t seq_offset = 0;
uint32_t bearer_id = 0;
}; };
} // namespace srsue } // namespace srsue

@ -26,6 +26,10 @@
#include "srsue/hdr/stack/upper/nas.h" #include "srsue/hdr/stack/upper/nas.h"
#include "srsue/hdr/stack/upper/nas_idle_procedures.h" #include "srsue/hdr/stack/upper/nas_idle_procedures.h"
#define LTE_MAC_OFFSET 1
#define LTE_SEQ_OFFSET 5
#define LTE_NAS_BEARER 0
using namespace srsran; using namespace srsran;
namespace srsue { namespace srsue {
@ -35,7 +39,7 @@ namespace srsue {
********************************************************************/ ********************************************************************/
nas::nas(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_) : nas::nas(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_) :
nas_base(logger_), nas_base(logger_, LTE_MAC_OFFSET, LTE_SEQ_OFFSET, LTE_NAS_BEARER),
plmn_searcher(this), plmn_searcher(this),
task_sched(task_sched_), task_sched(task_sched_),
t3402(task_sched_.get_unique_timer()), t3402(task_sched_.get_unique_timer()),

@ -27,6 +27,10 @@
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
#define MAC_5G_OFFSET 2
#define SEQ_5G_OFFSET 6
#define NAS_5G_BEARER 1
using namespace srsran; using namespace srsran;
using namespace srsran::nas_5g; using namespace srsran::nas_5g;
@ -37,7 +41,7 @@ namespace srsue {
********************************************************************/ ********************************************************************/
nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_) : nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sched_) :
nas_base(logger_), nas_base(logger_, MAC_5G_OFFSET, SEQ_5G_OFFSET, NAS_5G_BEARER),
task_sched(task_sched_), task_sched(task_sched_),
t3502(task_sched_.get_unique_timer()), t3502(task_sched_.get_unique_timer()),
t3510(task_sched_.get_unique_timer()), t3510(task_sched_.get_unique_timer()),

@ -14,7 +14,9 @@
using namespace srsran; using namespace srsran;
namespace srsue { namespace srsue {
nas_base::nas_base(srslog::basic_logger& logger_) : logger(logger_) {} nas_base::nas_base(srslog::basic_logger& logger_, uint32_t mac_offset_, uint32_t seq_offset_, uint32_t bearer_id_) :
logger(logger_), mac_offset(mac_offset_), seq_offset(seq_offset_), bearer_id(bearer_id_)
{}
int nas_base::parse_security_algorithm_list(std::string algorithm_string, bool* algorithm_caps) int nas_base::parse_security_algorithm_list(std::string algorithm_string, bool* algorithm_caps)
{ {
@ -51,31 +53,13 @@ void nas_base::integrity_generate(uint8_t* key_128,
case INTEGRITY_ALGORITHM_ID_EIA0: case INTEGRITY_ALGORITHM_ID_EIA0:
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA1: case INTEGRITY_ALGORITHM_ID_128_EIA1:
security_128_eia1(key_128, security_128_eia1(key_128, count, bearer_id, direction, msg, msg_len, mac);
count,
0, // Bearer always 0 for NAS
direction,
msg,
msg_len,
mac);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA2: case INTEGRITY_ALGORITHM_ID_128_EIA2:
security_128_eia2(key_128, security_128_eia2(key_128, count, bearer_id, direction, msg, msg_len, mac);
count,
0, // Bearer always 0 for NAS
direction,
msg,
msg_len,
mac);
break; break;
case INTEGRITY_ALGORITHM_ID_128_EIA3: case INTEGRITY_ALGORITHM_ID_128_EIA3:
security_128_eia3(key_128, security_128_eia3(key_128, count, bearer_id, direction, msg, msg_len, mac);
count,
0, // Bearer always 0 for NAS
direction,
msg,
msg_len,
mac);
break; break;
default: default:
break; break;
@ -91,14 +75,18 @@ bool nas_base::integrity_check(byte_buffer_t* pdu)
return false; return false;
} }
if (pdu->N_bytes > 5) { if (pdu->N_bytes > seq_offset) {
uint8_t exp_mac[4] = {0}; uint8_t exp_mac[4] = {0};
uint8_t* mac = &pdu->msg[1]; uint8_t* mac = &pdu->msg[mac_offset];
// generate expected MAC // generate expected MAC
uint32_t count_est = (ctxt.rx_count & 0x00FFFF00u) | pdu->msg[5]; uint32_t count_est = (ctxt.rx_count & 0x00FFFF00u) | pdu->msg[seq_offset];
integrity_generate( integrity_generate(&k_nas_int[16],
&k_nas_int[16], count_est, SECURITY_DIRECTION_DOWNLINK, &pdu->msg[5], pdu->N_bytes - 5, &exp_mac[0]); count_est,
SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[seq_offset],
pdu->N_bytes - seq_offset,
&exp_mac[0]);
// Check if expected mac equals the sent mac // Check if expected mac equals the sent mac
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@ -110,7 +98,7 @@ bool nas_base::integrity_check(byte_buffer_t* pdu)
exp_mac[1], exp_mac[1],
exp_mac[2], exp_mac[2],
exp_mac[3], exp_mac[3],
pdu->msg[5], pdu->msg[seq_offset],
mac[0], mac[0],
mac[1], mac[1],
mac[2], mac[2],
@ -120,7 +108,7 @@ bool nas_base::integrity_check(byte_buffer_t* pdu)
} }
logger.info("Integrity check ok. Local: count=%d, Received: count=%d [%02x %02x %02x %02x]", logger.info("Integrity check ok. Local: count=%d, Received: count=%d [%02x %02x %02x %02x]",
count_est, count_est,
pdu->msg[5], pdu->msg[seq_offset],
mac[0], mac[0],
mac[1], mac[1],
mac[2], mac[2],
@ -152,32 +140,32 @@ void nas_base::cipher_encrypt(byte_buffer_t* pdu)
case CIPHERING_ALGORITHM_ID_128_EEA1: case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&k_nas_enc[16], security_128_eea1(&k_nas_enc[16],
ctxt.tx_count, ctxt.tx_count,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_UPLINK, SECURITY_DIRECTION_UPLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&pdu_tmp.msg[6]); &pdu_tmp.msg[seq_offset + 1]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &pdu_tmp.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA2: case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&k_nas_enc[16], security_128_eea2(&k_nas_enc[16],
ctxt.tx_count, ctxt.tx_count,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_UPLINK, SECURITY_DIRECTION_UPLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&pdu_tmp.msg[6]); &pdu_tmp.msg[seq_offset + 1]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &pdu_tmp.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3: case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&k_nas_enc[16], security_128_eea3(&k_nas_enc[16],
ctxt.tx_count, ctxt.tx_count,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_UPLINK, SECURITY_DIRECTION_UPLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&pdu_tmp.msg[6]); &pdu_tmp.msg[seq_offset + 1]);
memcpy(&pdu->msg[6], &pdu_tmp.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &pdu_tmp.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
default: default:
logger.error("Ciphering algorithm not known"); logger.error("Ciphering algorithm not known");
@ -200,34 +188,34 @@ void nas_base::cipher_decrypt(byte_buffer_t* pdu)
case CIPHERING_ALGORITHM_ID_128_EEA1: case CIPHERING_ALGORITHM_ID_128_EEA1:
security_128_eea1(&k_nas_enc[16], security_128_eea1(&k_nas_enc[16],
count_est, count_est,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_DOWNLINK, SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&tmp_pdu.msg[6]); &tmp_pdu.msg[seq_offset + 1]);
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &tmp_pdu.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA2: case CIPHERING_ALGORITHM_ID_128_EEA2:
security_128_eea2(&k_nas_enc[16], security_128_eea2(&k_nas_enc[16],
count_est, count_est,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_DOWNLINK, SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&tmp_pdu.msg[6]); &tmp_pdu.msg[seq_offset + 1]);
logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &tmp_pdu.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
case CIPHERING_ALGORITHM_ID_128_EEA3: case CIPHERING_ALGORITHM_ID_128_EEA3:
security_128_eea3(&k_nas_enc[16], security_128_eea3(&k_nas_enc[16],
count_est, count_est,
0, // Bearer always 0 for NAS bearer_id,
SECURITY_DIRECTION_DOWNLINK, SECURITY_DIRECTION_DOWNLINK,
&pdu->msg[6], &pdu->msg[seq_offset + 1],
pdu->N_bytes - 6, pdu->N_bytes - seq_offset + 1,
&tmp_pdu.msg[6]); &tmp_pdu.msg[seq_offset + 1]);
logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted"); logger.debug(tmp_pdu.msg, pdu->N_bytes, "Decrypted");
memcpy(&pdu->msg[6], &tmp_pdu.msg[6], pdu->N_bytes - 6); memcpy(&pdu->msg[seq_offset + 1], &tmp_pdu.msg[seq_offset + 1], pdu->N_bytes - seq_offset + 1);
break; break;
default: default:
logger.error("Ciphering algorithms not known"); logger.error("Ciphering algorithms not known");

Loading…
Cancel
Save