From 23cc0ab011eae9acaf645a19d8c36cd46b629870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn?= Date: Mon, 9 Jul 2018 11:52:17 +0200 Subject: [PATCH 1/6] enb: add bind address for s1ap connection (#128) add s1c_bind_addr config option to specify the local bind address used for S1AP connections instead of using the GTP address. This allows operation on setups with split S1U and S1C networks. --- srsenb/enb.conf.example | 4 ++-- srsenb/hdr/upper/s1ap.h | 1 + srsenb/src/main.cc | 1 + srsenb/src/upper/s1ap.cc | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 4fa2a5731..1c7c93214 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -25,12 +25,12 @@ tac = 0x0007 mcc = 001 mnc = 01 mme_addr = 127.0.1.100 -gtp_bind_addr = 127.0.0.1 +gtp_bind_addr = 127.0.1.1 +s1c_bind_addr = 127.0.1.1 n_prb = 50 #tm = 4 #nof_ports = 2 - ##################################################################### # eNB configuration files # diff --git a/srsenb/hdr/upper/s1ap.h b/srsenb/hdr/upper/s1ap.h index 284b67d03..b686b6583 100644 --- a/srsenb/hdr/upper/s1ap.h +++ b/srsenb/hdr/upper/s1ap.h @@ -49,6 +49,7 @@ typedef struct { uint16_t mnc; // BCD-coded with 0xF filler std::string mme_addr; std::string gtp_bind_addr; + std::string s1c_bind_addr; std::string enb_name; }s1ap_args_t; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index eab5d4bcf..3622f8d05 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -77,6 +77,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) { ("enb.mnc", bpo::value(&mnc)->default_value("01"), "Mobile Network Code") ("enb.mme_addr", bpo::value(&args->enb.s1ap.mme_addr)->default_value("127.0.0.1"),"IP address of MME for S1 connnection") ("enb.gtp_bind_addr", bpo::value(&args->enb.s1ap.gtp_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for GTP connection") + ("enb.s1c_bind_addr", bpo::value(&args->enb.s1ap.s1c_bind_addr)->default_value("192.168.3.1"), "Local IP address to bind for S1AP connection") ("enb.phy_cell_id", bpo::value(&args->enb.pci)->default_value(0), "Physical Cell Identity (PCI)") ("enb.n_prb", bpo::value(&args->enb.n_prb)->default_value(25), "Number of PRB") ("enb.nof_ports", bpo::value(&args->enb.nof_ports)->default_value(1), "Number of ports") diff --git a/srsenb/src/upper/s1ap.cc b/srsenb/src/upper/s1ap.cc index 8cc4bebda..1e2b25987 100644 --- a/srsenb/src/upper/s1ap.cc +++ b/srsenb/src/upper/s1ap.cc @@ -274,8 +274,8 @@ bool s1ap::connect_mme() memset(&local_addr, 0, sizeof(struct sockaddr_in)); local_addr.sin_family = ADDR_FAMILY; local_addr.sin_port = 0; // Any local port will do - if(inet_pton(AF_INET, args.gtp_bind_addr.c_str(), &(local_addr.sin_addr)) != 1) { - s1ap_log->error("Error converting IP address (%s) to sockaddr_in structure\n", args.gtp_bind_addr.c_str()); + if(inet_pton(AF_INET, args.s1c_bind_addr.c_str(), &(local_addr.sin_addr)) != 1) { + s1ap_log->error("Error converting IP address (%s) to sockaddr_in structure\n", args.s1c_bind_addr.c_str()); return false; } bind(socket_fd, (struct sockaddr *)&local_addr, sizeof(local_addr)); From 2098aa073993aabe04dcfa6d7d2793c98746d4dc Mon Sep 17 00:00:00 2001 From: Merlin Chlosta Date: Mon, 9 Jul 2018 11:53:24 +0200 Subject: [PATCH 2/6] add keys to loglevel info to simplify PCAP analysis (#194) --- srsue/src/upper/nas.cc | 6 +++--- srsue/src/upper/pcsc_usim.cc | 2 +- srsue/src/upper/rrc.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 2e491b733..569ef7529 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -757,7 +757,7 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) { if (auth_result == AUTH_OK) { nas_log->info("Network authentication successful\n"); send_authentication_response(res, res_len); - nas_log->info("Generated k_asme=%s\n", hex_to_string(ctxt.k_asme, 32).c_str()); + nas_log->info_hex(ctxt.k_asme, 32, "Generated k_asme:\n"); } else if (auth_result == AUTH_SYNCH_FAILURE) { nas_log->error("Network authentication synchronization failure.\n"); send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res); @@ -878,8 +878,8 @@ void nas::parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu) // Generate NAS keys usim->generate_nas_keys(ctxt.k_asme, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); - nas_log->debug_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); - nas_log->debug_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); + nas_log->info_hex(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + nas_log->info_hex(k_nas_int, 32, "NAS integrity key - k_nas_int"); nas_log->debug("Generating integrity check. integ_algo:%d, count_dl:%d, lcid:%d\n", ctxt.integ_algo, ctxt.rx_count, lcid); diff --git a/srsue/src/upper/pcsc_usim.cc b/srsue/src/upper/pcsc_usim.cc index d94bebe1a..0d423c73c 100644 --- a/srsue/src/upper/pcsc_usim.cc +++ b/srsue/src/upper/pcsc_usim.cc @@ -250,7 +250,7 @@ auth_result_t pcsc_usim::generate_authentication_response(uint8_t *rand, mcc, mnc, k_asme); - log->debug_hex(k_asme, KEY_LEN, "K_ASME:\n"); + log->info_hex(k_asme, KEY_LEN, "K_ASME:\n"); ret = AUTH_OK; diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 66a7de33e..21d0b7833 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -2036,9 +2036,9 @@ void rrc::parse_dl_dcch(uint32_t lcid, byte_buffer_t *pdu) { uint8_t k_asme[32]; nas->get_k_asme(k_asme, 32); usim->generate_as_keys(k_asme, nas->get_ul_count(), 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"); + rrc_log->info_hex(k_rrc_enc, 32, "RRC encryption key - k_rrc_enc"); + rrc_log->info_hex(k_rrc_int, 32, "RRC integrity key - k_rrc_int"); + rrc_log->info_hex(k_up_enc, 32, "UP encryption key - k_up_enc"); security_is_activated = true; From 9b894799f047370d5d64e5cc766799fdc7b1a770 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 29 Jun 2018 10:40:33 +0200 Subject: [PATCH 3/6] add support for ciphered authentication response --- lib/include/srslte/asn1/liblte_mme.h | 2 ++ lib/src/asn1/liblte_mme.cc | 17 ++++++++++++++++ srsue/hdr/upper/nas.h | 4 ++-- srsue/src/upper/nas.cc | 29 +++++++++++++++++++--------- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/lib/include/srslte/asn1/liblte_mme.h b/lib/include/srslte/asn1/liblte_mme.h index 3d9640806..144c188fc 100644 --- a/lib/include/srslte/asn1/liblte_mme.h +++ b/lib/include/srslte/asn1/liblte_mme.h @@ -2814,6 +2814,8 @@ typedef struct{ }LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT; // Functions LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp, + uint8 sec_hdr_type, + uint32 count, LIBLTE_BYTE_MSG_STRUCT *msg); LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_response_msg(LIBLTE_BYTE_MSG_STRUCT *msg, LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp); diff --git a/lib/src/asn1/liblte_mme.cc b/lib/src/asn1/liblte_mme.cc index 189f9138a..5cb00e5cb 100644 --- a/lib/src/asn1/liblte_mme.cc +++ b/lib/src/asn1/liblte_mme.cc @@ -6180,6 +6180,8 @@ LIBLTE_ERROR_ENUM liblte_mme_unpack_authentication_request_msg(LIBLTE_BYTE_MSG_S Document Reference: 24.301 v10.2.0 Section 8.2.8 *********************************************************************/ LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp, + uint8 sec_hdr_type, + uint32 count, LIBLTE_BYTE_MSG_STRUCT *msg) { LIBLTE_ERROR_ENUM err = LIBLTE_ERROR_INVALID_INPUTS; @@ -6188,6 +6190,21 @@ LIBLTE_ERROR_ENUM liblte_mme_pack_authentication_response_msg(LIBLTE_MME_AUTHENT if(auth_resp != NULL && msg != NULL) { + + if(LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS != sec_hdr_type) + { + // Protocol Discriminator and Security Header Type + *msg_ptr = (sec_hdr_type << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); + msg_ptr++; + + // MAC will be filled in later + msg_ptr += 4; + + // Sequence Number + *msg_ptr = count & 0xFF; + msg_ptr++; + } + // Protocol Discriminator and Security Header Type *msg_ptr = (LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS << 4) | (LIBLTE_MME_PD_EPS_MOBILITY_MANAGEMENT); msg_ptr++; diff --git a/srsue/hdr/upper/nas.h b/srsue/hdr/upper/nas.h index 85c7a2f8e..32f6898f9 100644 --- a/srsue/hdr/upper/nas.h +++ b/srsue/hdr/upper/nas.h @@ -166,7 +166,7 @@ private: // Parsers void parse_attach_accept(uint32_t lcid, byte_buffer_t *pdu); void parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu); - void parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu); + void parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const uint8_t sec_hdr_type); void parse_authentication_reject(uint32_t lcid, byte_buffer_t *pdu); void parse_identity_request(uint32_t lcid, byte_buffer_t *pdu); void parse_security_mode_command(uint32_t lcid, byte_buffer_t *pdu); @@ -182,7 +182,7 @@ private: void send_identity_response(); void send_service_request(); void send_esm_information_response(const uint8 proc_transaction_id); - void send_authentication_response(const uint8_t* res, const size_t res_len); + void send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type); void send_authentication_failure(const uint8_t cause, const uint8_t* auth_fail_param); void gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT *msg); void send_security_mode_reject(uint8_t cause); diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 2e491b733..712e43103 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -331,7 +331,7 @@ void nas::write_pdu(uint32_t lcid, byte_buffer_t *pdu) { parse_attach_reject(lcid, pdu); break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: - parse_authentication_request(lcid, pdu); + parse_authentication_request(lcid, pdu, sec_hdr_type); break; case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: parse_authentication_reject(lcid, pdu); @@ -722,7 +722,7 @@ void nas::parse_attach_reject(uint32_t lcid, byte_buffer_t *pdu) { // FIXME: Command RRC to release? } -void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) { +void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu, const uint8_t sec_hdr_type) { LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req; bzero(&auth_req, sizeof(LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT)); @@ -756,7 +756,7 @@ void nas::parse_authentication_request(uint32_t lcid, byte_buffer_t *pdu) { if (auth_result == AUTH_OK) { nas_log->info("Network authentication successful\n"); - send_authentication_response(res, res_len); + send_authentication_response(res, res_len, sec_hdr_type); nas_log->info("Generated k_asme=%s\n", hex_to_string(ctxt.k_asme, 32).c_str()); } else if (auth_result == AUTH_SYNCH_FAILURE) { nas_log->error("Network authentication synchronization failure.\n"); @@ -1129,9 +1129,9 @@ void nas::send_security_mode_reject(uint8_t cause) { } -void nas::send_authentication_response(const uint8_t* res, const size_t res_len) { - byte_buffer_t *msg = pool_allocate; - if (!msg) { +void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) { + byte_buffer_t *pdu = pool_allocate; + if (!pdu) { nas_log->error("Fatal Error: Couldn't allocate PDU in send_authentication_response().\n"); return; } @@ -1143,13 +1143,24 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len) auth_res.res[i] = res[i]; } auth_res.res_len = res_len; - liblte_mme_pack_authentication_response_msg(&auth_res, (LIBLTE_BYTE_MSG_STRUCT *)msg); + liblte_mme_pack_authentication_response_msg(&auth_res, sec_hdr_type, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT *)pdu); if(pcap != NULL) { - pcap->write_nas(msg->msg, msg->N_bytes); + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED && pdu->N_bytes > 5) { + cipher_encrypt(pdu); + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[5], + pdu->N_bytes - 5, + &pdu->msg[1]); } + nas_log->info("Sending Authentication Response\n"); - rrc->write_sdu(cfg.lcid, msg); + rrc->write_sdu(cfg.lcid, pdu); } From bd5c1fd83a8e77e3c04fc3dc00a2cab544c312e4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 10 Jul 2018 19:52:46 +0200 Subject: [PATCH 4/6] deallocate dedicatedInfoNAS in rrc --- lib/include/srslte/common/buffer_pool.h | 2 +- srsue/src/upper/nas.cc | 1 - srsue/src/upper/rrc.cc | 6 ++++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/include/srslte/common/buffer_pool.h b/lib/include/srslte/common/buffer_pool.h index 75c56fc0e..0a87c0df1 100644 --- a/lib/include/srslte/common/buffer_pool.h +++ b/lib/include/srslte/common/buffer_pool.h @@ -183,7 +183,7 @@ public: } b->reset(); if (!pool->deallocate(b)) { - fprintf(stderr, "Error deallocating PDU: Addr=0x%lx not found in pool\n", (uint64_t) b); + printf("Error deallocating PDU: Addr=0x%lx not found in pool\n", (uint64_t) b); } b = NULL; } diff --git a/srsue/src/upper/nas.cc b/srsue/src/upper/nas.cc index 569ef7529..8672eb062 100644 --- a/srsue/src/upper/nas.cc +++ b/srsue/src/upper/nas.cc @@ -250,7 +250,6 @@ bool nas::rrc_connect() { } } else { nas_log->error("Could not establish RRC connection\n"); - pool->deallocate(dedicatedInfoNAS); } return false; } diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index 21d0b7833..440b4a318 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -526,6 +526,12 @@ bool rrc::connection_request(LIBLTE_RRC_CON_REQ_EST_CAUSE_ENUM cause, } } + if (!ret) { + rrc_log->warning("Could not estblish connection. Deallocating dedicatedInfoNAS PDU\n"); + pool->deallocate(this->dedicatedInfoNAS); + this->dedicatedInfoNAS = NULL; + } + pthread_mutex_unlock(&mutex); return ret; } From 7d324306b3652456649c5a279239e13959447193 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 7 Jul 2018 11:43:40 +0200 Subject: [PATCH 5/6] Default RLC to UM --- srsepc/user_db.csv.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/user_db.csv.example b/srsepc/user_db.csv.example index 77ab1e7a8..54d61eb30 100644 --- a/srsepc/user_db.csv.example +++ b/srsepc/user_db.csv.example @@ -12,5 +12,5 @@ # QCI: QoS Class Identifier for the UE's default bearer. # # Note: Lines starting by '#' are ignored and will be overwritten -ue1,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,9 +ue1,001010123456789,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,9001,000000001234,7 ue2,001010123456780,00112233445566778899aabbccddeeff,opc,63bfa50ee6523365ff14c1f45f88737d,8000,000000001234,7 From 9c5b9cef94c6720e44edff4cc96e97ec6fe126b8 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Sat, 7 Jul 2018 12:43:50 +0200 Subject: [PATCH 6/6] Set initial AGC gain correctly --- lib/src/phy/rf/rf_uhd_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index dc1bf6415..7fe291497 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -583,7 +583,7 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels) uhd_tx_metadata_make(&handler->tx_md, false, 0, 0, false, false); // Set starting gain to half maximum in case of using AGC - rf_uhd_set_rx_gain(handler, handler->info.max_tx_gain*0.7); + rf_uhd_set_rx_gain(handler, handler->info.max_rx_gain*0.7); #if HAVE_ASYNC_THREAD if (start_async_thread) {