From 6e01a628384a450beaad4d1e65275dd5fd78f4f4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 13 Mar 2023 12:30:59 +0100 Subject: [PATCH] Decode Registration Accept to receive GUTI --- .../NAS/COMMON/EMM/MSG/RegistrationAccept.c | 17 ++++++++++++ .../NAS/COMMON/EMM/MSG/RegistrationAccept.h | 4 +++ openair3/NAS/NR_UE/nr_nas_msg_sim.c | 26 +++++++++++++++++++ openair3/NAS/NR_UE/nr_nas_msg_sim.h | 1 + 4 files changed, 48 insertions(+) diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c index d8fde7e2cc..c34d777bd5 100644 --- a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.c @@ -50,6 +50,16 @@ int decode_registration_accept(registration_accept_msg *registration_accept, uin decoded += decoded_result; + if (decoded < len && buffer[decoded] == 0x77) { + registration_accept->guti = calloc(1, sizeof(*registration_accept->guti)); + if (!registration_accept->guti) + return -1; + int mi_dec = decode_5gs_mobile_identity(registration_accept->guti, 0x77, buffer + decoded, len - decoded); + if (mi_dec < 0) + return -1; + decoded += mi_dec; + } + // todo ,Decoding optional fields return decoded; } @@ -64,6 +74,13 @@ int encode_registration_accept(registration_accept_msg *registration_accept, uin *(buffer + encoded) = encode_fgs_registration_result(®istration_accept->fgsregistrationresult); encoded = encoded + 2; + if (registration_accept->guti) { + int mi_enc = encode_5gs_mobile_identity(registration_accept->guti, 0x77, buffer + encoded, len - encoded); + if (mi_enc < 0) + return mi_enc; + encoded += mi_enc; + } + // todo ,Encoding optional fields LOG_FUNC_RETURN(encoded); } diff --git a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h index 08daec2646..e0d3ade23a 100644 --- a/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h +++ b/openair3/NAS/COMMON/EMM/MSG/RegistrationAccept.h @@ -38,6 +38,7 @@ #include "SpareHalfOctet.h" #include "MessageType.h" #include "FGSRegistrationResult.h" +#include "FGSMobileIdentity.h" #ifndef REGISTRATION_ACCEPT_H_ #define REGISTRATION_ACCEPT_H_ @@ -56,6 +57,9 @@ typedef struct registration_accept_msg_tag { SpareHalfOctet sparehalfoctet:4; MessageType messagetype; FGSRegistrationResult fgsregistrationresult; + + /* Optional fields */ + FGSMobileIdentity *guti; } registration_accept_msg; int decode_registration_accept(registration_accept_msg *registrationaccept, uint8_t *buffer, uint32_t len); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index d415242324..443fb8d06c 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -42,6 +42,7 @@ #include "kdf.h" #include "PduSessionEstablishRequest.h" #include "PduSessionEstablishmentAccept.h" +#include "RegistrationAccept.h" #include "intertask_interface.h" #include "openair2/RRC/NAS/nas_config.h" #include @@ -613,6 +614,30 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia } } +static void decodeRegistrationAccept(uint8_t *buf, int len, nr_ue_nas_t *nas) +{ + registration_accept_msg reg_acc = {0}; + /* it seems there is no 5G corresponding emm_msg_decode() function, so here + * we just jump to the right decision */ + buf += 7; /* skip security header */ + buf += 2; /* skip prot discriminator, security header, half octet */ + AssertFatal(*buf == 0x42, "this is not a NAS Registration Accept\n"); + buf++; + int decoded = decode_registration_accept(®_acc, buf, len); + AssertFatal(decoded > 0, "could not decode registration accept\n"); + if (reg_acc.guti) { + AssertFatal(reg_acc.guti->guti.typeofidentity == FGS_MOBILE_IDENTITY_5G_GUTI, + "registration accept 5GS Mobile Identity is not GUTI, but %d\n", + reg_acc.guti->guti.typeofidentity); + nas->guti = malloc(sizeof(nas->guti)); + AssertFatal(nas->guti, "out of memory\n"); + *nas->guti = reg_acc.guti->guti; + free(reg_acc.guti); /* no proper memory management for NAS decoded messages */ + } else { + LOG_W(NAS, "no GUTI in registration accept\n"); + } +} + static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer) { //wait send RRCReconfigurationComplete and InitialContextSetupResponse @@ -909,6 +934,7 @@ void *nas_nrue_task(void *args_p) if (msg_type == REGISTRATION_ACCEPT) { LOG_I(NAS, "[UE] Received REGISTRATION ACCEPT message\n"); + decodeRegistrationAccept(pdu_buffer, NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length, nas); as_nas_info_t initialNasMsg; memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 8ca655ad9d..86cc4f856d 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -84,6 +84,7 @@ typedef struct { typedef struct { uicc_t *uicc; ue_sa_security_key_t security; + Guti5GSMobileIdentity_t *guti; } nr_ue_nas_t; typedef enum fgs_protocol_discriminator_e {