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); }