pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/40412?usp=email )
Change subject: 5gc: Initial NAS transmitting support ......................................................................
5gc: Initial NAS transmitting support
With this patch it is already possible to transmit the NAS Auth Response in the test ConnHdlr. We still lack generating a proper RES to have the response properly accepted.
Change-Id: I951e98217b0150eed58fabb8e50a4782c1a3b510 --- M 5gc/C5G_Tests.ttcn M library/NGAP_Emulation.ttcn M library/NGAP_Functions.ttcn M library/NG_NAS_Osmo_Templates.ttcn 4 files changed, 98 insertions(+), 48 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/12/40412/1
diff --git a/5gc/C5G_Tests.ttcn b/5gc/C5G_Tests.ttcn index 320d61f..9b45298 100644 --- a/5gc/C5G_Tests.ttcn +++ b/5gc/C5G_Tests.ttcn @@ -275,6 +275,12 @@ var template (present) NAS_KeySetIdentifier kset_id := f_tr_ConnHdlr_kset_id(); [] NGAP.receive(cr_NG_AUTHENTICATION_REQUEST) -> value rx_nas { log("Rx NAS message: ", rx_nas); + + g_pars.kset_id := rx_nas.authentication_Request.ngNasKeySetId; + + /* TODO: generate proper RES, 3GPP TS 33.501 A.4 */ + const OCT8 res := '6a91970e838fd079'O; + NGAP.send(cs_NG_AUTHENTICATION_RESPONSE(cs_AuthenticationResponseParameter(oct2bit(res)))); } }
@@ -284,14 +290,12 @@ var template (value) NG_NAS_UL_Message_Type nas_ul_msg; var NAS_PDU nas_pdu;
- p_ueLocInf := m_uPTransportLayerInformation_userLocationInformationNR( m_userLocationInformationNR( g_pars.ngran_pars[g_pars.c5g_idx].cell_identity.nR_CGI, ts_ngran_NGAP_TAI(g_pars.ngran_pars[g_pars.c5g_idx])
)); - nas_ul_msg := cs_NG_REGISTRATION_REQUEST(cs_RegistrationType(tsc_NG_RegistrationInitial, '1'B), g_pars.kset_id.nasKeySetId, g_pars.kset_id.tsc, @@ -299,17 +303,26 @@ f_SUCI_IMSI()), p_UESecurityCap := cs_NG_UE_SecurityCapability); nas_pdu := enc_NG_NAS_UL_Message_Type(valueof(nas_ul_msg)); - - tx_pdu := m_ngap_initMsg(m_n2_initialUeMessage(g_pars.c5g_idx, nas_pdu, /* Registration request */ p_ueLocInf, mo_Signalling)); - NGAP.send(tx_pdu); + + /* Expect updated KSI from network following 5G Core standards + *(open5gs.git 70310979c58fe186e9eaa06bec9d9a31f24ff7a1): */ + if (g_pars.kset_id.nasKeySetId != tsc_NasKsi_NoKey) { + if (g_pars.kset_id.nasKeySetId == '110'B) { + g_pars.kset_id.nasKeySetId := '000'B; + } else { + g_pars.kset_id.nasKeySetId := int2bit(bit2int(g_pars.kset_id.nasKeySetId) + 1, 3); + } + } + as_ngap_handle_auth();
/* TODO: handle Auth, SecurityModeCommand, InitialContextSetup, PDUSessionresource, */ + f_sleep(5.0); }
/* NG Setup procedure to 5GC using a Global gNB ID containing unknown/foreign PLMN. diff --git a/library/NGAP_Emulation.ttcn b/library/NGAP_Emulation.ttcn index 46f1d63..12487ae 100644 --- a/library/NGAP_Emulation.ttcn +++ b/library/NGAP_Emulation.ttcn @@ -144,9 +144,8 @@ type record AssociationData { NGAP_ConnHdlr comp_ref, /* component handling this UE connection */ uint32_t ran_ue_ngap_id optional, /* eNB side NGAP ID */ - uint40_t amf_ue_ngap_id optional//, /* AMF side NGAP ID */ - //EUTRAN_CGI cgi optional, - //TAI tai optional, + uint40_t amf_ue_ngap_id optional, /* AMF side NGAP ID */ + UserLocationInformation uli optional //NAS_UE_State nus };
@@ -329,8 +328,7 @@ for (var integer i := 0; i < sizeof(NGapAssociationTable); i := i+1) { NGapAssociationTable[i].amf_ue_ngap_id := omit; NGapAssociationTable[i].ran_ue_ngap_id := omit; - //NGapAssociationTable[i].cgi := omit; - //NGapAssociationTable[i].tai := omit; + NGapAssociationTable[i].uli := omit; //NGapAssociationTable[i].nus := valueof(t_NAS_UE_State(g_pars.role)); NGapAssociationTable[i].comp_ref := null; } @@ -356,26 +354,27 @@ }
function handle_NGAP_UeContextReleaseCmd(template (present) NGAP_PDU rel_cmd) runs on NGAP_Emulation_CT { -// if (ispresent(rel_cmd.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair)) { -// var template AMF_UE_NGAP_ID amf_ue_id; -// var template RAN_UE_NGAP_ID ran_ue_id; -// var integer assoc_id; -// var NGAP_ConnHdlr vc_conn -// -// amf_ue_id := rel_cmd.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair.mME_UE_NGAP_ID; -// ran_ue_id := rel_cmd.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair.eNB_UE_NGAP_ID; -// -// assoc_id := f_assoc_id_by_ngap_ids(amf_ue_id, ran_ue_id); -// vc_conn := NGapAssociationTable[assoc_id].comp_ref; -// -// f_ngap_id_table_del(vc_conn, valueof(ran_ue_id)); -// } else { -// /* TODO: The UE CONTEXT RELEASE COMMAND (see also: 3GPP TS 36.413, section 9.1.4.6), may identify the -// * context by either an uE_NGAP_ID_pair (AMF_UE_NGAP_ID and RAN_UE_NGAP_ID) or an AMF_UE_NGAP_ID alone. -// * The latter case is not implemented here yet. */ -// setverdict(fail, "complete implementation of UeContextReleaseCmd handling"); -// mtc.stop; -// } + if (ispresent(rel_cmd.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair)) { + var UE_NGAP_ID_pair ids := valueof(rel_cmd.initiatingMessage.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair); + var template AMF_UE_NGAP_ID amf_ue_id; + var template RAN_UE_NGAP_ID ran_ue_id; + var integer assoc_id; + var NGAP_ConnHdlr vc_conn + + amf_ue_id := ids.aMF_UE_NGAP_ID; + ran_ue_id := ids.rAN_UE_NGAP_ID; + + assoc_id := f_assoc_id_by_ngap_ids(amf_ue_id, ran_ue_id); + vc_conn := NGapAssociationTable[assoc_id].comp_ref; + + f_ngap_id_table_del(vc_conn, valueof(ran_ue_id)); + } else { + /* TODO: The UE CONTEXT RELEASE COMMAND (see also: 3GPP TS 36.413, section 9.1.4.6), may identify the + * context by either an uE_NGAP_ID_pair (AMF_UE_NGAP_ID and RAN_UE_NGAP_ID) or an AMF_UE_NGAP_ID alone. + * The latter case is not implemented here yet. */ + setverdict(fail, "complete implementation of UeContextReleaseCmd handling"); + mtc.stop; + } }
private function SendToNGapExpectTableProc(NGAP_PDU msg) runs on NGAP_Emulation_CT { @@ -446,7 +445,7 @@
while (true) { var NGAP_ConnHdlr vc_conn; - //var PDU_NAS_EPS nas; + var NG_NAS_UL_Message_Type ul_nas_msg; var AMF_UE_NGAP_ID amf_id; var RAN_UE_NGAP_ID ran_id; var integer procedureCode; @@ -461,12 +460,24 @@ [] NGAP_CLIENT.receive(mw_ngap_initMsg(mw_n2_initialUeMessage)) -> value msg sender vc_conn { /* create a table entry about this connection */ ai := f_ngap_id_table_add(vc_conn, omit, valueof(f_NGAP_get_RAN_UE_NGAP_ID(msg))); - /* Store CGI + TAI so we can use it for generating UlNasTransport from NAS */ -// NGapAssociationTable[ai].tai := msg.initiatingMessage.value_.InitialUEMessage.protocolIEs[2].value_.TAI; -// NGapAssociationTable[ai].cgi := msg.initiatingMessage.value_.InitialUEMessage.protocolIEs[3].value_.EUTRAN_CGI; + /* Store ULI so we can use it for generating UlNasTransport from NAS */ + NGapAssociationTable[ai].uli := msg.initiatingMessage.value_.InitialUEMessage.protocolIEs[2].value_.userLocationInformation; // /* Pass message through */ NGAP.send(t_NGAP_Send(g_ngap_conn_id, msg)); } + /* NAS from client: Wrap in NGAP Uplink NAS Transport */ + [] NGAP_CLIENT.receive(NG_NAS_UL_Message_Type:?) -> value ul_nas_msg sender vc_conn { + var integer assoc_id := f_assoc_id_by_comp(vc_conn); + var AssociationData ad := NGapAssociationTable[assoc_id]; + //ul_nas_msg := f_nas_encaps(NGapAssociationTable[assoc_id].nus, ul_nas_msg); + var NAS_PDU nas_enc := enc_NG_NAS_UL_Message_Type(ul_nas_msg); + NGAP.send(t_NGAP_Send(g_ngap_conn_id, + m_ngap_initMsg( + m_n2_UplinkNASTransport(ad.amf_ue_ngap_id, + ad.ran_ue_ngap_id, + nas_enc, + ad.uli)))); + } /* NGAP from client: pass on transparently */ [] NGAP_CLIENT.receive(NGAP_PDU:?) -> value msg sender vc_conn { /* Pass message through */ diff --git a/library/NGAP_Functions.ttcn b/library/NGAP_Functions.ttcn index 1323ab9..70d8941 100644 --- a/library/NGAP_Functions.ttcn +++ b/library/NGAP_Functions.ttcn @@ -25,10 +25,8 @@ case (mw_n2_DownlinkNASTransport) { return im.value_.downlinkNASTransport.protocolIEs[0].value_.aMF_UE_NGAP_ID; } - case (?) { - return omit; - /* TODO */ - /* return im.value_.InitialUEMessage.protocolIEs[0].value_.AMF_UE_NGAP_ID; */ + case (mw_n2_UEContextReleaseCommand) { + return im.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair.aMF_UE_NGAP_ID; } /* TODO */ } @@ -67,6 +65,9 @@ case (mw_n2_DownlinkNASTransport) { return im.value_.downlinkNASTransport.protocolIEs[1].value_.RAN_UE_NGAP_ID; } + case (mw_n2_UEContextReleaseCommand) { + return im.value_.uEContextReleaseCommand.protocolIEs[0].value_.uE_NGAP_IDs.uE_NGAP_ID_pair.rAN_UE_NGAP_ID; + } /* TODO */ } } else if (ischosen(ngap.successfulOutcome)) { diff --git a/library/NG_NAS_Osmo_Templates.ttcn b/library/NG_NAS_Osmo_Templates.ttcn index a22c542..1108947 100644 --- a/library/NG_NAS_Osmo_Templates.ttcn +++ b/library/NG_NAS_Osmo_Templates.ttcn @@ -31,10 +31,11 @@ } return len; } -template (value) NG_UE_SecurityCapability cs_NG_UE_SecurityCapability(template (value) O1_Type ngeaCap := 'f0'O, - template (value) O1_Type ngiaCap := '70'O, - template (omit) O1_Type eeaCap := omit, - template (omit) O1_Type eiaCap := omit) := +template (value) NG_UE_SecurityCapability +cs_NG_UE_SecurityCapability(template (value) O1_Type ngeaCap := 'f0'O, + template (value) O1_Type ngiaCap := '70'O, + template (omit) O1_Type eeaCap := omit, + template (omit) O1_Type eiaCap := omit) := { iei := '2E'O, iel := int2oct(f_cs_NG_UE_SecurityCapability_length(eeaCap, eiaCap), 1), @@ -45,14 +46,23 @@ spare := omit };
+template (value) AuthenticationResponseParameter +cs_AuthenticationResponseParameter(template (value) B32_128_Type p_ExpectedRES) := +{ + iei := '2D'O, + iel := int2oct(lengthof(bit2oct(valueof(p_ExpectedRES))), 1), + res := p_ExpectedRES +} +
/* 24.501 cl. 8.2.1 */ -template (present) NG_NAS_DL_Message_Type cr_NG_AUTHENTICATION_REQUEST(template (present) NAS_KsiValue p_KeySetId := ?, - template (present) ABBA p_ABBA := ?, - template RAND p_RAND := *, - template AUTN p_AUTN := *, - template EAP_Message p_EAP := * - ) := +template (present) NG_NAS_DL_Message_Type +cr_NG_AUTHENTICATION_REQUEST(template (present) NAS_KsiValue p_KeySetId := ?, + template (present) ABBA p_ABBA := ?, + template RAND p_RAND := *, + template AUTN p_AUTN := *, + template EAP_Message p_EAP := * + ) := { /* 24.501 cl. 8.2.1 */ authentication_Request := { protocolDiscriminator := tsc_EPD_GMM, /* cl. 9.2 M V 1 */ @@ -68,4 +78,19 @@ } }
+/* 24.501 cl. 8.2.2 */ +template (value) NG_NAS_UL_Message_Type +cs_NG_AUTHENTICATION_RESPONSE(template (value) AuthenticationResponseParameter p_Res, + template (omit) EAP_Message p_EAP := omit) := +{ + authentication_Response := { + protocolDiscriminator := tsc_EPD_GMM, /* cl. 9.2 M V 1 */ + spareHalfOctet := tsc_SpareHalfOctet, /* cl. 9.3 M V 1/2 */ + securityHeaderType := tsc_SHT_NoSecurityProtection, + messageType := tsc_MT_NG_AuthenticationResponse, /* cl. 9.7 M V 1 */ + authResponseParam := p_Res, /* cl. 9.11.3.17 O TLV 18 IEI=2D */ + eapMessage := p_EAP /* cl. 9.11.2.2 O TLV-E 7-1503 IEI=78 */ +} +} + }