/******************************************************************************/ // @copyright Copyright Notification // No part may be reproduced except as authorized by written permission. // The copyright and the foregoing restriction extend to reproduction in all media. // (c) 2023, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TSDSI, TTA, TTC). // All rights reserved. // @version: IWD_23wk37 // $Date: 2021-04-28 17:21:30 +0200 (Wed, 28 Apr 2021) $ // $Rev: 30488 $ /******************************************************************************/ module NasEmu5G_Main_NRNG { import from NR_RRC_ASN1_Definitions language "ASN.1:2002" all with {encode "UNALIGNED_PER_OctetAligned"}; import from NR_CommonDefs all; import from NR_ASP_SrbDefs all; import from NasEmu_Common4G5G all; import from Common4G5G_Templates all; import from NasEmu5G_AspTypes_NR all; import from NasEmu5G_Component_NRNG all; import from NasEmu5G_Component_NR_BASE all; import from NG_NasEmu_Common all; import from NG_NAS_MsgContainers all; import from NR_RRC_Templates all; import from CommonDefs all; import from NG_SecurityDefinitionsAndExternalFunctions all; //---------------------------------------------------------------------------- template (present) NR_SRB_COMMON_REQ car_NRNG_SignallingAspFromTC := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ Common := ?, Signalling := { Rrc := *, Nas := * } }; template (value) NR_SRB_COMMON_IND cas_NRNG_SignallingAspToTC(template (value) NR_IndAspCommonPart_Type p_Common, template (omit) NR_RRC_MSG_Indication_Type p_RrcMsg := omit, template (omit) NG_NAS_MSG_IndicationList_Type p_NasMsg := omit) := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ Common := p_Common, Signalling := { Rrc := p_RrcMsg, Nas := p_NasMsg } }; //---------------------------------------------------------------------------- template (present) NR_RRC_PDU_IND car_NRNG_PduFromSYS := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ Common := ?, RrcPdu := ? }; template (value) NR_RRC_PDU_REQ cas_NRNG_PduToSYS(template (value) NR_ReqAspCommonPart_Type p_Common, template (value) NR_RRC_MSG_Request_Type p_RRC_MSG_Request) := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ Common := p_Common, RrcPdu := p_RRC_MSG_Request }; template (value) NR_RRC_MSG_Request_Type cs_NR_RRC_MSG_RequestDCCH(template (value) DL_DCCH_Message p_DcchRrcPdu) := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ Dcch := p_DcchRrcPdu }; //**************************************************************************** // Templates: RRC Signalling //---------------------------------------------------------------------------- // DLInformationTransfer (38.331 cl. 6.2.2) template (value) DL_DCCH_Message cs_NR_DLInformationTransfer(RRC_TransactionIdentifier p_RRC_TI, template (value) DedicatedNAS_Message p_NAS_DedicatedMsg) := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ message_ := { c1 := { dlInformationTransfer := { rrc_TransactionIdentifier := p_RRC_TI, criticalExtensions := { dlInformationTransfer := { dedicatedNAS_Message := p_NAS_DedicatedMsg, lateNonCriticalExtension := omit, nonCriticalExtension := omit } } } } } }; template (value) RRCReconfiguration_v1530_IEs cs_38508_RRCReconfiguration_NonCriticalExtension_AllOmit := { /* @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ masterCellGroup := omit, fullConfig := omit, dedicatedNAS_MessageList := omit, masterKeyUpdate := omit, dedicatedSIB1_Delivery := omit, dedicatedSystemInformationDelivery := omit, otherConfig := omit, nonCriticalExtension := omit }; //---------------------------------------------------------------------------- /* * @desc Handling of ASPs coming from the test cases * @param p_NG_NasSecurityByRef (by reference) * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ altstep a_AspFromTestcaseHandler_NRNG(inout NG_NasSecurity_Type p_NG_NasSecurityByRef) runs on NASEMU_NR_BASE_PTC { var NR_SRB_COMMON_REQ v_AspFromTC; var NR_ReqAspCommonPart_Type v_ReqAspCommonPart; var template (value) NR_RRC_MSG_Request_Type v_RrcPduToSYS; var NG_NAS_MSG_Request_Type v_NG_NasPduFromTC; var template (value) DL_DCCH_Message v_DL_DCCH_Message; var DedicatedNAS_Message v_NAS_DedicatedMsg[maxDRB]; // we use an array as long as this is an inline type definition in ASN.1 var integer v_NoOfNasPdus := 0; var boolean v_RrcPduIsPresent; var boolean v_NasPduIsPresent; var integer I; [] TC_SRB.receive(car_NRNG_SignallingAspFromTC) -> value v_AspFromTC { v_ReqAspCommonPart := v_AspFromTC.Common; v_RrcPduIsPresent := ispresent(v_AspFromTC.Signalling.Rrc); v_NasPduIsPresent := ispresent(v_AspFromTC.Signalling.Nas); if (v_NasPduIsPresent) { // Note: in case of RRCReconfiguration there may be more than one NAS PDUs v_NoOfNasPdus := lengthof(v_AspFromTC.Signalling.Nas); // Note: per ASN.1 definition length is restricted to maxDRB for (I:=0; I < v_NoOfNasPdus; I:= I + 1) { v_NG_NasPduFromTC := v_AspFromTC.Signalling.Nas[I]; v_NAS_DedicatedMsg[I] := f_EncodeAndCipher_NG_NasPdu(p_NG_NasSecurityByRef, v_NG_NasPduFromTC); // encode NAS PDU; apply NAS security (if reqired) } } if (v_RrcPduIsPresent) { // ******* RRC PDU (containing RRC control information) v_RrcPduToSYS := v_AspFromTC.Signalling.Rrc; if (v_NasPduIsPresent) { // ***** NAS PDU BEING PIGGY BACKED if (not ischosen(v_RrcPduToSYS.Dcch)) { // ***** SRB0 f_NasEmulationError(__FILE__, __LINE__, "no piggy-backing possible for CCCH message"); return; /* don't send anything */ } else { // ***** SRB1/2/3 v_DL_DCCH_Message := v_RrcPduToSYS.Dcch; /* extract RRC message; Note: since v_RrcPduToSYS is a union v_RrcPduToSYS.Dcch is never omit */ if (ischosen(v_DL_DCCH_Message.message_.c1.rrcReconfiguration)) { /* RRC message is RRCConnectionReconfiguration */ // *** RRC RECONFIGURATION: if ((v_NoOfNasPdus > 0) and not isvalue(v_DL_DCCH_Message.message_.c1.rrcReconfiguration.criticalExtensions.rrcReconfiguration.nonCriticalExtension)) { // @sic R5s210463 sic@ v_DL_DCCH_Message.message_.c1.rrcReconfiguration.criticalExtensions.rrcReconfiguration.nonCriticalExtension := cs_38508_RRCReconfiguration_NonCriticalExtension_AllOmit; } for (I:=0; I < v_NoOfNasPdus; I:= I + 1) { v_DL_DCCH_Message.message_.c1.rrcReconfiguration.criticalExtensions.rrcReconfiguration.nonCriticalExtension.dedicatedNAS_MessageList[I] := v_NAS_DedicatedMsg[I]; } } else if (ischosen(v_DL_DCCH_Message.message_.c1.dlInformationTransfer)) { // RRC message is DLInformationTransfer // *** DL INFORMATION TRANSFER: if (v_NoOfNasPdus > 1) { f_NasEmulationError(__FILE__, __LINE__, "too many NAS PDUs (shall be a maximun of 1 PDU for DLInformationTransfer)"); return; // don't send anything } else { v_DL_DCCH_Message.message_.c1.dlInformationTransfer.criticalExtensions.dlInformationTransfer.dedicatedNAS_Message := v_NAS_DedicatedMsg[0]; } } else { // *** OTHER RRC PDU: f_NasEmulationError(__FILE__, __LINE__, "RRC message can not carry piggy-backed NAS PDU"); return; /* don't do anything else */ } v_RrcPduToSYS := cs_NR_RRC_MSG_RequestDCCH(v_DL_DCCH_Message); } } } else { // ******* NAS PDU only: if (not v_NasPduIsPresent) { f_NasEmulationError(__FILE__, __LINE__, "neither RRC nor NAS PDU to be sent"); return; /* don't send anything */ } else { if (v_NoOfNasPdus > 1) { f_NasEmulationError(__FILE__, __LINE__, "too many NAS PDUs (shall be a maximun of 1 PDU for DLInformationTransfer)"); return; /* don't send anything */ } else { v_RrcPduToSYS := cs_NR_RRC_MSG_RequestDCCH(cs_NR_DLInformationTransfer(tsc_NR_RRC_TI_Def, v_NAS_DedicatedMsg[0])); } } } SYS_SRB.send(cas_NRNG_PduToSYS(v_ReqAspCommonPart, v_RrcPduToSYS)); } } //---------------------------------------------------------------------------- /* * @desc handling of ASPs containing an RRC PDU from the system adaptor * @param p_NG_NasSecurityByRef (by reference) * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ altstep a_AspFromSystemAdaptorHandler_NRNG(inout NG_NasSecurity_Type p_NG_NasSecurityByRef) runs on NASEMU_NR_BASE_PTC { var NR_RRC_PDU_IND v_AspFromSYS; var NR_RRC_MSG_Indication_Type v_RrcIndication; var UL_DCCH_Message v_RrcPdu; var ULInformationTransfer_IEs v_ULInformationTransfer; var template (value) NR_SRB_COMMON_IND v_SRB_COMMON_IND; var template (value) NG_NasEmu_DecodingInfo_Type v_DecodingInfo; var DedicatedNAS_Message v_NAS_DedicatedMsg[maxDRB]; // even though there is always only one we use an array var integer v_NoOfNasPdus; var boolean v_RrcPduPresent; var boolean v_IntegrityError; var integer I; [] SYS_SRB.receive(car_NRNG_PduFromSYS) -> value v_AspFromSYS { v_RrcIndication := v_AspFromSYS.RrcPdu; v_SRB_COMMON_IND := cas_NRNG_SignallingAspToTC(v_AspFromSYS.Common); if (ischosen(v_RrcIndication.Ccch) or ischosen(v_RrcIndication.Ccch1)) { /* CCCH -> SRB0 */ //@sic R5s191051 sic@ v_SRB_COMMON_IND.Signalling.Rrc := v_RrcIndication; } else { /* DCCH -> SRB1/2/3 */ v_RrcPdu := v_RrcIndication.Dcch; v_RrcPduPresent := true; v_NoOfNasPdus := 0; v_IntegrityError := false; if (ischosen(v_RrcPdu.message_.c1)) { if (ischosen(v_RrcPdu.message_.c1.rrcSetupComplete)) { // RRC SETUP COMPLETE if (ischosen(v_RrcPdu.message_.c1.rrcSetupComplete.criticalExtensions.rrcSetupComplete)) { v_NAS_DedicatedMsg[0] := v_RrcPdu.message_.c1.rrcSetupComplete.criticalExtensions.rrcSetupComplete.dedicatedNAS_Message; v_NoOfNasPdus := 1; } } else if (ischosen(v_RrcPdu.message_.c1.ulInformationTransfer)) { // UL INFORMATION TRANSFER if (ischosen(v_RrcPdu.message_.c1.ulInformationTransfer.criticalExtensions.ulInformationTransfer)) { v_ULInformationTransfer := v_RrcPdu.message_.c1.ulInformationTransfer.criticalExtensions.ulInformationTransfer; v_NAS_DedicatedMsg[0] := v_ULInformationTransfer.dedicatedNAS_Message; v_RrcPduPresent := false; v_NoOfNasPdus := 1; } } else if (ischosen(v_RrcPdu.message_.c1.rrcResumeComplete)) { // RRC RESUME COMPLETE if (ispresent(v_RrcPdu.message_.c1.rrcResumeComplete.criticalExtensions.rrcResumeComplete.dedicatedNAS_Message)) { // @sic R5s190214 sic@ v_NAS_DedicatedMsg[0] := v_RrcPdu.message_.c1.rrcResumeComplete.criticalExtensions.rrcResumeComplete.dedicatedNAS_Message; v_NoOfNasPdus := 1; } } else { // OTHER RRC PDU } } else { // c1 only option at the moment } if (v_RrcPduPresent) { v_SRB_COMMON_IND.Signalling.Rrc := v_RrcIndication; } if (v_NoOfNasPdus > 0) { for (I := 0; I < v_NoOfNasPdus; I := I + 1) { v_DecodingInfo := f_NG_DecipherAndDecodeNasPdu(p_NG_NasSecurityByRef, v_NAS_DedicatedMsg[I]); v_SRB_COMMON_IND.Signalling.Nas[I] := v_DecodingInfo.NasIndication; // omit if message cannot be decoded => shall lead to a test case error v_IntegrityError := v_IntegrityError or valueof(v_DecodingInfo.IntegrityError); // valueof cannot be avoided here } if (v_IntegrityError) { // set Error choice of common part only if there is an error if (ischosen(v_SRB_COMMON_IND.Common.Status.Error)) { /* there is already an error flagged by the SA */ v_SRB_COMMON_IND.Common.Status.Error.Integrity.Nas := true; } else { /* the error needs to be set */ v_SRB_COMMON_IND.Common.Status := cs_IndicationStatus_NasIntegrityError; } } } } TC_SRB.send(v_SRB_COMMON_IND); } } /* * @desc Handling of NAS integrity returning the calculated MAC * @param p_NasSecurityByRef (by reference) * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ altstep a_Check4GIntegrity (inout NG_NasSecurity_Type p_NasSecurityByRef) runs on NASEMU_NRNG_PTC { var NASEmu_CoOrd_REQ v_ReceivedMsg; var NasCount_Type v_CountUL; var MessageAuthenticationCode v_CalculatedMac; [] EPS.receive(cr_NASEmu_CoOrd_REQ) -> value v_ReceivedMsg { v_CountUL := f_NG_NasSecurity_EstimateCOUNT(p_NasSecurityByRef.NasCount.UL, v_ReceivedMsg.SequenceNumber); v_CalculatedMac := fx_NG_NasIntegrityAlgorithm(v_ReceivedMsg.IntegrityProtectedOctets, p_NasSecurityByRef.Integrity.Algorithm, p_NasSecurityByRef.Integrity.K_NAS, v_CountUL, p_NasSecurityByRef.BearerId, tsc_DirectionUL); EPS.send(cs_NASEmu_CoOrd_CNF (v_CalculatedMac)); } } //**************************************************************************** // Main Loop //---------------------------------------------------------------------------- /* * @desc NAS emulation main loop (started by the MTC) * @status APPROVED (IMS, NR5GC, NR5GC_IRAT, POS) */ function f_NASEMU_MainLoop_NRNG() runs on NASEMU_NRNG_PTC { var NG_NasSecurity_Type v_NG_NasSecurityByRef := f_NG_NasEmu_NasSecurity_Init(); while (true) { alt { [] a_NG_NasEmu_ConfigurationHandler(CTRL, v_NG_NasSecurityByRef); [] a_AspFromTestcaseHandler_NRNG(v_NG_NasSecurityByRef); [] a_AspFromSystemAdaptorHandler_NRNG(v_NG_NasSecurityByRef); [] a_Check4GIntegrity(v_NG_NasSecurityByRef); // @sic 5G Integrity in 4G sic@ [] any port.receive { f_NasEmulationError(__FILE__, __LINE__, "unexpected message (skipped)"); repeat; } } } } }