From 89eae04132e7e04b767b7b511d36793c1241e84f Mon Sep 17 00:00:00 2001 From: Xue Song Date: Tue, 3 Nov 2020 09:58:23 +0000 Subject: [PATCH] Add NAS Security Mode Complete --- cmake_targets/CMakeLists.txt | 1 + openair2/RRC/NR_UE/rrc_UE.c | 12 +++- .../EMM/MSG/FGSNASSecurityModeComplete.c | 36 ++++++++++ .../EMM/MSG/FGSNASSecurityModeComplete.h | 43 ++++++++++++ openair3/NAS/COMMON/IES/FGSMobileIdentity.c | 24 ++++++- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 65 +++++++++++++++++++ openair3/NAS/NR_UE/nr_nas_msg_sim.h | 6 ++ 7 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c create mode 100644 openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f663f63659..52c759c867 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2457,6 +2457,7 @@ if(ITTI_SIM) ${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c ${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c ${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c + ${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c ) set(libnrnas_ies_OBJS diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 240d5f4552..04b4e8a903 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2350,12 +2350,19 @@ nr_rrc_ue_decode_dcch( LOG_I(NR_RRC, "[UE %d] Received %s: UEid %u, length %u , buffer %p\n", ctxt_pP->module_id, messages_info[NAS_DOWNLINK_DATA_IND].name, ctxt_pP->module_id, pdu_length, pdu_buffer); as_nas_info_t initialNasMsg; + uint8_t msg_type; memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + if((pdu_buffer + 1) != NULL){ + if (*(pdu_buffer + 1) > 0 ) { + msg_type = *(pdu_buffer + 9); + } else { + msg_type = *(pdu_buffer + 2); + } + } if((pdu_buffer + 2) == NULL){ LOG_W(NR_RRC, "[UE] Received invalid downlink message\n"); return 0; } - uint8_t msg_type = *(pdu_buffer + 2); switch(msg_type){ case FGS_IDENTITY_REQUEST: @@ -2364,6 +2371,9 @@ nr_rrc_ue_decode_dcch( case FGS_AUTHENTICATION_REQUEST: generateAuthenticationResp(&initialNasMsg, pdu_buffer); break; + case FGS_SECURITY_MODE_COMMAND: + generateSecurityModeComplete(&initialNasMsg); + break; default: LOG_W(NR_RRC,"unknow message type %d\n",msg_type); break; diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c new file mode 100644 index 0000000000..2012f55a6b --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.c @@ -0,0 +1,36 @@ +/*! \file FGSNASSecurityModeComplete.c + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include +#include + +#include "nas_log.h" + +#include "FGSNASSecurityModeComplete.h" +#include "FGSMobileIdentity.h" + +int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len) +{ + int encoded = 0; + int encode_result = 0; + + if ((encode_result = + encode_5gs_mobile_identity(&fgs_security_mode_comp->fgsmobileidentity, 0x77, buffer + + encoded, len - encoded)) < 0) //Return in case of error + return encode_result; + else + encoded += encode_result; + + return encoded; +} + + + diff --git a/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h new file mode 100644 index 0000000000..936ed225cf --- /dev/null +++ b/openair3/NAS/COMMON/EMM/MSG/FGSNASSecurityModeComplete.h @@ -0,0 +1,43 @@ +/*! \file FGSNASSecurityModeComplete.h + +\brief security mode complete procedures for gNB +\author Yoshio INOUE, Masayuki HARADA +\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com +\date 2020 +\version 0.1 +*/ + +#include +#include +#include + +#include "ExtendedProtocolDiscriminator.h" +#include "SecurityHeaderType.h" +#include "SpareHalfOctet.h" +#include "FGSMobileIdentity.h" +#include "MessageType.h" + +#ifndef FGS_NAS_SECURITY_MODE_COMPLETE_H_ +#define FGS_NAS_SECURITY_MODE_COMPLETE_H_ + +/* + * Message name: security mode complete + * Description: This message is sent by the UE to the AMF in response to a SECURITY MODE COMMAND message. See table 8.2.26.1.1. + * Significance: dual + * Direction: UE to AMF + */ + +typedef struct fgs_security_mode_complete_msg_tag { + /* Mandatory fields */ + ExtendedProtocolDiscriminator protocoldiscriminator; + SecurityHeaderType securityheadertype:4; + SpareHalfOctet sparehalfoctet:4; + MessageType messagetype; + FGSMobileIdentity fgsmobileidentity; + +} fgs_security_mode_complete_msg; + +int encode_fgs_security_mode_complete(fgs_security_mode_complete_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len); + +#endif /* ! defined(FGS_NAS_SECURITY_MODE_COMPLETE_H_) */ + diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index 09e98252cd..4e54b6bb17 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -20,6 +20,7 @@ static int decode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_t *buffer); static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer); +static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer); int decode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei, uint8_t *buffer, uint32_t len) { @@ -72,11 +73,21 @@ int encode_5gs_mobile_identity(FGSMobileIdentity *fgsmobileidentity, uint8_t iei buffer + encoded); } + if (fgsmobileidentity->imeisv.typeofidentity == FGS_MOBILE_IDENTITY_IMEISV) { + encoded_rc = encode_imeisv_5gs_mobile_identity(&fgsmobileidentity->imeisv, + buffer + encoded); + } + if (encoded_rc < 0) { return encoded_rc; } - *(uint16_t*) buffer = htons(encoded + encoded_rc - 2 - ((iei > 0) ? 1 : 0)); + if(iei > 0){ + *(uint16_t*) (buffer+1) = htons(encoded + encoded_rc - 3); + } else { + *(uint16_t*) buffer = htons(encoded + encoded_rc - 2); + } + return (encoded + encoded_rc); } @@ -193,4 +204,15 @@ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_ return encoded; } +static int encode_imeisv_5gs_mobile_identity(Imeisv5GSMobileIdentity_t *imeisv, uint8_t *buffer) +{ + uint32_t encoded = 0; + *(buffer + encoded) = 0x00 | (imeisv->digit1 << 4) | (imeisv->oddeven << 3) | (imeisv->typeofidentity); + encoded++; + + *(buffer + encoded) = 0x00 | (imeisv->digitp1 << 4) | (imeisv->digitp); + encoded++; + + return encoded; +} diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 7ec8da34c3..196088f8d3 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -18,6 +18,28 @@ #include "aka_functions.h" #include "secu_defs.h" +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 mm_msg_header_t *header, uint8_t *buffer, uint32_t len) { @@ -74,6 +96,9 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { 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; default: LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x", mm_msg->header.message_type); @@ -303,5 +328,45 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){ initialNasMsg->length = mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data), size); } +void generateSecurityModeComplete(as_nas_info_t *initialNasMsg) +{ + int size = sizeof(mm_msg_header_t); + fgs_nas_message_t nas_msg; + memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + MM_msg *mm_msg; + int i; + // set security protected header + nas_msg.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + nas_msg.header.security_header_type = INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX; + size += 7; + mm_msg = &nas_msg.security_protected.plain.mm_msg; + + // set header + 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_SECURITY_MODE_COMPLETE; + + // set security mode complete + mm_msg->fgs_security_mode_complete.protocoldiscriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE; + size += 1; + mm_msg->fgs_security_mode_complete.securityheadertype = PLAIN_5GS_MSG; + size += 1; + mm_msg->fgs_security_mode_complete.messagetype = FGS_SECURITY_MODE_COMPLETE; + size += 1; + + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.typeofidentity = FGS_MOBILE_IDENTITY_IMEISV; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digit1 = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp1 = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.digitp = 1; + mm_msg->fgs_security_mode_complete.fgsmobileidentity.imeisv.oddeven = 0; + size += 5; + + // encode the message + initialNasMsg->data = (Byte_t *)malloc(size * sizeof(Byte_t)); + + int security_header_len = nas_protected_security_header_encode((char*)(initialNasMsg->data),&(nas_msg.header), size); + + initialNasMsg->length = security_header_len + mm_msg_encode(mm_msg, (uint8_t*)(initialNasMsg->data+security_header_len), size-security_header_len); +} diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 97b3a0b519..9ed301ad7b 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -14,11 +14,15 @@ #include "RegistrationRequest.h" #include "FGSIdentityResponse.h" #include "FGSAuthenticationResponse.h" +#include "FGSNASSecurityModeComplete.h" #include "as_message.h" #define PLAIN_5GS_MSG 0b0000 #define INTEGRITY_PROTECTED 0b0001 +#define INTEGRITY_PROTECTED_AND_CIPHERED 0b0010 +#define INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX 0b0011 // only for SECURITY MODE COMMAND +#define INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX 0b0100 // only for SECURITY MODE COMPLETE #define REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */ #define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */ @@ -59,6 +63,7 @@ typedef union { registration_request_msg registration_request; fgs_identiy_response_msg fgs_identity_response; fgs_authentication_response_msg fgs_auth_response; + fgs_security_mode_complete_msg fgs_security_mode_complete; } MM_msg; @@ -82,6 +87,7 @@ typedef union { void generateRegistrationRequest(as_nas_info_t *initialNasMsg); void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype); void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf); +void generateSecurityModeComplete(as_nas_info_t *initialNasMsg); #endif /* __NR_NAS_MSG_SIM_H__*/