Commit 65d86435 authored by Chenyu's avatar Chenyu

session establishment request to upf ,but no response

parent 8dc01636
...@@ -2511,7 +2511,7 @@ if(NAS_UE) ...@@ -2511,7 +2511,7 @@ if(NAS_UE)
endif() endif()
if(ITTI_SIM) #if(ITTI_SIM)
set(libnas_ue_api_OBJS set(libnas_ue_api_OBJS
${NAS_SRC}UE/API/USER/at_command.c ${NAS_SRC}UE/API/USER/at_command.c
${NAS_SRC}UE/API/USER/at_error.c ${NAS_SRC}UE/API/USER/at_error.c
...@@ -2585,6 +2585,13 @@ if(ITTI_SIM) ...@@ -2585,6 +2585,13 @@ if(ITTI_SIM)
set(libnrnas_emm_msg_OBJS set(libnrnas_emm_msg_OBJS
${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c ${NAS_SRC}COMMON/EMM/MSG/RegistrationRequest.c
${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
${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 set(libnrnas_ies_OBJS
...@@ -2592,8 +2599,11 @@ if(ITTI_SIM) ...@@ -2592,8 +2599,11 @@ if(ITTI_SIM)
${NAS_SRC}COMMON/IES/FGSMobileIdentity.c ${NAS_SRC}COMMON/IES/FGSMobileIdentity.c
${NAS_SRC}COMMON/IES/FGSRegistrationType.c ${NAS_SRC}COMMON/IES/FGSRegistrationType.c
${NAS_SRC}COMMON/IES/SpareHalfOctet.c ${NAS_SRC}COMMON/IES/SpareHalfOctet.c
${NAS_SRC}COMMON/IES/FGSRegistrationResult.c
${NAS_SRC}COMMON/IES/FGMMCapability.c ${NAS_SRC}COMMON/IES/FGMMCapability.c
${NAS_SRC}COMMON/IES/NrUESecurityCapability.c ${NAS_SRC}COMMON/IES/NrUESecurityCapability.c
${NAS_SRC}COMMON/IES/FGCNasMessageContainer.c
${NAS_SRC}COMMON/IES/SORTransparentContainer.c
) )
add_library(LIB_NAS_SIMUE add_library(LIB_NAS_SIMUE
...@@ -2627,7 +2637,7 @@ if(ITTI_SIM) ...@@ -2627,7 +2637,7 @@ if(ITTI_SIM)
include_directories(${NAS_SRC}UE/EMM/SAP) include_directories(${NAS_SRC}UE/EMM/SAP)
include_directories(${NAS_SRC}UE/ESM) include_directories(${NAS_SRC}UE/ESM)
include_directories(${NAS_SRC}UE/ESM/SAP) include_directories(${NAS_SRC}UE/ESM/SAP)
endif() #endif()
# nbiot # nbiot
add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16")
...@@ -3111,7 +3121,7 @@ target_link_libraries (nr-uesoftmodem ...@@ -3111,7 +3121,7 @@ target_link_libraries (nr-uesoftmodem
-Wl,--start-group -Wl,--start-group
RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB S1AP_LIB S1AP_ENB NFAPI_USER_LIB S1AP_LIB S1AP_ENB ${NAS_SIM_LIB}
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB
-Wl,--end-group z dl) -Wl,--end-group z dl)
......
...@@ -1248,9 +1248,9 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Trans ...@@ -1248,9 +1248,9 @@ uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Trans
memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t)); memset(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,0,sizeof(OCTET_STRING_t));
OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength); OCTET_STRING_fromBuf(&RrcSetupComplete->criticalExtensions.choice.rrcSetupComplete->dedicatedNAS_Message,dedicatedInfoNAS,dedicatedInfoNASLength);
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
} //}
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
NULL, NULL,
......
...@@ -800,7 +800,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( ...@@ -800,7 +800,7 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS(
/* Transfer data to PDCP */ /* Transfer data to PDCP */
nr_rrc_data_req ( nr_rrc_data_req (
&ctxt, &ctxt,
ue_context_p->ue_context.Srb2.Srb_info.Srb_id, DCCH,//ue_context_p->ue_context.Srb2.Srb_info.Srb_id,
(*rrc_gNB_mui)++, (*rrc_gNB_mui)++,
SDU_CONFIRM_NO, SDU_CONFIRM_NO,
length, length,
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
#include "RRC/NAS/rb_config.h" #include "RRC/NAS/rb_config.h"
#include "SIMULATION/TOOLS/sim.h" // for taus #include "SIMULATION/TOOLS/sim.h" // for taus
#if ITTI_SIM #if 1 //ITTI_SIM
#include "nr_nas_msg_sim.h" #include "nr_nas_msg_sim.h"
#endif #endif
...@@ -1365,6 +1365,10 @@ static void rrc_ue_generate_RRCSetupComplete( ...@@ -1365,6 +1365,10 @@ static void rrc_ue_generate_RRCSetupComplete(
nas_msg = nr_nas_attach_req_imsi; nas_msg = nr_nas_attach_req_imsi;
nas_msg_length = sizeof(nr_nas_attach_req_imsi); nas_msg_length = sizeof(nr_nas_attach_req_imsi);
} }
as_nas_info_t initialNasMsg;
generateRegistrationRequest(&initialNasMsg);
nas_msg = (char*)initialNasMsg.data;
nas_msg_length = initialNasMsg.length;
size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg); size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg);
LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
...@@ -2333,7 +2337,7 @@ nr_rrc_ue_decode_dcch( ...@@ -2333,7 +2337,7 @@ nr_rrc_ue_decode_dcch(
nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP, nr_rrc_ue_generate_RRCReconfigurationComplete(ctxt_pP,
gNB_indexP, gNB_indexP,
dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier); dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
#ifdef ITTI_SIM #if 1//def ITTI_SIM
as_nas_info_t initialNasMsg; as_nas_info_t initialNasMsg;
memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
generateRegistrationComplete(&initialNasMsg, NULL); generateRegistrationComplete(&initialNasMsg, NULL);
...@@ -2402,7 +2406,7 @@ nr_rrc_ue_decode_dcch( ...@@ -2402,7 +2406,7 @@ nr_rrc_ue_decode_dcch(
uint8_t *pdu_buffer; uint8_t *pdu_buffer;
pdu_length = dedicatedNAS_Message->size; pdu_length = dedicatedNAS_Message->size;
pdu_buffer = dedicatedNAS_Message->buf; pdu_buffer = dedicatedNAS_Message->buf;
#ifdef ITTI_SIM #if 1 //def ITTI_SIM
LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id, messages_info[NAS_DOWNLINK_DATA_IND].name, LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id, messages_info[NAS_DOWNLINK_DATA_IND].name,
ctxt_pP->module_id, pdu_length, pdu_buffer); ctxt_pP->module_id, pdu_length, pdu_buffer);
as_nas_info_t initialNasMsg; as_nas_info_t initialNasMsg;
...@@ -2590,7 +2594,7 @@ void *rrc_nrue_task( void *args_p ) { ...@@ -2590,7 +2594,7 @@ void *rrc_nrue_task( void *args_p ) {
PDCP_TRANSMISSION_MODE_CONTROL); PDCP_TRANSMISSION_MODE_CONTROL);
} else { } else {
rrc_data_req_ue (&ctxt, rrc_data_req_ue (&ctxt,
DCCH1, DCCH,
nr_rrc_mui++, nr_rrc_mui++,
SDU_CONFIRM_NO, SDU_CONFIRM_NO,
length, buffer, length, buffer,
......
/*! \file FGSAuthenticationResponse.c
\brief authentication response procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "nas_log.h"
#include "FGSAuthenticationResponse.h"
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
if ((encode_result =
encode_authentication_response_parameter(&authentication_response->authenticationresponseparameter,
AUTHENTICATION_RESPONSE_PARAMETER_IEI, buffer + encoded, len - encoded)) < 0) //Return in case of error
return encode_result;
else
encoded += encode_result;
return encoded;
}
/*! \file FGSAuthenticationResponse.h
\brief authentication response procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "SecurityHeaderType.h"
#include "SpareHalfOctet.h"
#include "MessageType.h"
#include "AuthenticationResponseParameter.h"
#ifndef FGS_AUTHENTICATION_RESPONSE_H_
#define FGS_AUTHENTICATION_RESPONSE_H_
#define AUTHENTICATION_RESPONSE_PARAMETER_IEI 0x2d
/*
* Message name: Identity response
* Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1.
* Significance: dual
* Direction: UE to AMF
*/
typedef struct fgs_authentication_response_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
AuthenticationResponseParameter authenticationresponseparameter;
} fgs_authentication_response_msg;
int encode_fgs_authentication_response(fgs_authentication_response_msg *authentication_response, uint8_t *buffer, uint32_t len);
#endif /* ! defined(FGS_AUTHENTICATION_RESPONSE_H_) */
/*! \file FGSIdentityResponse.c
\brief identity response procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "nas_log.h"
#include "FGSIdentityResponse.h"
int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
if ((encode_result =
encode_5gs_mobile_identity(&fgs_identity_reps->fgsmobileidentity, 0, buffer +
encoded, len - encoded)) < 0) //Return in case of error
return encode_result;
else
encoded += encode_result;
return encoded;
}
/*! \file FGSIdentityResponse.h
\brief identity response procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "SecurityHeaderType.h"
#include "SpareHalfOctet.h"
#include "FGSMobileIdentity.h"
#include "MessageType.h"
#ifndef FGS_IDENTITY_RESPONSE_H_
#define FGS_IDENTITY_RESPONSE_H_
/*
* Message name: Identity response
* Description: This message is sent by the UE to the AMF to provide the requested identity. See table 8.2.22.1.
* Significance: dual
* Direction: UE to AMF
*/
typedef struct fgs_identiy_response_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
FGSMobileIdentity fgsmobileidentity;
} fgs_identiy_response_msg;
int encode_identiy_response(fgs_identiy_response_msg *fgs_identity_reps, uint8_t *buffer, uint32_t len);
#endif /* ! defined(FGS_IDENTITY_RESPONSE_H_) */
/*! \file FGSNASSecurityModeComplete.c
\brief security mode complete procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "nas_log.h"
#include "FGSNASSecurityModeComplete.h"
#include "FGSMobileIdentity.h"
#include "FGCNasMessageContainer.h"
int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
if ((encode_result =
encode_5gs_mobile_identity(&fgs_security_mode_comp->fgsmobileidentity, 0x77, buffer +
encoded, len - encoded)) < 0) { //Return in case of error
return encode_result;
} else {
encoded += encode_result;
if ((encode_result =
encode_fgc_nas_message_container(&fgs_security_mode_comp->fgsnasmessagecontainer, 0x71, buffer +
encoded, len - encoded)) < 0) {
return encode_result;
} else {
encoded += encode_result;
}
}
return encoded;
}
/*! \file FGSNASSecurityModeComplete.h
\brief security mode complete procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "SecurityHeaderType.h"
#include "SpareHalfOctet.h"
#include "FGSMobileIdentity.h"
#include "MessageType.h"
#include "FGCNasMessageContainer.h"
#ifndef FGS_NAS_SECURITY_MODE_COMPLETE_H_
#define FGS_NAS_SECURITY_MODE_COMPLETE_H_
/*
* Message name: security mode complete
* Description: This message is sent by the UE to the AMF in response to a SECURITY MODE COMMAND message. See table 8.2.26.1.1.
* Significance: dual
* Direction: UE to AMF
*/
typedef struct fgs_security_mode_complete_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
FGSMobileIdentity fgsmobileidentity;
FGCNasMessageContainer fgsnasmessagecontainer;
} fgs_security_mode_complete_msg;
int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len);
#endif /* ! defined(FGS_NAS_SECURITY_MODE_COMPLETE_H_) */
/*! \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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>
#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;
}
/*! \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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#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_) */
/*! \file RegistrationAccept.c
\brief 5GS registration accept procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "RegistrationAccept.h"
#include "assertions.h"
int decode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len)
{
uint32_t decoded = 0;
int decoded_result = 0;
/* Decoding mandatory fields */
if ((decoded_result = decode_fgs_registration_result(&registration_accept->fgsregistrationresult, 0, *(buffer + decoded), len - decoded)) < 0)
return decoded_result;
decoded += decoded_result;
// todo ,Decoding optional fields
return decoded;
}
int encode_registration_accept(registration_accept_msg *registration_accept, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
LOG_FUNC_IN;
*(buffer + encoded) = encode_fgs_registration_result(&registration_accept->fgsregistrationresult);
encoded = encoded + 2;
// todo ,Encoding optional fields
LOG_FUNC_RETURN(encoded);
}
/*! \file RegistrationAccept.h
\brief 5GS registration accept procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "SecurityHeaderType.h"
#include "SpareHalfOctet.h"
#include "MessageType.h"
#include "FGSRegistrationResult.h"
#ifndef REGISTRATION_ACCEPT_H_
#define REGISTRATION_ACCEPT_H_
/*
* Message name: Registration accept
* Description: The REGISTRATION ACCEPT message is sent by the AMF to the UE. See table 8.2.7.1.1.
* Significance: dual
* Direction: network to UE
*/
typedef struct registration_accept_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
FGSRegistrationResult fgsregistrationresult;
} registration_accept_msg;
int decode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
int encode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len);
#endif /* ! defined(REGISTRATION_ACCEPT_H_) */
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "RegistrationComplete.h"
#include "SORTransparentContainer.h"
int decode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len)
{
uint32_t decoded = 0;
int decoded_result = 0;
/* Decoding mandatory fields */
if ((decoded_result = decode_sor_transparent_container(&registration_complete->sortransparentcontainer, 0, buffer + decoded, len - decoded)) < 0)
return decoded_result;
else
decoded += decoded_result;
return decoded;
}
int encode_registration_complete(registration_complete_msg *registration_complete, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
if ((encode_result =
encode_sor_transparent_container(&registration_complete->sortransparentcontainer, 0,
buffer + encoded, len - encoded)) < 0) //Return in case of error
return encode_result;
else
encoded += encode_result;
return encoded;
}
/*! \file RegistrationRequest.h
\brief registration request procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "SecurityHeaderType.h"
#include "SpareHalfOctet.h"
#include "MessageType.h"
#include "SORTransparentContainer.h"
#ifndef REGISTRATION_COMPLETE_H_
#define REGISTRATION_COMPLETE_H_
typedef struct registration_complete_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
SecurityHeaderType securityheadertype:4;
SpareHalfOctet sparehalfoctet:4;
MessageType messagetype;
/* Optional fields */
SORTransparentContainer sortransparentcontainer;
} registration_complete_msg;
int decode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len);
int encode_registration_complete(registration_complete_msg *registrationcomplete, uint8_t *buffer, uint32_t len);
#endif /* ! defined(REGISTRATION_COMPLETE_H_) */
/*! \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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#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);
*(buffer + encoded) = 0x91;
encoded++;
*(buffer + encoded) = 0xA1;
encoded++;
return encoded;
}
/*! \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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#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_) */
/*! \file FGCNasMessageContainer.c
\brief security mode complete procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "FGCNasMessageContainer.h"
int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
int decoded = 0;
uint8_t ielen = 0;
int decode_result;
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}
ielen = *(buffer + decoded);
decoded += 2;
CHECK_LENGTH_DECODER(len - decoded, ielen);
if ((decode_result = decode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, ielen, buffer + decoded, len - decoded)) < 0)
return decode_result;
else
decoded += decode_result;
return decoded;
}
int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
uint32_t encoded = 0;
int encode_result;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH, len);
if (iei > 0) {
*buffer = iei;
encoded++;
}
encoded += 2;
if ((encode_result = encode_octet_string(&nasmessagecontainer->nasmessagecontainercontents, buffer + encoded, len - encoded)) < 0) {
return encode_result;
} else {
*(uint16_t*) (buffer+1) = htons(encoded + encode_result - 3);
encoded += encode_result;
}
return encoded;
}
void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei)
{
printf("<Nas Message Container>\n");
if (iei > 0)
/* Don't display IEI if = 0 */
printf(" <IEI>0x%X</IEI>\n", iei);
printf("%s", dump_octet_string_xml(&nasmessagecontainer->nasmessagecontainercontents));
printf("</Nas Message Container>\n");
}
/*! \file FGCNasMessageContainer.h
\brief security mode complete procedures for gNB
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "OctetString.h"
#ifndef FGC_NAS_MESSAGE_CONTAINER_H_
#define FGC_NAS_MESSAGE_CONTAINER_H_
#define FGC_NAS_MESSAGE_CONTAINER_MINIMUM_LENGTH 4
#define FGC_NAS_MESSAGE_CONTAINER_MAXIMUM_LENGTH 65535
typedef struct FGCNasMessageContainer_tag {
OctetString nasmessagecontainercontents;
} FGCNasMessageContainer;
int encode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_fgc_nas_message_container(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
void dump_fgc_nas_message_container_xml(FGCNasMessageContainer *nasmessagecontainer, uint8_t iei);
#endif /* FGC NAS MESSAGE CONTAINER_H_ */
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer);
static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer);
static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer);
int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len)
{ {
...@@ -87,11 +89,26 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei ...@@ -87,11 +89,26 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei
buffer + encoded); buffer + encoded);
} }
if (fgsmobileidentity->suci.typeofidentity == FGS_MOBILE_IDENTITY_SUCI) {
encoded_rc = encode_suci_5gs_mobile_identity(&fgsmobileidentity->suci,
buffer + encoded);
}
if (fgsmobileidentity->imeisv.typeofidentity == FGS_MOBILE_IDENTITY_IMEISV) {
encoded_rc = encode_imeisv_5gs_mobile_identity(&fgsmobileidentity->imeisv,
buffer + encoded);
}
if (encoded_rc < 0) { if (encoded_rc < 0) {
return encoded_rc; return encoded_rc;
} }
*(uint16_t*) buffer = htons(encoded + encoded_rc - 2 - ((iei > 0) ? 1 : 0)); if(iei > 0){
*(uint16_t*) (buffer+1) = htons(encoded + encoded_rc - 3);
} else {
*(uint16_t*) buffer = htons(encoded + encoded_rc - 2);
}
return (encoded + encoded_rc); return (encoded + encoded_rc);
} }
...@@ -166,10 +183,57 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_ ...@@ -166,10 +183,57 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_
*(buffer + encoded) = guti->amfregionid; *(buffer + encoded) = guti->amfregionid;
encoded++; encoded++;
temp = 0x00 | ((guti->amfsetid & 0x3f) << 6) | (guti->amfpointer & 0x3f); temp = 0x00 | ((guti->amfsetid) << 6) | (guti->amfpointer & 0x3f);
IES_ENCODE_U16(buffer, encoded, temp); IES_ENCODE_U16(buffer, encoded, temp);
IES_ENCODE_U32(buffer, encoded, guti->tmsi); IES_ENCODE_U32(buffer, encoded, guti->tmsi);
return encoded; return encoded;
} }
static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer)
{
uint32_t encoded = 0;
*(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity);
encoded++;
*(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) |
(suci->mccdigit1 & 0xf);
encoded++;
*(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) |
(suci->mccdigit3 & 0xf);
encoded++;
*(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) |
(suci->mncdigit1 & 0xf);
encoded++;
*(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) |
(suci->routingindicatordigit1 & 0xf);
encoded++;
*(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) |
(suci->routingindicatordigit3 & 0xf);
encoded++;
*(buffer + encoded) = 0x00 | (suci->protectionschemeId & 0xf);
encoded++;
*(buffer + encoded) = suci->homenetworkpki;
encoded++;
IES_ENCODE_U32(buffer, encoded, suci->schemeoutput);
return encoded;
}
static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer)
{
uint32_t encoded = 0;
*(buffer + encoded) = 0x00 | (imeisv->digit1 << 4) | (imeisv->oddeven << 3) | (imeisv->typeofidentity);
encoded++;
*(buffer + encoded) = 0x00 | (imeisv->digitp1 << 4) | (imeisv->digitp);
encoded++;
return encoded;
}
...@@ -64,6 +64,7 @@ typedef struct { ...@@ -64,6 +64,7 @@ typedef struct {
uint8_t spare6:1; uint8_t spare6:1;
uint8_t protectionschemeId:4; uint8_t protectionschemeId:4;
uint8_t homenetworkpki; uint8_t homenetworkpki;
uint32_t schemeoutput;
} Suci5GSMobileIdentity_t; } Suci5GSMobileIdentity_t;
typedef struct { typedef struct {
......
/*! \file FGSRegistrationResult.c
\brief 5GS Registration result for registration request procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "FGSRegistrationResult.h"
int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len)
{
int decoded = 0;
uint16_t *buffer = &value;
fgsregistrationresult->registrationresult = *buffer & 0x7;
fgsregistrationresult->smsallowed = *buffer & 0x8;
decoded = decoded+2;
return decoded;
}
uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult)
{
uint16_t bufferReturn;
uint16_t *buffer = &bufferReturn;
uint8_t encoded = 0;
*(buffer + encoded) = 0x00 | (fgsregistrationresult->smsallowed & 0x8) |
(fgsregistrationresult->registrationresult & 0x7);
encoded= encoded+2;
return bufferReturn;
}
/*! \file FGSRegistrationResult.h
\brief 5GS Registration result for registration request procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "OctetString.h"
#ifndef FGS_REGISTRATION_RESULT_H_
#define FGS_REGISTRATION_RESULT_H_
#define FGS_REGISTRATION_RESULT_3GPP 0b001
#define FGS_REGISTRATION_RESULT_NON_3GPP 0b010
#define FGS_REGISTRATION_RESULT_3GPP_AND_NON_3GPP 0b011
typedef struct {
uint8_t iei;
uint8_t resultlength;
uint8_t spare:4;
uint8_t smsallowed:1;
uint8_t registrationresult:3;
} FGSRegistrationResult;
uint16_t encode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult);
int decode_fgs_registration_result(FGSRegistrationResult *fgsregistrationresult, uint8_t iei, uint16_t value, uint32_t len);
#endif /* FGS REGISTRATION RESULT_H_*/
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "SORTransparentContainer.h"
#include "nas_log.h"
//#define NAS_DEBUG 1
int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
int decoded = 0;
int decode_result;
uint16_t ielen;
LOG_FUNC_IN;
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}
DECODE_LENGTH_U16(buffer + decoded, ielen, decoded);
CHECK_LENGTH_DECODER(len - decoded, ielen);
if ((decode_result = decode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, ielen, buffer + decoded, len - decoded)) < 0) {
LOG_FUNC_RETURN(decode_result);
} else {
decoded += decode_result;
}
#if defined (NAS_DEBUG)
dump_sor_transparent_container_xml(sortransparentcontainer, iei);
#endif
LOG_FUNC_RETURN(decoded);
}
int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len)
{
uint8_t *lenPtr;
uint32_t encoded = 0;
int32_t encode_result;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH, len);
#if defined (NAS_DEBUG)
dump_sor_transparent_container_xml(sortransparentcontainer, iei);
#endif
if (iei > 0) {
*buffer = iei;
encoded++;
}
lenPtr = (buffer + encoded);
//encoded += 2;
//if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, buffer + sizeof(uint16_t), len - sizeof(uint16_t))) < 0)
if ((encode_result = encode_octet_string(&sortransparentcontainer->sortransparentcontainercontents, lenPtr + sizeof(uint16_t), len - sizeof(uint16_t))) < 0)
return encode_result;
else
encoded += encode_result;
ENCODE_U16(lenPtr, encode_result, encoded);
return encoded;
}
void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei)
{
printf("<SOR Transparent Container>\n");
if (iei > 0)
/* Don't display IEI if = 0 */
printf(" <IEI>0x%X</IEI>\n", iei);
printf("%s", dump_octet_string_xml(&sortransparentcontainer->sortransparentcontainercontents));
printf("</SOR Transparent Container>\n");
}
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "OctetString.h"
#ifndef SOR_TRANSPARENT_CONTAINER_H_
#define SOR_TRANSPARENT_CONTAINER_H_
#define SOR_TRANSPARENT_CONTAINER_MINIMUM_LENGTH 2 // [length]+[length]
#define SOR_TRANSPARENT_CONTAINER_MAXIMUM_LENGTH 65538 // [IEI]+[length]+[length]+[ESM msg]
typedef struct SORTransparentContainer_tag {
OctetString sortransparentcontainercontents;
} SORTransparentContainer;
int encode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_sor_transparent_container(SORTransparentContainer *sortransparentcontainer, uint8_t iei, uint8_t *buffer, uint32_t len);
void dump_sor_transparent_container_xml(SORTransparentContainer *sortransparentcontainer, uint8_t iei);
#endif /* ESM MESSAGE CONTAINER_H_ */
...@@ -35,7 +35,41 @@ ...@@ -35,7 +35,41 @@
#include "TLVDecoder.h" #include "TLVDecoder.h"
#include "TLVEncoder.h" #include "TLVEncoder.h"
#include "nr_nas_msg_sim.h" #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
uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0};
// OPC: 981d464c7c52eb6e5036234984ad0bcf
const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};
uint8_t *registration_request_buf;
uint32_t registration_request_len;
static int nas_protected_security_header_encode(
char *buffer,
const fgs_nas_message_security_header_t *header,
int length)
{
LOG_FUNC_IN;
int size = 0;
/* Encode the protocol discriminator) */
ENCODE_U8(buffer, header->protocol_discriminator, size);
/* Encode the security header type */
ENCODE_U8(buffer+size, (header->security_header_type & 0xf), size);
/* Encode the message authentication code */
ENCODE_U32(buffer+size, header->message_authentication_code, size);
/* Encode the sequence number */
ENCODE_U8(buffer+size, header->sequence_number, size);
LOG_FUNC_RETURN (size);
}
static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, static int _nas_mm_msg_encode_header(const mm_msg_header_t *header,
uint8_t *buffer, uint32_t len) { uint8_t *buffer, uint32_t len) {
...@@ -86,7 +120,18 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { ...@@ -86,7 +120,18 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
case REGISTRATION_REQUEST: case REGISTRATION_REQUEST:
encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len); encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len);
break; break;
case FGS_IDENTITY_RESPONSE:
encode_result = encode_identiy_response(&mm_msg->fgs_identity_response, buffer, len);
break;
case FGS_AUTHENTICATION_RESPONSE:
encode_result = encode_fgs_authentication_response(&mm_msg->fgs_auth_response, buffer, len);
break;
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: default:
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
mm_msg->header.message_type); mm_msg->header.message_type);
...@@ -106,7 +151,104 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { ...@@ -106,7 +151,104 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) {
LOG_FUNC_RETURN (header_result + encode_result); LOG_FUNC_RETURN (header_result + encode_result);
} }
void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) {
uint8_t S[100];
S[0] = 0x6B;
int netNamesize = strlen(netName);
memcpy(&S[1], netName, netNamesize);
S[1 + netNamesize] = (netNamesize & 0xff00) >> 8;
S[2 + netNamesize] = (netNamesize & 0x00ff);
for (int i = 0; i < 16; i++)
S[3 + netNamesize + i] = rand[i];
S[19 + netNamesize] = 0x00;
S[20 + netNamesize] = 0x10;
for (int i = 0; i < 8; i++)
S[21 + netNamesize + i] = input[i];
S[29 + netNamesize] = 0x00;
S[30 + netNamesize] = 0x08;
uint8_t plmn[3] = { 0x02, 0xf8, 0x39 };
uint8_t oldS[100];
oldS[0] = 0x6B;
memcpy(&oldS[1], plmn, 3);
oldS[4] = 0x00;
oldS[5] = 0x03;
for (int i = 0; i < 16; i++)
oldS[6 + i] = rand[i];
oldS[22] = 0x00;
oldS[23] = 0x10;
for (int i = 0; i < 8; i++)
oldS[24 + i] = input[i];
oldS[32] = 0x00;
oldS[33] = 0x08;
uint8_t key[32];
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY
uint8_t out[32];
kdf(key, 32, S, 31 + netNamesize, out, 32);
for (int i = 0; i < 16; i++)
output[i] = out[16 + i];
}
void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) {
uint8_t S[100];
uint8_t key[32];
int netNamesize = strlen(netName);
memcpy(&key[0], ck, 16);
memcpy(&key[16], ik, 16); //KEY
S[0] = 0x6A;
memcpy(&S[1], netName, netNamesize);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
for (int i = 0; i < 6; i++) {
S[3 + netNamesize + i] = sqn[i];
}
S[9 + netNamesize] = 0x00;
S[10 + netNamesize] = 0x06;
kdf(key, 32, S, 11 + netNamesize, kausf, 32);
}
void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) {
uint8_t S[100];
int netNamesize = strlen(netName);
S[0] = 0x6C; //FC
memcpy(&S[1], netName, netNamesize);
S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8);
S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff);
kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32);
}
void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) {
int imsiLen = strlen(imsi);
uint8_t S[100];
S[0] = 0x6D; //FC = 0x6D
memcpy(&S[1], imsi, imsiLen);
S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8);
S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff);
S[3 + imsiLen] = abba & 0x00ff;
S[4 + imsiLen] = (abba & 0xff00) >> 8;
S[5 + imsiLen] = 0x00;
S[6 + imsiLen] = 0x02;
kdf(kseaf, 32, S, 7 + imsiLen, kamf, 32);
}
//------------------------------------------------------------------------------
void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t kamf[32], uint8_t *knas_int) {
uint8_t S[20];
uint8_t out[32] = { 0 };
S[0] = 0x69; //FC
S[1] = (uint8_t)(nas_alg_type & 0xFF);
S[2] = 0x00;
S[3] = 0x01;
S[4] = nas_alg_id;
S[5] = 0x00;
S[6] = 0x01;
kdf(kamf, 32, S, 7, out, 32);
for (int i = 0; i < 16; i++)
knas_int[i] = out[16 + i];
}
void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
int size = sizeof(mm_msg_header_t); int size = sizeof(mm_msg_header_t);
...@@ -129,20 +271,35 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { ...@@ -129,20 +271,35 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
mm_msg->registration_request.messagetype = REGISTRATION_REQUEST; mm_msg->registration_request.messagetype = REGISTRATION_REQUEST;
size += 1; size += 1;
mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION; mm_msg->registration_request.fgsregistrationtype = INITIAL_REGISTRATION;
mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE; mm_msg->registration_request.naskeysetidentifier.naskeysetidentifier = 1;
size += 1; size += 1;
mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI; if(1){
// mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 1; mm_msg->registration_request.fgsmobileidentity.guti.typeofidentity = FGS_MOBILE_IDENTITY_5G_GUTI;
// mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 1; mm_msg->registration_request.fgsmobileidentity.guti.amfregionid = 0xca;
// mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1; mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0;
mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10; mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016;
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9; mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10;
mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3; mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2; mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 3;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0; mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8; mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2;
mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0;
size += 13; mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8;
size += 13;
} else {
mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9;
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 3;
mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf;
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2;
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0;
mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8;
mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778;
size += 14;
}
mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT; mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT;
mm_msg->registration_request.fgmmcapability.iei = REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI; mm_msg->registration_request.fgmmcapability.iei = REGISTRATION_REQUEST_5GMM_CAPABILITY_IEI;
...@@ -154,15 +311,378 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { ...@@ -154,15 +311,378 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) {
mm_msg->registration_request.nruesecuritycapability.iei = REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI; mm_msg->registration_request.nruesecuritycapability.iei = REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_IEI;
mm_msg->registration_request.nruesecuritycapability.length = 8; mm_msg->registration_request.nruesecuritycapability.length = 8;
mm_msg->registration_request.nruesecuritycapability.fg_EA = 0x80; mm_msg->registration_request.nruesecuritycapability.fg_EA = 0x80;
mm_msg->registration_request.nruesecuritycapability.fg_IA = 0x20; mm_msg->registration_request.nruesecuritycapability.fg_IA = 0x40;
mm_msg->registration_request.nruesecuritycapability.EEA = 0; mm_msg->registration_request.nruesecuritycapability.EEA = 0;
mm_msg->registration_request.nruesecuritycapability.EIA = 0; mm_msg->registration_request.nruesecuritycapability.EIA = 0;
size += 10; size += 10;
// encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
registration_request_buf = initialNasMsg->data;
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
registration_request_len = initialNasMsg->length;
}
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) {
int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
mm_msg = &nas_msg.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_IDENTITY_RESPONSE;
// set identity response
mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
size += 1;
mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG;
size += 1;
mm_msg->fgs_identity_response.messagetype = FGS_IDENTITY_RESPONSE;
size += 1;
if(identitytype == FGS_MOBILE_IDENTITY_SUCI){
mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 3;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8;
mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778;
size += 14;
}
// encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
}
OctetString knas_int;
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){
uint8_t ak[6];
uint8_t kausf[32];
uint8_t sqn[6];
uint8_t kseaf[32];
uint8_t kamf[32];
OctetString res;
// get RAND for authentication request
unsigned char rand[16];
for(int index = 0; index < 16;index++){
rand[index] = buf[8+index];
}
uint8_t resTemp[16];
uint8_t ck[16], ik[16], output[16];
f2345(k, rand, resTemp, ck, ik, ak, opc);
transferRES(ck, ik, resTemp, rand, output);
// get knas_int
knas_int.length = 16;
knas_int.value = malloc(knas_int.length);
for(int index = 0; index < 6; index++){
sqn[index] = buf[26+index];
}
derive_kausf(ck, ik, sqn, kausf);
derive_kseaf(kausf, kseaf);
derive_kamf(kseaf, kamf, 0x0000);
derive_knas(0x02, 2, kamf, knas_int.value);
printf("kausf:");
for(int i = 0; i < 32; i++){
printf("%x ", kausf[i]);
}
printf("\n");
printf("kseaf:");
for(int i = 0; i < 32; i++){
printf("%x ", kseaf[i]);
}
printf("\n");
printf("kamf:");
for(int i = 0; i < 32; i++){
printf("%x ", kamf[i]);
}
printf("\n");
printf("knas_int:\n");
for(int i = 0; i < 16; i++){
printf("%x ", knas_int.value[i]);
}
printf("\n");
// set res
res.length = 16;
res.value = output;
int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
mm_msg = &nas_msg.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_AUTHENTICATION_RESPONSE;
// set authentication response
mm_msg->fgs_identity_response.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
size += 1;
mm_msg->fgs_identity_response.securityheadertype = PLAIN_5GS_MSG;
size += 1;
mm_msg->fgs_identity_response.messagetype = FGS_AUTHENTICATION_RESPONSE;
size += 1;
//set response parameter
mm_msg->fgs_auth_response.authenticationresponseparameter.res = res;
size += 18;
// encode the message // encode the message
initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t));
initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size);
}
void generateSecurityModeComplete(as_nas_info_t *initialNasMsg)
{
int size = sizeof(mm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
nas_stream_cipher_t stream_cipher;
uint8_t mac[4];
// 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_SECURITY_MODE_COMPLETE;
// set security mode complete
mm_msg->fgs_security_mode_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
size += 1;
mm_msg->fgs_security_mode_complete.securityheadertype = PLAIN_5GS_MSG;
size += 1;
mm_msg->fgs_security_mode_complete.messagetype = FGS_SECURITY_MODE_COMPLETE;
size += 1;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit1 = 1;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp1 = 1;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp = 1;
mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.oddeven = 0;
size += 5;
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.value = registration_request_buf;
mm_msg->fgs_security_mode_complete.fgsnasmessagecontainer.nasmessagecontainercontents.length = registration_request_len;
size += (registration_request_len + 2);
// 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];
}
}
void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) {
int length = 0;
int size = 0;
fgs_nas_message_t nas_msg;
nas_stream_cipher_t stream_cipher;
uint8_t mac[4];
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
fgs_nas_message_security_protected_t *sp_msg;
sp_msg = &nas_msg.security_protected;
// set header
sp_msg->header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
sp_msg->header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED;
sp_msg->header.message_authentication_code = 0;
sp_msg->header.sequence_number = 1;
length = 7;
sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
length += 1;
sp_msg->plain.mm_msg.registration_complete.securityheadertype = PLAIN_5GS_MSG;
sp_msg->plain.mm_msg.registration_complete.sparehalfoctet = 0;
length += 1;
sp_msg->plain.mm_msg.registration_complete.messagetype = REGISTRATION_COMPLETE;
length += 1;
if(sortransparentcontainer) {
length += sortransparentcontainer->sortransparentcontainercontents.length;
}
// encode the message
initialNasMsg->data = (Byte_t *)malloc(length * sizeof(Byte_t));
/* Encode the first octet of the header (extended protocol discriminator) */
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.protocol_discriminator, size);
/* Encode the security header type */
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.security_header_type, size);
/* Encode the message authentication code */
ENCODE_U32(initialNasMsg->data + size, sp_msg->header.message_authentication_code, size);
/* Encode the sequence number */
ENCODE_U8(initialNasMsg->data + size, sp_msg->header.sequence_number, size);
/* Encode the extended protocol discriminator */
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.protocoldiscriminator, size);
/* Encode the security header type */
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.securityheadertype, size);
/* Encode the message type */
ENCODE_U8(initialNasMsg->data + size, sp_msg->plain.mm_msg.registration_complete.messagetype, size);
if(sortransparentcontainer) {
encode_registration_complete(&sp_msg->plain.mm_msg.registration_complete, initialNasMsg->data + size, length - size);
}
initialNasMsg->length = length;
stream_cipher.key = knas_int.value;
stream_cipher.key_length = 16;
stream_cipher.count = 1;
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];
}
}
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 = 8;
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];
}
} }
...@@ -33,13 +33,52 @@ ...@@ -33,13 +33,52 @@
#define __NR_NAS_MSG_SIM_H__ #define __NR_NAS_MSG_SIM_H__
#include "RegistrationRequest.h" #include "RegistrationRequest.h"
#include "FGSIdentityResponse.h"
#include "FGSAuthenticationResponse.h"
#include "FGSNASSecurityModeComplete.h"
#include "RegistrationComplete.h"
#include "as_message.h" #include "as_message.h"
#include "FGSUplinkNasTransport.h"
#define PLAIN_5GS_MSG 0b0000 #define PLAIN_5GS_MSG 0b0000
#define INTEGRITY_PROTECTED 0b0001 #define INTEGRITY_PROTECTED 0b0001
#define INTEGRITY_PROTECTED_AND_CIPHERED 0b0010
#define INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX 0b0011 // only for SECURITY MODE COMMAND
#define INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX 0b0100 // only for SECURITY MODE COMPLETE
#define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */ #define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */
#define REGISTRATION_ACCEPT 0b01000010 /* 66 = 0x42 */
#define REGISTRATION_COMPLETE 0b01000011 /* 67 = 0x43 */
#define REGISTRATION_REJECT 0b01000100 /* 68 = 0x44 */
#define DEREGISTRATION_REQUEST_UE_ORIGINATING 0b01000101 /* 69 = 0x45 */
#define DEREGISTRATION_ACCEPT_UE_ORIGINATING 0b01000110 /* 70 = 0x46 */
#define DEREGISTRATION_REQUEST_UE_TERMINATED 0b01000111 /* 71 = 0x47 */
#define DEREGISTRATION_ACCEPT_UE_TERMINATED 0b01001000 /* 72 = 0x48 */
#define FIVEGMM_SERVICE_REQUEST 0b01001100 /* 76 = 0x4c */
#define FIVEGMM_SERVICE_REJECT 0b01001101 /* 77 = 0x4d */
#define FIVEGMM_SERVICE_ACCEPT 0b01001110 /* 78 = 0x4e */
#define CONFIGURATION_UPDATE_COMMAND 0b01010100 /* 84 = 0x54 */
#define CONFIGURATION_UPDATE_COMPLETE 0b01010101 /* 85 = 0x55 */
#define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */
#define FGS_AUTHENTICATION_RESPONSE 0b01010111 /* 87 = 0x57 */
#define AUTHENTICATION_REJECT 0b01011000 /* 88 = 0x58 */
#define AUTHENTICATION_FAILURE 0b01011001 /* 89 = 0x59 */
#define AUTHENTICATION_RESULT 0b01011010 /* 90 = 0x5a */
#define FGS_IDENTITY_REQUEST 0b01011011 /* 91 = 0x5b */
#define FGS_IDENTITY_RESPONSE 0b01011100 /* 92 = 0x5c */
#define FGS_SECURITY_MODE_COMMAND 0b01011101 /* 93 = 0x5d */
#define FGS_SECURITY_MODE_COMPLETE 0b01011110 /* 94 = 0x5e */
#define FIVEGMM_SECURITY_MODE_REJECT 0b01011111 /* 95 = 0x5f */
#define FIVEGMM_STATUS 0b01100100 /* 100 = 0x64 */
#define NOTIFICATION 0b01100101 /* 101 = 0x65 */
#define NOTIFICATION_RESPONSE 0b01100110 /* 102 = 0x66 */
#define FGS_UPLINK_NAS_TRANSPORT 0b01100111 /* 103= 0x67 */
#define DL_NAS_TRANSPORT 0b01101000 /* 104 = 0x68 */
// message type for 5GS session management
#define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */
#define INITIAL_REGISTRATION 0b001 #define INITIAL_REGISTRATION 0b001
...@@ -69,6 +108,11 @@ typedef struct { ...@@ -69,6 +108,11 @@ typedef struct {
typedef union { typedef union {
mm_msg_header_t header; mm_msg_header_t header;
registration_request_msg registration_request; registration_request_msg registration_request;
fgs_identiy_response_msg fgs_identity_response;
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; } MM_msg;
...@@ -90,5 +134,13 @@ typedef union { ...@@ -90,5 +134,13 @@ typedef union {
} fgs_nas_message_t; } fgs_nas_message_t;
void generateRegistrationRequest(as_nas_info_t *initialNasMsg); void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
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__*/ #endif /* __NR_NAS_MSG_SIM_H__*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment