Commit 03a4d8ef authored by Guido Casati's avatar Guido Casati

Refactor NAS 5GS (5GMM & 5GSM) structs definitions and their use

Every NAS 5GS message can have 3 different headers: (1) security protected
(2) 5GMM plain (3) 5GS plain;

According to 3GPP TS 24.501:
> 4.2 Coordination between the protocols for 5GS mobility management and 5GS session management
> A 5GS session management (5GSM) message is piggybacked in specific 5GS mobility management (5GMM) transport
> messages. To this purpose, the 5GSM messages can be transmitted in an information element in the 5GMM transport
> messages.

A PDU Session Establishment accept is a 5GSM message and as such it is contained in a 5GMM
transport message. The code in capture_pdu_session_establishment_accept_msg is reflecting this.
The message is thus expected to have: (1) Security protected 5GMM header (2) Plain 5GMM message
(3) 5GSM Payload Container (4) Plain 5GSM message.

5.4.5 of 3GPP TS 24.501: also says:

> The type of the payload is identified by the Payload container type IE and includes one of the following: a) a single 5GSM message;

Thus, a 5GSM is not the only possible payload of a NAS transport message.

This commit is focusing on the refactoring of the structs definitions and adaptation of the CMakeLists.

Based on the above:

* Move NR_NAS_defs.h to 5GS subfolder in NR_UE
* Move NAS FGS structs and definitions to NR_NAS_defs.h
* Rename mm_msg_header_t to fgmm_msg_header_t
* Remove duplicated NAS struct definitions
  (1) kept fgs_nas_message_security_header_t over security_protected_nas_5gs_msg_t
  (2) Kept fgsm_msg_header_t over fgs_sm_nas_msg_header_t
* Remove unused definitions, structs, functions in the process
parent c0583be2
......@@ -22,7 +22,7 @@
*/
#include <arpa/inet.h>
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
#include "openair3/NAS/NR_UE/5GS/NR_NAS_defs.h"
#include <openair3/SECU/secu_defs.h>
#include <openair3/SECU/kdf.h>
......
......@@ -10,4 +10,4 @@ add_library(fgs_5gmm_lib OBJECT
FGSDeregistrationRequestUEOriginating.c
)
target_include_directories(fgs_5gmm_lib PUBLIC . ../IES)
target_include_directories(fgs_5gmm_lib PUBLIC . ../IES ../../)
add_library(fgs_5gsm_lib OBJECT PduSessionEstablishRequest.c
PduSessionEstablishmentAccept.c)
target_include_directories(fgs_5gsm_lib PUBLIC .)
target_include_directories(fgs_5gsm_lib PUBLIC . ../../)
......@@ -61,28 +61,32 @@ static int capture_ipv6_addr(const uint8_t *addr, char *ip, size_t len)
*/
void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length)
{
security_protected_nas_5gs_msg_t sec_nas_hdr;
security_protected_plain_nas_5gs_msg_t sec_nas_msg;
fgs_nas_message_security_header_t sec_nas_hdr;
pdu_session_establishment_accept_msg_t psea_msg;
uint8_t *curPtr = buffer;
sec_nas_hdr.epd = *curPtr++;
sec_nas_hdr.sht = *curPtr++;
// Security protected NAS header (7 bytes)
sec_nas_hdr.protocol_discriminator = *curPtr++;
sec_nas_hdr.security_header_type = *curPtr++;
uint32_t tmp;
memcpy(&tmp, buffer, sizeof(tmp));
sec_nas_hdr.mac = htonl(tmp);
curPtr += sizeof(sec_nas_hdr.mac);
sec_nas_hdr.sqn = *curPtr++;
sec_nas_msg.epd = *curPtr++;
sec_nas_msg.sht = *curPtr++;
sec_nas_msg.msg_type = *curPtr++;
sec_nas_msg.payload_type = *curPtr++;
sec_nas_msg.payload_len = getShort(curPtr);
curPtr += sizeof(sec_nas_msg.payload_len);
sec_nas_hdr.message_authentication_code = htonl(tmp);
curPtr += sizeof(sec_nas_hdr.message_authentication_code);
sec_nas_hdr.sequence_number = *curPtr++;
// Security protected plain NAS message
fgmm_msg_header_t header;
header.ex_protocol_discriminator = *curPtr++;
header.security_header_type = *curPtr++;
header.message_type = *curPtr++;
// Payload container type and spare (1 octet)
curPtr++;
// Payload container length
curPtr += sizeof(getShort(curPtr));
/* Mandatory Presence IEs */
psea_msg.epd = *curPtr++;
psea_msg.pdu_id = *curPtr++;
psea_msg.pti = *curPtr++;
psea_msg.msg_type = *curPtr++;
fgsm_msg_header_t *sm_header = &psea_msg.header;
sm_header->ex_protocol_discriminator = *curPtr++;
sm_header->pdu_session_id = *curPtr++;
sm_header->pti = *curPtr++;
sm_header->message_type = *curPtr++;
psea_msg.pdu_type = *curPtr & 0x0f;
psea_msg.ssc_mode = (*curPtr++ & 0xf0) >> 4;
psea_msg.qos_rules.length = getShort(curPtr);
......
......@@ -147,10 +147,7 @@ typedef struct qos_fd_s {
typedef struct pdu_session_establishment_accept_msg_s {
/* Mandatory presence */
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t pdu_id; /* PDU Session ID */
uint8_t pti; /* Procedure Transaction Identity */
uint8_t msg_type; /* Message Type */
fgsm_msg_header_t header;
uint8_t pdu_type; /* PDU Session Type */
uint8_t ssc_mode; /* SSC mode */
auth_qos_rule_t qos_rules; /* Authorized QoS rules */
......@@ -163,21 +160,6 @@ typedef struct pdu_session_establishment_accept_msg_s {
qos_fd_t qos_fd_ie; /* QoS flow descriptions */
} pdu_session_establishment_accept_msg_t; /* 24.501 Table 8.3.2.1.1 */
typedef struct security_protected_plain_nas_5gs_msg_s {
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t sht; /* Security Header Type */
uint8_t msg_type; /* Message Type */
uint8_t payload_type; /* Payload Container Type */
uint16_t payload_len; /* Payload Container Length */
} security_protected_plain_nas_5gs_msg_t;
typedef struct security_protected_nas_5gs_msg_s {
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t sht; /* Security Header Type */
uint32_t mac; /* Message Authentication Code */
uint8_t sqn; /* Sequence Number */
} security_protected_nas_5gs_msg_t; /* 24.501 Figure 9.1.1.2 */
void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length);
#endif
......@@ -9,8 +9,6 @@
*
* http://www.openairinterface.org/?page_id=698
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* 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.
......@@ -20,23 +18,12 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef NR_NAS_DEFS_H
#define NR_NAS_DEFS_H
#include <common/utils/LOG/log.h>
#include <openair3/UICC/usim_interface.h>
/* TS 24.007 possible L3 formats:
Table 11.1: Formats of information elements
Format Meaning IEI present LI present Value part present
T Type only yes no no
V Value only no no yes
TV Type and Value yes no yes
LV Length and Value no yes yes
TLV Type, Length and Value yes yes yes
LV-E Length and Value no yes yes
TLV-E Type, Length and Value yes yes yes
*/
#include <stdint.h>
#include "openair3/UICC/usim_interface.h"
/* Map task id to printable name. */
typedef struct {
......@@ -44,24 +31,9 @@ typedef struct {
char text[256];
} text_info_t;
static inline const char * idToText(const text_info_t* table, int size, int id) {
for(int i=0; i<size; i++)
if (table[i].id==id)
return table[i].text;
LOG_E(NAS,"impossible id %x\n", id);
return "IMPOSSIBLE";
}
#define idStr(TaBle, iD) idToText(TaBle, sizeof(TaBle)/sizeof(text_info_t), iD)
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
#define TO_ENUM(LabEl, nUmID ) LabEl = nUmID,
//TS 24.501, chap 9.2 => TS 24.007
typedef enum {
SGSsessionmanagementmessages=0x2e, //LTEbox: 0xC0 ???
SGSmobilitymanagementmessages=0x7e,
} Extendedprotocoldiscriminator_t;
#define FOREACH_TYPE(TYPE_DEF) \
TYPE_DEF(REGISTRATION_REQUEST, 0x41) \
TYPE_DEF(REGISTRATION_ACCEPT, 0x42) \
......@@ -130,17 +102,6 @@ typedef enum {
INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX = 4,
} Security_header_t;
typedef enum {
SUCI=1,
SGGUTI,
IMEI,
SGSTMSI,
IMEISV,
MACaddress,
EUI64,
} identitytype_t;
// table 9.11.3.2.1
#define FOREACH_CAUSE(CAUSE_DEF) \
CAUSE_DEF(Illegal_UE,0x3 )\
......@@ -187,7 +148,6 @@ typedef enum {
CAUSE_DEF(Protocol_error_unspecified,0x67 )
/* Map task id to printable name. */
#define CAUSE_TEXT(LabEl, nUmID) {nUmID, #LabEl},
static const text_info_t cause_text_info[] = {
......@@ -255,132 +215,52 @@ typedef enum {
FOREACH_CAUSE_SECU(TO_ENUM)
} cause_secu_id_t;
// IEI (information element identifier) are spread in each message definition
// IEIs (Information Element Identifier)
#define IEI_NULL 0x00
#define IEI_RAND 0x21
#define IEI_AUTN 0x20
#define IEI_EAP 0x78
#define IEI_AuthenticationResponse 0x2d
//TS 24.501 sub layer states for UE
// for network side, only 5GMMderegistered, 5GMMderegistered_initiated, 5GMMregistered, 5GMMservice_request_initiated are valid
typedef enum {
SGMMnull,
SGMMderegistered,
SGMMderegistered_initiated,
SGMMregistered,
SGMMregistered_initiated,
SGMMservice_request_initiated,
} SGMM_UE_states;
/**
* Security protected 5GS NAS message header (9.1.1 of 3GPP TS 24.501)
* either 5GMM or 5GSM
* Standard L3 message header (11.2.3.1 of 3GPP TS 24.007)
*/
typedef struct {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
} SGScommonHeader_t;
// Extended Protocol Discriminator
uint8_t protocol_discriminator;
// Security Header Type
uint8_t security_header_type;
// Message Authentication Code
uint32_t message_authentication_code;
// Sequence Number
uint8_t sequence_number;
} __attribute__((packed)) fgs_nas_message_security_header_t;
/// 5GMM - 5GS mobility management
/**
* Header of a plain 5GMM NAS message (5GS)
* Standard L3 message header (11.2.3.1 of 3GPP TS 24.007)
*/
typedef struct {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
identitytype_t it:8;
} Identityrequest_t;
// the message continues with the identity value, depending on identity type, see TS 14.501, 9.11.3.4
typedef struct __attribute__((packed)) {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
uint16_t len;
}
Identityresponse_t;
typedef struct __attribute__((packed)) {
Identityresponse_t common;
identitytype_t mi:8;
unsigned int supiFormat:4;
unsigned int identityType:4;
unsigned int mcc1:4;
unsigned int mcc2:4;
unsigned int mcc3:4;
unsigned int mnc3:4;
unsigned int mnc1:4;
unsigned int mnc2:4;
unsigned int routing1:4;
unsigned int routing2:4;
unsigned int routing3:4;
unsigned int routing4:4;
unsigned int protectScheme:4;
unsigned int spare:4;
uint8_t hplmnId;
}
IdentityresponseIMSI_t;
typedef struct __attribute__((packed)) {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
unsigned int ngKSI:4;
unsigned int spare:4;
unsigned int ABBALen:8;
unsigned int ABBA:16;
uint8_t ieiRAND;
uint8_t RAND[16];
uint8_t ieiAUTN;
uint8_t AUTNlen;
uint8_t AUTN[16];
}
authenticationrequestHeader_t;
typedef struct __attribute__((packed)) {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
uint8_t iei;
uint8_t RESlen;
uint8_t RES[16];
} authenticationresponse_t;
//AUTHENTICATION RESULT
typedef struct __attribute__((packed)) {
Extendedprotocoldiscriminator_t epd:8;
Security_header_t sh:8;
SGSmobilitymanagementmessages_t mt:8;
uint8_t ex_protocol_discriminator;
uint8_t security_header_type;
uint8_t message_type;
} fgmm_msg_header_t;
unsigned int selectedNASsecurityalgorithms;
unsigned int ngKSI:4; //ngKSI NAS key set identifier 9.11.3.32
unsigned int spare:4;
// LV 3-9 bytes Replayed UE security capabilities UE security capability 9.11.3.54
/// 5GSM - 5GS session management
/* optional
TV (E-, 1 byte) Oprional IMEISV request IMEISV request 9.11.3.28
TV (57, 2 bytes ) Selected EPS NAS security algorithms EPS NAS security algorithms 9.11.3.25
TLV (36, 3 bytes) Additional 5G security information Additional 5G security information 9.11.3.12
TLV-E (78,, 7-1503 bytes) EAP message EAP message 9.11.2.2
TLV (38, 4-n)ABBA ABBA 9.11.3.10
TLV (19, 4-7) Replayed S1 UE security capabilities S1 UE security capability 9.11.3.48A
/**
* Header of a plain 5GSM NAS message (5GS)
* Standard L3 message header (11.2.3.1 of 3GPP TS 24.007)
*/
} securityModeCommand_t;
typedef struct __attribute__((packed)) {
Extendedprotocoldiscriminator_t epd: 8;
Security_header_t sh: 8;
SGSmobilitymanagementmessages_t mt: 8;
} deregistrationRequestUEOriginating_t;
typedef struct {
uicc_t *uicc;
} nr_user_nas_t;
#define STATIC_ASSERT(test_for_true) _Static_assert((test_for_true), "(" #test_for_true ") failed")
#define myCalloc(var, type) type * var=(type*)calloc(sizeof(type),1);
#define arrayCpy(tO, FroM) STATIC_ASSERT(sizeof(tO) == sizeof(FroM)) ; memcpy(tO, FroM, sizeof(tO))
int resToresStar(uint8_t *msg, const uicc_t* uicc);
int identityResponse(void **msg, nr_user_nas_t *UE);
int authenticationResponse(void **msg, nr_user_nas_t *UE);
void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size);
#endif
// Extended protocol discriminator
uint8_t ex_protocol_discriminator;
// PDU session identity
uint8_t pdu_session_id;
// Procedure transaction identity
uint8_t pti;
// Message type
uint8_t message_type;
} fgsm_msg_header_t;
#endif // NR_NAS_DEFS_H
......@@ -16,4 +16,5 @@ target_link_libraries(nr_nas PUBLIC
target_include_directories(nr_nas PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/5GS
)
......@@ -150,12 +150,12 @@ static int nas_protected_security_header_encode(char *buffer, const fgs_nas_mess
LOG_FUNC_RETURN(size);
}
static int _nas_mm_msg_encode_header(const mm_msg_header_t *header, uint8_t *buffer, uint32_t len)
static int _nas_mm_msg_encode_header(const fgmm_msg_header_t *header, uint8_t *buffer, uint32_t len)
{
int size = 0;
/* Check the buffer length */
if (len < sizeof(mm_msg_header_t)) {
if (len < sizeof(fgmm_msg_header_t)) {
return (TLV_ENCODE_BUFFER_TOO_SHORT);
}
......@@ -510,7 +510,7 @@ nr_ue_nas_t *get_ue_nas_info(module_id_t module_id)
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
{
int size = sizeof(mm_msg_header_t);
int size = sizeof(fgmm_msg_header_t);
fgs_nas_message_t nas_msg = {0};
MM_msg *mm_msg;
......@@ -590,7 +590,7 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
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_SERVICE_REQUEST;
size += sizeof(mm_msg_header_t);
size += sizeof(mm_msg->header);
// Fill Service Request
// Service Type
......@@ -645,7 +645,7 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t *uicc)
{
int size = sizeof(mm_msg_header_t);
int size = sizeof(fgmm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
......@@ -681,7 +681,7 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN
res.value = calloc(1, 16);
memcpy(res.value, nas->security.res, 16);
int size = sizeof(mm_msg_header_t);
int size = sizeof(fgmm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
MM_msg *mm_msg;
......@@ -721,7 +721,7 @@ int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32])
static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg)
{
int size = sizeof(mm_msg_header_t);
int size = sizeof(fgmm_msg_header_t);
fgs_nas_message_t nas_msg;
memset(&nas_msg, 0, sizeof(fgs_nas_message_t));
......@@ -964,7 +964,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
sp_msg->header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED;
sp_msg->header.message_authentication_code = 0;
sp_msg->header.sequence_number = nas->security.nas_count_ul & 0xff;
int size = sizeof(fgs_nas_message_security_header_t);
int size = sizeof(sp_msg->header);
fgs_deregistration_request_ue_originating_msg *dereg_req = &sp_msg->plain.mm_msg.fgs_deregistration_request_ue_originating;
dereg_req->protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
......
......@@ -42,6 +42,7 @@
#include "FGSUplinkNasTransport.h"
#include <openair3/UICC/usim_interface.h>
#include "secu_defs.h"
#include "NR_NAS_defs.h"
#define INITIAL_REGISTRATION 0b001
......@@ -94,22 +95,8 @@ typedef enum fgs_protocol_discriminator_e {
FGS_SESSION_MANAGEMENT_MESSAGE = 0x2E,
} fgs_protocol_discriminator_t;
typedef struct {
uint8_t ex_protocol_discriminator;
uint8_t security_header_type;
uint8_t message_type;
} mm_msg_header_t;
/* Structure of security protected header */
typedef struct {
uint8_t protocol_discriminator;
uint8_t security_header_type;
uint32_t message_authentication_code;
uint8_t sequence_number;
} fgs_nas_message_security_header_t;
typedef union {
mm_msg_header_t header;
fgmm_msg_header_t header;
registration_request_msg registration_request;
fgs_service_request_msg_t service_request;
fgs_identiy_response_msg fgs_identity_response;
......@@ -137,7 +124,7 @@ typedef union {
typedef struct {
union {
mm_msg_header_t plain_nas_msg_header;
fgmm_msg_header_t plain_nas_msg_header;
struct security_protected_nas_msg_header_s {
uint8_t ex_protocol_discriminator;
uint8_t security_header_type;
......@@ -148,20 +135,6 @@ typedef struct {
} choice;
} nas_msg_header_t;
typedef struct {
uint8_t ex_protocol_discriminator;
uint8_t pdu_session_id;
uint8_t PTI;
uint8_t message_type;
} fgs_sm_nas_msg_header_t;
typedef struct {
mm_msg_header_t plain_nas_msg_header;
uint8_t payload_container_type;
uint16_t payload_container_length;
fgs_sm_nas_msg_header_t sm_nas_msg_header;
} dl_nas_transport_t;
nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);
void generateRegistrationRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas);
......
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