diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f12ef109fb..391f8d7ffe 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2459,6 +2459,8 @@ if(ITTI_SIM) ${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c ${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c ${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c + ${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c + ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c ) set(libnrnas_ies_OBJS diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index a07111d8c2..9036867570 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2341,6 +2341,18 @@ nr_rrc_ue_decode_dcch( itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(RegistrationComplete)\n"); } + as_nas_info_t pduEstablishMsg; + memset(&pduEstablishMsg, 0, sizeof(as_nas_info_t)); + generatePduSessionEstablishRequest(&pduEstablishMsg); + if(initialNasMsg.length > 0){ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_NRUE, NAS_UPLINK_DATA_REQ); + NAS_UPLINK_DATA_REQ(message_p).UEid = ctxt_pP->module_id; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.data = (uint8_t *)pduEstablishMsg.data; + NAS_UPLINK_DATA_REQ(message_p).nasMsg.length = pduEstablishMsg.length; + itti_send_msg_to_task(TASK_RRC_NRUE, ctxt_pP->instance, message_p); + LOG_I(NR_RRC, " Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); + } #endif } break; diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c new file mode 100644 index 0000000000..55c30d24c7 --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.c @@ -0,0 +1,129 @@ +/*! \file FGSUplinkNasTransport.c + +\brief uplink nas transport procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include +#include + +#include "FGSUplinkNasTransport.h" +#include "TLVEncoder.h" + +int encode_fgs_payload_container(FGSPayloadContainer *paycontainer, uint8_t iei, uint8_t *buffer, uint32_t len) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + encoded += 2; + + if ((encode_result = encode_octet_string(&paycontainer->payloadcontainercontents, buffer + encoded, len - encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + if(iei > 0){ + *(uint16_t*) (buffer+1) = htons(encoded - 3); + } else { + *(uint16_t*) (buffer) = htons(encoded - 2); + } + + return encoded; +} + +int encode_nssai(OctetString *nssai, uint8_t iei, uint8_t *buffer) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + *(buffer + encoded) = nssai->length; + encoded++; + + + if ((encode_result = encode_octet_string(nssai, buffer + encoded, nssai->length)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + +int encode_dnn(OctetString *dnn, uint8_t iei, uint8_t *buffer) +{ + uint32_t encoded = 0; + int encode_result; + + if (iei > 0) { + *buffer = iei; + encoded++; + } + + *(buffer + encoded) = dnn->length; + encoded++; + + if ((encode_result = encode_octet_string(dnn, buffer + encoded, dnn->length)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + +int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_up_nas_transport, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + *(buffer + encoded) = (fgs_up_nas_transport->payloadcontainertype.iei << 4) | (fgs_up_nas_transport->payloadcontainertype.type &0xf); + encoded++; + + if ((encode_result = encode_fgs_payload_container(&fgs_up_nas_transport->fgspayloadcontainer, + 0, buffer +encoded, len - encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + *(buffer + encoded) = 0x12; + encoded++; + + IES_ENCODE_U8(buffer, encoded, fgs_up_nas_transport->pdusessionid); + + // set request type + *(buffer + encoded) = (0x8<<4)|(fgs_up_nas_transport->requesttype &0x7); + encoded++; + + if ((encode_result = encode_nssai(&fgs_up_nas_transport->snssai, 0x22, buffer +encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + if ((encode_result = encode_dnn(&fgs_up_nas_transport->dnn, 0x25, buffer +encoded)) < 0) { + return encode_result; + } else { + encoded += encode_result; + } + + return encoded; +} + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h new file mode 100644 index 0000000000..f0debd79eb --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSUplinkNasTransport.h @@ -0,0 +1,56 @@ +/*! \file FGSUplinkNasTransport.h + +\brief uplink nas transport procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "MessageType.h" + +#ifndef FGS_UPLINK_NAS_TRANSPORT_H_ +#define FGS_UPLINK_NAS_TRANSPORT_H_ + +/* + * Message name: uplink nas transpaort + * Description: The UL NAS TRANSPORT message transports message payload and associated information to the AMF. See table 8.2.10.1.1. + * Significance: dual + * Direction: UE to network + */ + +typedef struct PayloadContainerType_tag{ + uint8_t iei:4; + uint8_t type:4; +}PayloadContainerType; +typedef struct FGSPayloadContainer_tag { + OctetString payloadcontainercontents; +} FGSPayloadContainer; + +typedef struct fgs_uplink_nas_transport_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + PayloadContainerType payloadcontainertype; + FGSPayloadContainer fgspayloadcontainer; + /* Optional fields */ + uint16_t pdusessionid; + uint8_t requesttype; + OctetString snssai; + OctetString dnn; +} fgs_uplink_nas_transport_msg; + +int encode_fgs_uplink_nas_transport(fgs_uplink_nas_transport_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_UPLINK_NAS_TRANSPORT_H_) */ + + diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c new file mode 100644 index 0000000000..369d6b83aa --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.c @@ -0,0 +1,40 @@ +/*! \file PduSessionEstablishRequest.c + +\brief pdu session establishment request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + + +#include "TLVEncoder.h" +#include "TLVDecoder.h" +#include "PduSessionEstablishRequest.h" + + +int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer) +{ + int encoded = 0; + + + *(buffer + encoded) = pdusessionestablishrequest->protocoldiscriminator; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pdusessionid; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pti; + encoded++; + *(buffer + encoded) = pdusessionestablishrequest->pdusessionestblishmsgtype; + encoded++; + + IES_ENCODE_U16(buffer, encoded, pdusessionestablishrequest->maxdatarate); + + return encoded; +} + + diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h new file mode 100644 index 0000000000..6626e35cc6 --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishRequest.h @@ -0,0 +1,43 @@ +/*! \file PduSessionEstablishRequest.h + +\brief pdu session establishment request procedures +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "MessageType.h" + +#ifndef PDU_SESSION_ESTABLISHMENT_REQUEST_H_ +#define PDU_SESSION_ESTABLISHMENT_REQUEST_H_ + + +/* + * Message name: pdu session establishment request + * Description: The PDU SESSION ESTABLISHMENT REQUEST message is sent by the UE to the SMF to initiate establishment of a PDU session. See table 8.3.1.1.1. + * Significance: dual + * Direction: UE to network + */ + +typedef struct pdu_session_establishment_request_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + uint8_t pdusessionid; + uint8_t pti; + MessageType pdusessionestblishmsgtype; + uint16_t maxdatarate; + /* Optional fields */ +} pdu_session_establishment_request_msg; + + +int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer); + +#endif /* ! defined(PDU_SESSION_ESTABLISHMENT_REQUEST_H_) */ + + diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 81edd0ccb8..e0d3ddff72 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -17,6 +17,7 @@ #include "nr_nas_msg_sim.h" #include "aka_functions.h" #include "secu_defs.h" +#include "PduSessionEstablishRequest.h" char netName[] = "5G:mnc093.mcc208.3gppnetwork.org"; char imsi[] = "2089300007487"; // USIM_API_K: 5122250214c33e723a5dd523fc145fc0 @@ -108,6 +109,9 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { case FGS_SECURITY_MODE_COMPLETE: encode_result = encode_fgs_security_mode_complete(&mm_msg->fgs_security_mode_complete, buffer, len); break; + case FGS_UPLINK_NAS_TRANSPORT: + encode_result = encode_fgs_uplink_nas_transport(&mm_msg->uplink_nas_transport, buffer, len); + break; default: LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", mm_msg->header.message_type); @@ -577,3 +581,88 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo initialNasMsg->data[2+i] = mac[i]; } } + +void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){ + int size = 0; + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + + // setup pdu session establishment request + uint16_t req_length = 6; + uint8_t *req_buffer = malloc(req_length); + pdu_session_establishment_request_msg pdu_session_establish; + pdu_session_establish.protocoldiscriminator = FGS_SESSION_MANAGEMENT_MESSAGE; + pdu_session_establish.pdusessionid = 10; + pdu_session_establish.pti = 0; + pdu_session_establish.pdusessionestblishmsgtype = FGS_PDU_SESSION_ESTABLISHMENT_REQ; + pdu_session_establish.maxdatarate = 0xffff; + encode_pdu_session_establishment_request(&pdu_session_establish, req_buffer); + + + + MM_msg *mm_msg; + nas_stream_cipher_t stream_cipher; + uint8_t mac[4]; + uint8_t nssai[]={1,1,2,3}; + uint8_t dnn[9]={0x8,0x69,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74}; + // set security protected header + nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX; + size += 7; + + mm_msg = &nas_msg.security_protected.plain.mm_msg; + + // set header + mm_msg->header.ex_protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + mm_msg->header.security_header_type = PLAIN_5GS_MSG; + mm_msg->header.message_type = FGS_UPLINK_NAS_TRANSPORT; + + // set uplink nas transport + mm_msg->uplink_nas_transport.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->uplink_nas_transport.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->uplink_nas_transport.messagetype = FGS_UPLINK_NAS_TRANSPORT; + size += 1; + + mm_msg->uplink_nas_transport.payloadcontainertype.iei = 0; + mm_msg->uplink_nas_transport.payloadcontainertype.type = 1; + size += 1; + mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.length = req_length; + mm_msg->uplink_nas_transport.fgspayloadcontainer.payloadcontainercontents.value = req_buffer; + size += (2+req_length); + mm_msg->uplink_nas_transport.pdusessionid = 10; + mm_msg->uplink_nas_transport.requesttype = 1; + size += 3; + mm_msg->uplink_nas_transport.snssai.length = 4; + mm_msg->uplink_nas_transport.snssai.value = nssai; + size += (1+1+4); + mm_msg->uplink_nas_transport.dnn.length = 9; + mm_msg->uplink_nas_transport.dnn.value = dnn; + size += (1+1+9); + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); + + initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); + + stream_cipher.key = knas_int.value; + stream_cipher.key_length = 16; + stream_cipher.count = 0; + stream_cipher.bearer = 1; + stream_cipher.direction = 0; + stream_cipher.message = (unsigned char *)(initialNasMsg->data + 6); + /* length in bits */ + stream_cipher.blength = (initialNasMsg->length - 6) << 3; + + // only for Type of integrity protection algorithm: 128-5G-IA2 (2) + nas_stream_encrypt_eia2( + &stream_cipher, + mac); + + printf("mac %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]); + for(int i = 0; i < 4; i++){ + initialNasMsg->data[2+i] = mac[i]; + } +} diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 73a23b7167..18ae059d3e 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -17,7 +17,7 @@ #include "FGSNASSecurityModeComplete.h" #include "RegistrationComplete.h" #include "as_message.h" - +#include "FGSUplinkNasTransport.h" #define PLAIN_5GS_MSG 0b0000 #define INTEGRITY_PROTECTED 0b0001 @@ -34,6 +34,10 @@ #define FGS_IDENTITY_RESPONSE 0b01011100 /* 92 = 0x5c */ #define FGS_SECURITY_MODE_COMMAND 0b01011101 /* 93 = 0x5d */ #define FGS_SECURITY_MODE_COMPLETE 0b01011110 /* 94 = 0x5e */ +#define FGS_UPLINK_NAS_TRANSPORT 0b01100111 /* 103= 0x67 */ + +// message type for 5GS session management +#define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */ #define INITIAL_REGISTRATION 0b001 @@ -68,6 +72,7 @@ typedef union { fgs_authentication_response_msg fgs_auth_response; fgs_security_mode_complete_msg fgs_security_mode_complete; registration_complete_msg registration_complete; + fgs_uplink_nas_transport_msg uplink_nas_transport; } MM_msg; @@ -93,6 +98,7 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf); void generateSecurityModeComplete(as_nas_info_t *initialNasMsg); void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer); +void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg); #endif /* __NR_NAS_MSG_SIM_H__*/