From acc2948b454dce589b50219b0c26225b291ba993 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 1 Apr 2020 21:29:42 +0200 Subject: [PATCH] nas: fix security handling First of all, with this the NAS conformance tests pass with ciphering and integrity turned on. Before only integrity was working. Mainly the NAS was applying the integrity protection and/or ciphering incorrectly because it wasn't taking the secuirty status of the PDUs into account. Some where already correct, some not. The patch streamlines the handling for all outgoing messages. --- srsue/hdr/stack/upper/nas.h | 11 +- srsue/src/stack/upper/nas.cc | 214 +++++++++++++++++++---------------- 2 files changed, 124 insertions(+), 101 deletions(-) diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index f4f597308..771a2ec1c 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -120,6 +120,7 @@ private: bool have_ctxt = false; nas_sec_ctxt ctxt = {}; bool auth_request = false; + uint8_t current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS; const uint32_t max_attach_attempts = 5; // Sec. 5.5.1.2.6 uint32_t attach_attempt_counter = 0; @@ -171,7 +172,7 @@ private: bool integrity_check(srslte::byte_buffer_t* pdu); void cipher_encrypt(srslte::byte_buffer_t* pdu); void cipher_decrypt(srslte::byte_buffer_t* pdu); - int apply_security_config(srslte::unique_byte_buffer_t& pdu); + int apply_security_config(srslte::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); void reset_security_context(); void set_k_enb_count(uint32_t count); @@ -194,7 +195,7 @@ private: void parse_emm_status(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_deactivate_eps_bearer_context_request(srslte::unique_byte_buffer_t pdu); - void parse_activate_test_mode(uint32_t lcid, srslte::unique_byte_buffer_t pdu, const uint8_t sec_hdr_type); + void parse_activate_test_mode(uint32_t lcid, srslte::unique_byte_buffer_t pdu); void parse_modify_eps_bearer_context_request(srslte::unique_byte_buffer_t pdu); // Packet generators @@ -203,10 +204,10 @@ private: // Senders void send_attach_complete(const uint8_t& transaction_id, const uint8_t& eps_bearer_id); - void send_identity_response(uint8 id_type, const uint8_t sec_hdr_type); + void send_identity_response(uint8 id_type); 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, const uint8_t sec_hdr_type); + void send_authentication_response(const uint8_t* res, const size_t res_len); 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); @@ -217,7 +218,7 @@ private: const uint8_t& eps_bearer_id); void send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); void send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_id, const uint8_t& eps_bearer_id); - void send_activate_test_mode_complete(const uint8_t sec_hdr_type); + void send_activate_test_mode_complete(); // Other internal helpers void enter_state(emm_state_t state_); diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index a2f176c37..0f91c23ac 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -616,7 +616,37 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) // Parse the message header liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &pd, &msg_type); nas_log->info_hex(pdu->msg, pdu->N_bytes, "DL %s Decrypted PDU", rrc->get_rb_name(lcid).c_str()); - // TODO: Check if message type requieres specical security header type and if it isvalid + + // drop messages if integrity protection isn't applied (see TS 24.301 Sec. 4.4.4.2) + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS) { + switch (msg_type) { + case LIBLTE_MME_MSG_TYPE_IDENTITY_REQUEST: // special case for IMSI is checked in parse_identity_request() + case LIBLTE_MME_MSG_TYPE_EMM_INFORMATION: + case LIBLTE_MME_MSG_TYPE_EMM_STATUS: + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REQUEST: + case LIBLTE_MME_MSG_TYPE_AUTHENTICATION_REJECT: + case LIBLTE_MME_MSG_TYPE_ATTACH_REJECT: + case LIBLTE_MME_MSG_TYPE_DETACH_REQUEST: + case LIBLTE_MME_MSG_TYPE_DETACH_ACCEPT: + case LIBLTE_MME_MSG_TYPE_TRACKING_AREA_UPDATE_REJECT: + case LIBLTE_MME_MSG_TYPE_SERVICE_REJECT: + break; + default: + nas_log->error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X without integrity protection!\n", + msg_type, + sec_hdr_type); + return; + } + } + + // Reserved for Security Mode Command (Sec 9.3.1) + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_WITH_NEW_EPS_SECURITY_CONTEXT && + msg_type != LIBLTE_MME_MSG_TYPE_SECURITY_MODE_COMMAND) { + nas_log->error("Not handling NAS message MSG_TYPE=%02X with SEC_HDR_TYPE=%02X. Security header type reserved!\n", + msg_type, + sec_hdr_type); + return; + } switch (msg_type) { case LIBLTE_MME_MSG_TYPE_ATTACH_ACCEPT: @@ -662,7 +692,7 @@ void nas::write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) parse_modify_eps_bearer_context_request(std::move(pdu)); break; case LIBLTE_MME_MSG_TYPE_ACTIVATE_TEST_MODE: - parse_activate_test_mode(lcid, std::move(pdu), sec_hdr_type); + parse_activate_test_mode(lcid, std::move(pdu)); break; // TODO: Handle deactivate test mode and ue close/open case LIBLTE_MME_MSG_TYPE_DEACTIVATE_TEST_MODE: @@ -808,7 +838,13 @@ bool nas::integrity_check(byte_buffer_t* pdu) return false; } } - nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n", ctxt.rx_count, pdu->msg[5]); + nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d [%02x %02x %02x %02x]\n", + ctxt.rx_count, + pdu->msg[5], + mac[0], + mac[1], + mac[2], + mac[3]); // Updated local count (according to TS 24.301 Sec. 4.4.3.3) if (pdu->msg[5] != ctxt.rx_count) { @@ -921,20 +957,26 @@ bool nas::check_cap_replay(LIBLTE_MME_UE_SECURITY_CAPABILITIES_STRUCT* caps) /** * Applies the current security config on a packed NAS PDU * - * The PDU is ciphered and integrity protected if NAS security is configured - * and the current security context is valid. The function also performs - * a length check. + * The PDU is ciphered and integrity protected if NAS security is configured, + * the header type requires security protection and the current security context is valid. + * The function also performs a length check. * * @param pdu The NAS PDU already packed inside a byte_buffer - * @return True if successfull, false otherwise + * @param sec_hdr_type Security header type of the message + * @return True if successful, false otherwise */ -int nas::apply_security_config(srslte::unique_byte_buffer_t& pdu) +int nas::apply_security_config(srslte::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type) { if (have_ctxt) { if (pdu->N_bytes > 5) { - cipher_encrypt(pdu.get()); - integrity_generate( - &k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); + if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED || + sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT) { + cipher_encrypt(pdu.get()); + } + if (sec_hdr_type >= LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY) { + integrity_generate( + &k_nas_int[16], ctxt.tx_count, SECURITY_DIRECTION_UPLINK, &pdu->msg[5], pdu->N_bytes - 5, &pdu->msg[1]); + } } else { nas_log->error("Invalid PDU size %d\n", pdu->N_bytes); return SRSLTE_ERROR; @@ -952,6 +994,7 @@ void nas::reset_security_context() { have_guti = false; have_ctxt = false; + current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS; ctxt = {}; ctxt.ksi = LIBLTE_MME_NAS_KEY_SET_IDENTIFIER_NO_KEY_AVAILABLE; } @@ -1252,8 +1295,7 @@ void nas::parse_attach_reject(uint32_t lcid, unique_byte_buffer_t pdu) void nas::parse_authentication_request(uint32_t lcid, unique_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)); + LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req = {}; nas_log->info("Received Authentication Request\n"); liblte_mme_unpack_authentication_request_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &auth_req); @@ -1282,7 +1324,10 @@ void nas::parse_authentication_request(uint32_t lcid, unique_byte_buffer_t pdu, if (auth_result == AUTH_OK) { nas_log->info("Network authentication successful\n"); - send_authentication_response(res, res_len, sec_hdr_type); + // MME wants to re-establish security context, use provided protection level until security (re-)activation + current_sec_hdr = sec_hdr_type; + + send_authentication_response(res, res_len); nas_log->info_hex(ctxt.k_asme, 32, "Generated k_asme:\n"); set_k_enb_count(0); auth_request = true; @@ -1314,7 +1359,7 @@ void nas::parse_identity_request(unique_byte_buffer_t pdu, const uint8_t sec_hdr // do not respond if request is not protected (TS 24.301 Sec. 4.4.4.2) if (sec_hdr_type >= LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY || (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS && id_req.id_type == LIBLTE_MME_MOBILE_ID_TYPE_IMSI)) { - send_identity_response(id_req.id_type, sec_hdr_type); + send_identity_response(id_req.id_type); } else { nas_log->info("Not sending identity response due to missing integrity protection.\n"); } @@ -1332,11 +1377,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) return; } - LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd; - bzero(&sec_mode_cmd, sizeof(LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT)); - LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp; - bzero(&sec_mode_comp, sizeof(LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT)); - + LIBLTE_MME_SECURITY_MODE_COMMAND_MSG_STRUCT sec_mode_cmd = {}; liblte_mme_unpack_security_mode_command_msg((LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), &sec_mode_cmd); nas_log->info("Received Security Mode Command ksi: %d, eea: %s, eia: %s\n", sec_mode_cmd.nas_ksi.nas_ksi, @@ -1400,9 +1441,7 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) ctxt.rx_count++; - // Take security context into use - have_ctxt = true; - + LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sec_mode_comp = {}; if (sec_mode_cmd.imeisv_req_present && LIBLTE_MME_IMEISV_REQUESTED == sec_mode_cmd.imeisv_req) { sec_mode_comp.imeisv_present = true; sec_mode_comp.imeisv.type_of_id = LIBLTE_MME_MOBILE_ID_TYPE_IMEISV; @@ -1413,18 +1452,19 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) sec_mode_comp.imeisv_present = false; } - // Send response + // Take security context into use and use new security header + have_ctxt = true; + current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT; + + // Pack and send response pdu->clear(); liblte_mme_pack_security_mode_complete_msg( - &sec_mode_comp, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &sec_mode_comp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -1434,6 +1474,9 @@ void nas::parse_security_mode_command(uint32_t lcid, unique_byte_buffer_t pdu) rrc->get_rb_name(lcid).c_str()); rrc->write_sdu(std::move(pdu)); ctxt.tx_count++; + + // switch security header for all following messages + current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED; } void nas::parse_service_reject(uint32_t lcid, unique_byte_buffer_t pdu) @@ -1621,13 +1664,13 @@ void nas::parse_modify_eps_bearer_context_request(srslte::unique_byte_buffer_t p send_modify_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); } -void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu, const uint8_t sec_hdr_type) +void nas::parse_activate_test_mode(uint32_t lcid, unique_byte_buffer_t pdu) { nas_log->info("Received Activate test mode\n"); ctxt.rx_count++; - send_activate_test_mode_complete(sec_hdr_type); + send_activate_test_mode_complete(); } void nas::parse_emm_status(uint32_t lcid, unique_byte_buffer_t pdu) @@ -1722,7 +1765,7 @@ void nas::gen_attach_request(srslte::unique_byte_buffer_t& msg) liblte_mme_pack_attach_request_msg( &attach_req, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)msg.get()); - if (apply_security_config(msg)) { + if (apply_security_config(msg, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -1793,8 +1836,7 @@ void nas::gen_service_request(srslte::unique_byte_buffer_t& msg) void nas::gen_pdn_connectivity_request(LIBLTE_BYTE_MSG_STRUCT* msg) { - LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req; - ZERO_OBJECT(pdn_con_req); + LIBLTE_MME_PDN_CONNECTIVITY_REQUEST_MSG_STRUCT pdn_con_req = {}; nas_log->info("Generating PDN Connectivity Request\n"); @@ -1876,8 +1918,7 @@ void nas::send_detach_request(bool switch_off) return; } - LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request; - bzero(&detach_request, sizeof(detach_request)); + LIBLTE_MME_DETACH_REQUEST_MSG_STRUCT detach_request = {}; if (switch_off) { detach_request.detach_type.switch_off = 1; detach_request.detach_type.type_of_detach = LIBLTE_MME_SO_FLAG_SWITCH_OFF; @@ -1892,18 +1933,15 @@ void nas::send_detach_request(bool switch_off) memcpy(&detach_request.eps_mobile_id.guti, &ctxt.guti, sizeof(LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT)); detach_request.nas_ksi.tsc_flag = LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE; detach_request.nas_ksi.nas_ksi = ctxt.ksi; - nas_log->info("Sending detach request with GUTI\n"); // If sent as an Initial UE message, it cannot be chiphered - liblte_mme_pack_detach_request_msg(&detach_request, - rrc->is_connected() ? LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED - : LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + nas_log->info("Sending detach request with GUTI\n"); // If sent as an Initial UE message, it cannot be ciphered + liblte_mme_pack_detach_request_msg( + &detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -1914,7 +1952,7 @@ void nas::send_detach_request(bool switch_off) usim->get_imsi_vec(detach_request.eps_mobile_id.imsi, 15); nas_log->info("Sending detach request with IMSI\n"); liblte_mme_pack_detach_request_msg( - &detach_request, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &detach_request, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); @@ -1957,16 +1995,14 @@ void nas::send_attach_complete(const uint8_t& transaction_id_, const uint8_t& ep // Pack entire message unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); - liblte_mme_pack_attach_complete_msg(&attach_complete, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_attach_complete_msg( + &attach_complete, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); // Write NAS pcap if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -1989,16 +2025,13 @@ void nas::send_detach_accept() LIBLTE_MME_DETACH_ACCEPT_MSG_STRUCT detach_accept; bzero(&detach_accept, sizeof(detach_accept)); - liblte_mme_pack_detach_accept_msg(&detach_accept, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_detach_accept_msg(&detach_accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2007,7 +2040,7 @@ void nas::send_detach_accept() rrc->write_sdu(std::move(pdu)); } -void nas::send_authentication_response(const uint8_t* res, const size_t res_len, const uint8_t sec_hdr_type) +void nas::send_authentication_response(const uint8_t* res, const size_t res_len) { unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); if (!pdu) { @@ -2015,25 +2048,22 @@ void nas::send_authentication_response(const uint8_t* res, const size_t res_len, return; } - LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res; - bzero(&auth_res, sizeof(LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT)); + LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT auth_res = {}; for (uint32_t i = 0; i < res_len; i++) { auth_res.res[i] = res[i]; } auth_res.res_len = res_len; liblte_mme_pack_authentication_response_msg( - &auth_res, sec_hdr_type, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + &auth_res, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); if (pcap != nullptr) { pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) { - if (apply_security_config(pdu)) { - nas_log->error("Error applying NAS security.\n"); - return; - } + if (apply_security_config(pdu, current_sec_hdr)) { + nas_log->error("Error applying NAS security.\n"); + return; } nas_log->info("Sending Authentication Response\n"); @@ -2067,7 +2097,7 @@ void nas::send_authentication_failure(const uint8_t cause, const uint8_t* auth_f rrc->write_sdu(std::move(msg)); } -void nas::send_identity_response(const uint8 id_type, const uint8_t sec_hdr_type) +void nas::send_identity_response(const uint8 id_type) { LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp = {}; @@ -2097,14 +2127,12 @@ void nas::send_identity_response(const uint8 id_type, const uint8_t sec_hdr_type return; } - liblte_mme_pack_identity_response_msg(&id_resp, sec_hdr_type, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); + liblte_mme_pack_identity_response_msg(&id_resp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()); // add security if needed - if (sec_hdr_type == LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED) { - if (apply_security_config(pdu)) { - nas_log->error("Error applying NAS security.\n"); - return; - } + if (apply_security_config(pdu, current_sec_hdr)) { + nas_log->error("Error applying NAS security.\n"); + return; } if (pcap != nullptr) { @@ -2244,10 +2272,8 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) return; } - if (liblte_mme_pack_esm_information_response_msg(&esm_info_resp, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + if (liblte_mme_pack_esm_information_response_msg( + &esm_info_resp, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { nas_log->error("Error packing ESM information response.\n"); return; } @@ -2256,7 +2282,7 @@ void nas::send_esm_information_response(const uint8 proc_transaction_id) pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2279,10 +2305,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ accept.proc_transaction_id = proc_transaction_id; if (liblte_mme_pack_activate_dedicated_eps_bearer_context_accept_msg( - &accept, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { nas_log->error("Error packing Activate Dedicated EPS Bearer context accept.\n"); return; } @@ -2291,7 +2314,7 @@ void nas::send_activate_dedicated_eps_bearer_context_accept(const uint8_t& proc_ pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2315,11 +2338,9 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact accept.eps_bearer_id = eps_bearer_id; accept.proc_transaction_id = proc_transaction_id; - if (liblte_mme_pack_deactivate_eps_bearer_context_accept_msg(&accept, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { - nas_log->error("Error packing Aeactivate EPS Bearer context accept.\n"); + if (liblte_mme_pack_deactivate_eps_bearer_context_accept_msg( + &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + nas_log->error("Error packing Activate EPS Bearer context accept.\n"); return; } @@ -2327,7 +2348,7 @@ void nas::send_deactivate_eps_bearer_context_accept(const uint8_t& proc_transact pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2351,10 +2372,8 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ accept.eps_bearer_id = eps_bearer_id; accept.proc_transaction_id = proc_transaction_id; - if (liblte_mme_pack_modify_eps_bearer_context_accept_msg(&accept, - LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED, - ctxt.tx_count, - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { + if (liblte_mme_pack_modify_eps_bearer_context_accept_msg( + &accept, current_sec_hdr, ctxt.tx_count, (LIBLTE_BYTE_MSG_STRUCT*)pdu.get()) != LIBLTE_SUCCESS) { nas_log->error("Error packing Modify EPS Bearer context accept.\n"); return; } @@ -2363,7 +2382,7 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2378,12 +2397,12 @@ void nas::send_modify_eps_bearer_context_accept(const uint8_t& proc_transaction_ ctxt.tx_count++; } -void nas::send_activate_test_mode_complete(const uint8_t sec_hdr_type) +void nas::send_activate_test_mode_complete() { unique_byte_buffer_t pdu = srslte::allocate_unique_buffer(*pool, true); if (liblte_mme_pack_activate_test_mode_complete_msg( - (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), sec_hdr_type, ctxt.tx_count)) { + (LIBLTE_BYTE_MSG_STRUCT*)pdu.get(), current_sec_hdr, ctxt.tx_count)) { nas_log->error("Error packing activate test mode complete.\n"); return; } @@ -2392,7 +2411,7 @@ void nas::send_activate_test_mode_complete(const uint8_t sec_hdr_type) pcap->write_nas(pdu->msg, pdu->N_bytes); } - if (apply_security_config(pdu)) { + if (apply_security_config(pdu, current_sec_hdr)) { nas_log->error("Error applying NAS security.\n"); return; } @@ -2491,7 +2510,6 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) } file.close(); - have_guti = true; nas_log->info("Read GUTI from file " "m_tmsi: %x, mcc: %x, mnc: %x, mme_group_id: %x, mme_code: %x\n", ctxt_->guti.m_tmsi, @@ -2499,7 +2517,6 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) ctxt_->guti.mnc, ctxt_->guti.mme_group_id, ctxt_->guti.mme_code); - have_ctxt = true; nas_log->info("Read security ctxt from file .ctxt. " "ksi: %x, k_asme: %s, tx_count: %x, rx_count: %x, int_alg: %d, enc_alg: %d\n", ctxt_->ksi, @@ -2508,6 +2525,11 @@ bool nas::read_ctxt_file(nas_sec_ctxt* ctxt_) ctxt_->rx_count, ctxt_->integ_algo, ctxt_->cipher_algo); + + have_guti = true; + have_ctxt = true; + current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED; + return true; } return false;