Commit 2d755988 authored by Guido Casati's avatar Guido Casati

Initial separation of enc/dec functions from handlers/callbacks

* move enc/dec definitions to NR_NAS_defs.h and add new lib file nr_fgs_nas_lib.c
  both used by nr_nas_msg.c
* move utility macros to fgs_nas_utils.h: this can be used in all the 5GMM, 5GSM lib files
* use nr_nas_msg.c for handlers/callbacks only, it should call the enc/dec
  functions in nr_fgs_nas_lib and in the 5GMM, 5GSM libs
* 5GMM, 5GSM libs should only do the enc/dec of the NAS message contents
parent f73579ea
......@@ -3,6 +3,4 @@ add_library(nas_common_ies_lib OBJECT
NasKeySetIdentifier.c
)
target_include_directories(nas_common_ies_lib PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(nas_common_ies_lib PUBLIC .)
......@@ -7,3 +7,7 @@ add_library(fgs_5gmm_ies_lib OBJECT
FGCNasMessageContainer.c
SORTransparentContainer.c
)
target_link_libraries(fgs_5gmm_ies_lib PUBLIC
nas_common_ies_lib
)
......@@ -10,4 +10,6 @@ add_library(fgs_5gmm_lib OBJECT
FGSDeregistrationRequestUEOriginating.c
)
target_include_directories(fgs_5gmm_lib PUBLIC . ../IES ../../)
target_link_libraries(fgs_5gmm_lib PUBLIC fgs_5gmm_ies_lib)
target_include_directories(fgs_5gmm_lib PRIVATE ../IES/ ../../)
......@@ -28,9 +28,10 @@
*/
#include "FGSDeregistrationRequestUEOriginating.h"
#include "NR_NAS_defs.h"
#include <stdint.h>
#define IEI_NULL 0x00
int encode_fgs_deregistration_request_ue_originating(fgs_deregistration_request_ue_originating_msg *drr,
uint8_t *buffer,
uint32_t len)
......
......@@ -28,11 +28,12 @@
*/
#include "RegistrationRequest.h"
#include "NR_NAS_defs.h"
#include <stdint.h>
#include "T.h"
#include "nas_log.h"
#define IEI_NULL 0x00
int decode_registration_request(registration_request_msg *registration_request, uint8_t *buffer, uint32_t len)
{
uint32_t decoded = 0;
......
......@@ -30,10 +30,10 @@
#include "FGSMobileIdentity.h"
#include "NasKeySetIdentifier.h"
#include "ServiceType.h"
#include "NR_NAS_defs.h"
#define LEN_FGS_MOBILE_ID_CONTENTS_SIZE 2 // octets
#define MIN_LEN_FGS_SERVICE_REQUEST 10 // octets
#define IEI_NULL 0x00
/**
* @brief Encode 5GMM NAS Service Request message (8.2.16 of 3GPP TS 24.501)
......
add_library(fgs_5gsm_lib OBJECT PduSessionEstablishRequest.c
PduSessionEstablishmentAccept.c)
target_include_directories(fgs_5gsm_lib PUBLIC . ../../)
target_link_libraries(fgs_5gsm_lib PUBLIC nas_common_ies_lib)
target_include_directories(fgs_5gsm_lib PUBLIC .
../../5GMM/MSG # NOTE: to be removed in a later commit
../../5GMM/IES # NOTE: to be removed in a later commit
../../
)
......@@ -23,7 +23,8 @@
#define PDU_SESSION_ESTABLISHMENT_ACCEPT_H_
#include <stdint.h>
#include "NR_NAS_defs.h"
#include "fgs_nas_utils.h"
#include "NR_NAS_defs.h" // TEMP: to be removed in later commit
/* PDU Session Establish Accept Optional IE Identifiers - TS 24.501 Table 8.3.2.1.1 */
......
......@@ -5,3 +5,13 @@ add_subdirectory(5GSM/MSG)
if(ENABLE_TESTS)
add_subdirectory(tests)
endif()
add_library(fgs_lib fgs_nas_lib.c)
target_link_libraries(fgs_lib PUBLIC
fgs_5gmm_lib
fgs_5gsm_lib
fgs_5gmm_ies_lib
nas_common_ies_lib
)
target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES)
......@@ -24,15 +24,16 @@
#include <stdint.h>
#include "openair3/UICC/usim_interface.h"
/* Map task id to printable name. */
typedef struct {
int id;
char text[256];
} text_info_t;
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
#define TO_ENUM(LabEl, nUmID ) LabEl = nUmID,
#include "fgs_nas_utils.h"
#include "FGSAuthenticationResponse.h"
#include "FGSDeregistrationRequestUEOriginating.h"
#include "FGSIdentityResponse.h"
#include "FGSMobileIdentity.h"
#include "FGSNASSecurityModeComplete.h"
#include "FGSUplinkNasTransport.h"
#include "RegistrationComplete.h"
#include "RegistrationRequest.h"
#include "fgs_service_request.h"
/* Message types defintions for:
(a) 5GS Mobility Management (5GMM) (IDs 0x41 - 0x68)
......@@ -220,9 +221,6 @@ typedef enum {
FOREACH_CAUSE_SECU(TO_ENUM)
} cause_secu_id_t;
// IEIs (Information Element Identifier)
#define IEI_NULL 0x00
/**
* Security protected 5GS NAS message header (9.1.1 of 3GPP TS 24.501)
* either 5GMM or 5GSM
......@@ -239,6 +237,15 @@ typedef struct {
uint8_t sequence_number;
} __attribute__((packed)) fgs_nas_message_security_header_t;
/// 5GS Protocol Discriminator identifiers
typedef enum fgs_protocol_discriminator_e {
// 5GS Mobility Management
FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E,
// 5GS Session Management
FGS_SESSION_MANAGEMENT_MESSAGE = 0x2E,
} fgs_protocol_discriminator_t;
/// 5GMM - 5GS mobility management
/**
......@@ -251,6 +258,46 @@ typedef struct {
uint8_t message_type;
} fgmm_msg_header_t;
/// 5GS legacy defs
typedef union {
fgmm_msg_header_t header;
registration_request_msg registration_request;
fgs_service_request_msg_t service_request;
fgs_identiy_response_msg fgs_identity_response;
fgs_authentication_response_msg fgs_auth_response;
fgs_deregistration_request_ue_originating_msg fgs_deregistration_request_ue_originating;
fgs_security_mode_complete_msg fgs_security_mode_complete;
registration_complete_msg registration_complete;
fgs_uplink_nas_transport_msg uplink_nas_transport;
} MM_msg;
typedef struct {
MM_msg mm_msg; /* 5GS Mobility Management messages */
} fgs_nas_message_plain_t;
typedef struct {
fgs_nas_message_security_header_t header;
fgs_nas_message_plain_t plain;
} fgs_nas_message_security_protected_t;
typedef union {
fgs_nas_message_security_header_t header;
fgs_nas_message_security_protected_t security_protected;
fgs_nas_message_plain_t plain;
} fgs_nas_message_t;
typedef struct {
union {
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;
uint16_t message_authentication_code1;
uint16_t message_authentication_code2;
uint8_t sequence_number;
} security_protected_nas_msg_header_t;
} choice;
} nas_msg_header_t;
/// 5GSM - 5GS session management
/**
......@@ -268,4 +315,10 @@ typedef struct {
uint8_t message_type;
} fgsm_msg_header_t;
/// Function prototypes
int mm_msg_encode(const MM_msg *mm_msg, uint8_t *buffer, uint32_t len);
int nas_protected_security_header_encode(uint8_t *buffer, const fgs_nas_message_security_header_t *header, int length);
int _nas_mm_msg_encode_header(const fgmm_msg_header_t *header, uint8_t *buffer, uint32_t len);
#endif // NR_NAS_DEFS_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 "NR_NAS_defs.h"
#include "nas_log.h"
#include "TLVEncoder.h"
#include "fgs_nas_utils.h"
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(fgmm_msg_header_t)) {
return (TLV_ENCODE_BUFFER_TOO_SHORT);
}
/* Check the protocol discriminator */
if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) {
LOG_TRACE(ERROR, "Unexpected extened protocol discriminator: 0x%x", header->ex_protocol_discriminator);
return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED);
}
/* Encode the extendedprotocol discriminator */
ENCODE_U8(buffer + size, header->ex_protocol_discriminator, size);
/* Encode the security header type */
ENCODE_U8(buffer + size, (header->security_header_type & 0xf), size);
/* Encode the message type */
ENCODE_U8(buffer + size, header->message_type, size);
return (size);
}
int mm_msg_encode(const MM_msg *mm_msg, uint8_t *buffer, uint32_t len)
{
LOG_FUNC_IN;
int header_result;
int encode_result;
uint8_t msg_type = mm_msg->header.message_type;
/* First encode the EMM message header */
header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len);
if (header_result < 0) {
LOG_TRACE(ERROR,
"Failed to encode 5GMM message header"
"(%d)",
header_result);
LOG_FUNC_RETURN(header_result);
}
buffer += header_result;
len -= header_result;
switch (msg_type) {
case FGS_REGISTRATION_REQUEST:
encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len);
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;
case FGS_DEREGISTRATION_REQUEST_UE_ORIGINATING:
encode_result =
encode_fgs_deregistration_request_ue_originating(&mm_msg->fgs_deregistration_request_ue_originating, buffer, len);
break;
case FGS_SERVICE_REQUEST:
encode_result = encode_fgs_service_request(buffer, &mm_msg->service_request, len);
break;
default:
LOG_TRACE(ERROR, " Unexpected message type: 0x%x", mm_msg->header.message_type);
encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE;
break;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
}
if (encode_result < 0) {
LOG_TRACE(ERROR,
" Failed to encode L3 EMM message 0x%x "
"(%d)",
mm_msg->header.message_type,
encode_result);
}
if (encode_result < 0)
LOG_FUNC_RETURN(encode_result);
LOG_FUNC_RETURN(header_result + encode_result);
}
int nas_protected_security_header_encode(uint8_t *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);
}
/*
* 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
*/
#ifndef FGS_NAS_UTILS_H
#define FGS_NAS_UTILS_H
#include <stdint.h>
/* Map task id to printable name. */
typedef struct {
int id;
char text[256];
} text_info_t;
#define TO_TEXT(LabEl, nUmID) {nUmID, #LabEl},
#define TO_ENUM(LabEl, nUmID ) LabEl = nUmID,
#endif // FGS_NAS_UTILS_H
......@@ -4,6 +4,7 @@ add_library(nr_nas STATIC nr_nas_msg.c)
target_link_libraries(nr_nas PUBLIC asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
target_link_libraries(nr_nas PUBLIC
fgs_lib
fgs_5gmm_lib
fgs_5gsm_lib
fgs_5gmm_ies_lib
......@@ -11,7 +12,4 @@ target_link_libraries(nr_nas PUBLIC
nas_utils
)
target_include_directories(nr_nas PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/5GS
)
target_include_directories(nr_nas PUBLIC . 5GS/)
......@@ -20,7 +20,7 @@
*/
/*! \file nr_nas_msg.c
* \brief simulator for nr nas message
* \brief Definitions of handlers and callbacks for NR NAS UE task
* \author Yoshio INOUE, Masayuki HARADA
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
* \date 2020
......@@ -40,7 +40,6 @@
#include "FGCNasMessageContainer.h"
#include "FGSDeregistrationRequestUEOriginating.h"
#include "FGSDeregistrationType.h"
#include "LOG/log.h"
#include "NasKeySetIdentifier.h"
#include "NrUESecurityCapability.h"
#include "OctetString.h"
......@@ -158,50 +157,6 @@ static security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_b
return NAS_SECURITY_INTEGRITY_PASSED;
}
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 fgmm_msg_header_t *header, uint8_t *buffer, uint32_t len)
{
int size = 0;
/* Check the buffer length */
if (len < sizeof(fgmm_msg_header_t)) {
return (TLV_ENCODE_BUFFER_TOO_SHORT);
}
/* Check the protocol discriminator */
if (header->ex_protocol_discriminator != FGS_MOBILITY_MANAGEMENT_MESSAGE) {
LOG_TRACE(ERROR, "ESM-MSG - Unexpected extened protocol discriminator: 0x%x", header->ex_protocol_discriminator);
return (TLV_ENCODE_PROTOCOL_NOT_SUPPORTED);
}
/* Encode the extendedprotocol discriminator */
ENCODE_U8(buffer + size, header->ex_protocol_discriminator, size);
/* Encode the security header type */
ENCODE_U8(buffer + size, (header->security_header_type & 0xf), size);
/* Encode the message type */
ENCODE_U8(buffer + size, header->message_type, size);
return (size);
}
static int fill_suci(FGSMobileIdentity *mi, const uicc_t *uicc)
{
mi->suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI;
......@@ -259,71 +214,6 @@ static int fill_imeisv(FGSMobileIdentity *mi, const uicc_t *uicc)
return 19;
}
int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len)
{
LOG_FUNC_IN;
int header_result;
int encode_result;
uint8_t msg_type = mm_msg->header.message_type;
/* First encode the EMM message header */
header_result = _nas_mm_msg_encode_header(&mm_msg->header, buffer, len);
if (header_result < 0) {
LOG_TRACE(ERROR,
"EMM-MSG - Failed to encode EMM message header "
"(%d)",
header_result);
LOG_FUNC_RETURN(header_result);
}
buffer += header_result;
len -= header_result;
switch (msg_type) {
case FGS_REGISTRATION_REQUEST:
encode_result = encode_registration_request(&mm_msg->registration_request, buffer, len);
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;
case FGS_DEREGISTRATION_REQUEST_UE_ORIGINATING:
encode_result =
encode_fgs_deregistration_request_ue_originating(&mm_msg->fgs_deregistration_request_ue_originating, buffer, len);
break;
case FGS_SERVICE_REQUEST:
encode_result = encode_fgs_service_request(buffer, &mm_msg->service_request, len);
break;
default:
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", mm_msg->header.message_type);
encode_result = TLV_ENCODE_WRONG_MESSAGE_TYPE;
break;
/* TODO: Handle not standard layer 3 messages: SERVICE_REQUEST */
}
if (encode_result < 0) {
LOG_TRACE(ERROR,
"EMM-MSG - Failed to encode L3 EMM message 0x%x "
"(%d)",
mm_msg->header.message_type,
encode_result);
}
if (encode_result < 0)
LOG_FUNC_RETURN(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, uicc_t *uicc)
{
uint8_t S[100] = {0};
......@@ -786,7 +676,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
// encode the message
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->nas_data), &(nas_msg.header), size);
int security_header_len = nas_protected_security_header_encode(initialNasMsg->nas_data, &nas_msg.header, size);
initialNasMsg->length =
security_header_len
......@@ -1010,7 +900,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
// encode the message
initialNasMsg->nas_data = calloc_or_fail(size, sizeof(*initialNasMsg->nas_data));
int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->nas_data), &nas_msg.header, size);
int security_header_len = nas_protected_security_header_encode(initialNasMsg->nas_data, &nas_msg.header, size);
initialNasMsg->length =
security_header_len
......@@ -1118,7 +1008,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
// encode the message
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
int security_header_len = nas_protected_security_header_encode((char *)(initialNasMsg->nas_data), &(nas_msg.header), size);
int security_header_len = nas_protected_security_header_encode(initialNasMsg->nas_data, &nas_msg.header, size);
initialNasMsg->length =
security_header_len
......
......@@ -35,15 +35,6 @@
#include <openair3/UICC/usim_interface.h>
#include <stdbool.h>
#include <stdint.h>
#include "FGSAuthenticationResponse.h"
#include "FGSDeregistrationRequestUEOriginating.h"
#include "FGSIdentityResponse.h"
#include "FGSMobileIdentity.h"
#include "FGSNASSecurityModeComplete.h"
#include "FGSUplinkNasTransport.h"
#include "RegistrationComplete.h"
#include "RegistrationRequest.h"
#include "fgs_service_request.h"
#include "as_message.h"
#include "NR_NAS_defs.h"
#include "secu_defs.h"
......@@ -92,54 +83,6 @@ typedef struct {
instance_t UE_id;
} nr_ue_nas_t;
typedef enum fgs_protocol_discriminator_e {
/* Protocol discriminator identifier for 5GS Mobility Management */
FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E,
/* Protocol discriminator identifier for 5GS Session Management */
FGS_SESSION_MANAGEMENT_MESSAGE = 0x2E,
} fgs_protocol_discriminator_t;
typedef union {
fgmm_msg_header_t header;
registration_request_msg registration_request;
fgs_service_request_msg_t service_request;
fgs_identiy_response_msg fgs_identity_response;
fgs_authentication_response_msg fgs_auth_response;
fgs_deregistration_request_ue_originating_msg fgs_deregistration_request_ue_originating;
fgs_security_mode_complete_msg fgs_security_mode_complete;
registration_complete_msg registration_complete;
fgs_uplink_nas_transport_msg uplink_nas_transport;
} MM_msg;
typedef struct {
MM_msg mm_msg; /* 5GS Mobility Management messages */
} fgs_nas_message_plain_t;
typedef struct {
fgs_nas_message_security_header_t header;
fgs_nas_message_plain_t plain;
} fgs_nas_message_security_protected_t;
typedef union {
fgs_nas_message_security_header_t header;
fgs_nas_message_security_protected_t security_protected;
fgs_nas_message_plain_t plain;
} fgs_nas_message_t;
typedef struct {
union {
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;
uint16_t message_authentication_code1;
uint16_t message_authentication_code2;
uint8_t sequence_number;
} security_protected_nas_msg_header_t;
} choice;
} nas_msg_header_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