Commit 89eae041 authored by Xue Song's avatar Xue Song

Add NAS Security Mode Complete

parent 947194a2
...@@ -2457,6 +2457,7 @@ if(ITTI_SIM) ...@@ -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( ...@@ -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( ...@@ -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;
......
/*! \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;
}
/*! \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_ ...@@ -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 ...@@ -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_ ...@@ -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 @@ ...@@ -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) { ...@@ -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){ ...@@ -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 @@ ...@@ -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 { ...@@ -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 { ...@@ -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__*/
......
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