Add NAS Security Mode Complete
This commit is contained in:
@@ -2457,6 +2457,7 @@ if(ITTI_SIM)
|
|||||||
${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
|
${NAS_SRC}COMMON/EMM/MSG/RegistrationAccept.c
|
||||||
${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
|
${NAS_SRC}COMMON/EMM/MSG/FGSIdentityResponse.c
|
||||||
${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
|
${NAS_SRC}COMMON/EMM/MSG/FGSAuthenticationResponse.c
|
||||||
|
${NAS_SRC}COMMON/EMM/MSG/FGSNASSecurityModeComplete.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set(libnrnas_ies_OBJS
|
set(libnrnas_ies_OBJS
|
||||||
|
|||||||
@@ -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,
|
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);
|
ctxt_pP->module_id, pdu_length, pdu_buffer);
|
||||||
as_nas_info_t initialNasMsg;
|
as_nas_info_t initialNasMsg;
|
||||||
|
uint8_t msg_type;
|
||||||
memset(&initialNasMsg, 0, sizeof(as_nas_info_t));
|
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){
|
if((pdu_buffer + 2) == NULL){
|
||||||
LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
|
LOG_W(NR_RRC, "[UE] Received invalid downlink message\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint8_t msg_type = *(pdu_buffer + 2);
|
|
||||||
|
|
||||||
switch(msg_type){
|
switch(msg_type){
|
||||||
case FGS_IDENTITY_REQUEST:
|
case FGS_IDENTITY_REQUEST:
|
||||||
@@ -2364,6 +2371,9 @@ nr_rrc_ue_decode_dcch(
|
|||||||
case FGS_AUTHENTICATION_REQUEST:
|
case FGS_AUTHENTICATION_REQUEST:
|
||||||
generateAuthenticationResp(&initialNasMsg, pdu_buffer);
|
generateAuthenticationResp(&initialNasMsg, pdu_buffer);
|
||||||
break;
|
break;
|
||||||
|
case FGS_SECURITY_MODE_COMMAND:
|
||||||
|
generateSecurityModeComplete(&initialNasMsg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
|
LOG_W(NR_RRC,"unknow message type %d\n",msg_type);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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_) */
|
||||||
|
|
||||||
@@ -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_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_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)
|
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);
|
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) {
|
if (encoded_rc < 0) {
|
||||||
return encoded_rc;
|
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);
|
return (encoded + encoded_rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,4 +204,15 @@ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_
|
|||||||
return encoded;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,28 @@
|
|||||||
#include "aka_functions.h"
|
#include "aka_functions.h"
|
||||||
#include "secu_defs.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,
|
static int _nas_mm_msg_encode_header(const mm_msg_header_t *header,
|
||||||
uint8_t *buffer, uint32_t len) {
|
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:
|
case FGS_AUTHENTICATION_RESPONSE:
|
||||||
encode_result = encode_fgs_authentication_response(&mm_msg->fgs_auth_response, buffer, len);
|
encode_result = encode_fgs_authentication_response(&mm_msg->fgs_auth_response, buffer, len);
|
||||||
break;
|
break;
|
||||||
|
case FGS_SECURITY_MODE_COMPLETE:
|
||||||
|
encode_result = encode_fgs_security_mode_complete(&mm_msg->fgs_security_mode_complete, buffer, len);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
|
LOG_TRACE(ERROR, "EMM-MSG - Unexpected message type: 0x%x",
|
||||||
mm_msg->header.message_type);
|
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);
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,11 +14,15 @@
|
|||||||
#include "RegistrationRequest.h"
|
#include "RegistrationRequest.h"
|
||||||
#include "FGSIdentityResponse.h"
|
#include "FGSIdentityResponse.h"
|
||||||
#include "FGSAuthenticationResponse.h"
|
#include "FGSAuthenticationResponse.h"
|
||||||
|
#include "FGSNASSecurityModeComplete.h"
|
||||||
#include "as_message.h"
|
#include "as_message.h"
|
||||||
|
|
||||||
|
|
||||||
#define PLAIN_5GS_MSG 0b0000
|
#define PLAIN_5GS_MSG 0b0000
|
||||||
#define INTEGRITY_PROTECTED 0b0001
|
#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 REGISTRATION_REQUEST 0b01000001 /* 65 = 0x41 */
|
||||||
#define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */
|
#define FGS_AUTHENTICATION_REQUEST 0b01010110 /* 86 = 0x56 */
|
||||||
@@ -59,6 +63,7 @@ typedef union {
|
|||||||
registration_request_msg registration_request;
|
registration_request_msg registration_request;
|
||||||
fgs_identiy_response_msg fgs_identity_response;
|
fgs_identiy_response_msg fgs_identity_response;
|
||||||
fgs_authentication_response_msg fgs_auth_response;
|
fgs_authentication_response_msg fgs_auth_response;
|
||||||
|
fgs_security_mode_complete_msg fgs_security_mode_complete;
|
||||||
} MM_msg;
|
} MM_msg;
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +87,7 @@ typedef union {
|
|||||||
void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
|
void generateRegistrationRequest(as_nas_info_t *initialNasMsg);
|
||||||
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype);
|
void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype);
|
||||||
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf);
|
void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf);
|
||||||
|
void generateSecurityModeComplete(as_nas_info_t *initialNasMsg);
|
||||||
|
|
||||||
#endif /* __NR_NAS_MSG_SIM_H__*/
|
#endif /* __NR_NAS_MSG_SIM_H__*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user