Compare commits

...

8 Commits

Author SHA1 Message Date
Eduard Vlad
113475fa1e Security Mode Command: Perform Algorithm Rejection in NAS Handler
This change performs the algorithm rejection in the corresponding NAS
handler for 5G, since the protocol definitions differ between LTE and
5G, regarding NIA0/EIA0 user plane traffic.

Therefore, for 5G NIA0 is rejected, since it is not allowed under normal
circumstances, while LTE user plane traffic can indeed have EIA0
selected.

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-05-23 15:08:23 +02:00
Eduard Vlad
badb41f301 Security Mode Command: Handle incorrect authentication
It is not allowed to accept an unauthenticated SMC message,
as this effectively bypasses all security measures and
enables a malicioius attacker to compromise the confidentiality
and integrity of exchanged messages.

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-05-23 15:08:21 +02:00
Eduard Vlad
c5b41ba3fd security mode command: generation of reject message
This is necessary to indicate to the Core network, that
the security mode command procedure has failed.

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:43:59 +00:00
Eduard Vlad
4584d5aadc FGS NAS lib: Encode Security Mode Reject
Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:43:59 +00:00
Eduard Vlad
f38bf4f3ab 5GS 5GMM Messages: Add FGSNASSecurityModeReject message
This is required for an invalid security mode command, e.g. when the MAC
fails, or the wrong Security Header is set.

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:43:59 +00:00
Eduard Vlad
a4ef158b01 5gs IEs: Add FGSNasCause
This is required for encoding the Cause in the Seucurity Mode Reject
message (among others).

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:43:59 +00:00
Eduard Vlad
d3727884e2 nas security: Implement reusable procedures for Security Mode Command handling
Retrieving the mac is necessary during the handling of the SMC, since the
context is generated from the specified keys therein. Therefore, it is
necessary to check the MAC right after generation and ensure the authenticity
of the message. If it is not given, the message must be rejected.

Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:43:57 +00:00
Eduard Vlad
faa81c024b SMC: reject NULL integrity for non emergency cases
Signed-off-by: Eduard Vlad <eduard.vlad@rwth-aachen.de>
2025-04-04 07:42:14 +00:00
10 changed files with 459 additions and 25 deletions

2
.gitignore vendored
View File

@@ -25,4 +25,4 @@ tags
nfapi_nr_interface_scf
*.log
*.out
CMakeUserPresets.json
CMakeUserPresets.json

View File

@@ -4,6 +4,7 @@ add_library(fgs_5gmm_ies_lib OBJECT
FGSRegistrationResult.c
FGMMCapability.c
NrUESecurityCapability.c
FGSNasCause.c
FGCNasMessageContainer.c
SORTransparentContainer.c
)

View File

@@ -0,0 +1,64 @@
/*
* 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
*/
/*! \file FGSNASSecurityModeReject.c
\brief security mode complete reject for gNB
\author Eduard Vlad
\email: eduard.vlad@rwth-aachen.de
\date 2025
*/
#include "FGSNasCause.h"
#include "TLVEncoder.h"
#include "TLVDecoder.h"
int encode_fgs_nas_cause(const FGSNasCause *emmcause, uint8_t iei, uint8_t *buffer, uint32_t len)
{
uint32_t encoded = 0;
/* Checking IEI and pointer */
CHECK_PDU_POINTER_AND_LENGTH_ENCODER(buffer, FGS_NAS_CAUSE_MINIMUM_LENGTH, len);
/* Cause has no IE */
if (iei > 0) {
*buffer = iei;
encoded++;
}
*(buffer + encoded) = *emmcause;
encoded++;
return encoded;
}
int decode_fgs_nas_cause(FGSNasCause *fgs_nas_cause, uint8_t iei, uint8_t *buffer, uint32_t len){
int decoded = 0;
/* Cause has no IE */
if (iei > 0) {
CHECK_IEI_DECODER(iei, *buffer);
decoded++;
}
(*fgs_nas_cause) = *(buffer + decoded);
decoded++;
return decoded;
}

View File

@@ -0,0 +1,44 @@
/*
* 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
*/
/*! \file FGSNASSecurityModeReject.c
\brief security mode complete reject for gNB
\author Eduard Vlad
\email: eduard.vlad@rwth-aachen.de
\date 2025
*/
#ifndef FGS_NAS_CAUSE_H_
#define FGS_NAS_CAUSE_H_
#include <stdint.h>
typedef uint8_t FGSNasCause;
#define FGS_NAS_CAUSE_MINIMUM_LENGTH 1
#define FGS_NAS_CAUSE_MAXIMUM_LENGTH 1
int encode_fgs_nas_cause(const FGSNasCause *fgs_nas_cause, uint8_t iei, uint8_t *buffer, uint32_t len);
int decode_fgs_nas_cause(FGSNasCause *fgs_nas_cause, uint8_t iei, uint8_t *buffer, uint32_t len);
#endif

View File

@@ -7,6 +7,7 @@ add_library(fgs_5gmm_lib OBJECT
FGSIdentityResponse.c
FGSAuthenticationResponse.c
FGSNASSecurityModeComplete.c
FGSNASSecurityModeReject.c
RegistrationComplete.c
FGSUplinkNasTransport.c
FGSDeregistrationRequestUEOriginating.c

View File

@@ -0,0 +1,59 @@
/*
* 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
*/
/*! \file FGSNASSecurityModeReject.c
\brief security mode complete reject for gNB
\author Eduard Vlad
\email: eduard.vlad@rwth-aachen.de
\date 2025
*/
#include <stdint.h>
#include "FGSNASSecurityModeReject.h"
#include "FGSNasCause.h"
int encode_fgs_security_mode_reject(const fgs_security_mode_reject_msg *fgs_security_mode_rej, uint8_t *buffer, uint32_t len)
{
int encoded = 0;
int encode_result = 0;
/* Encode the Cause, which has no IEI */
if((encode_result = encode_fgs_nas_cause(&fgs_security_mode_rej->cause,0 , buffer + encoded, len - encoded)) < 0) {
return encode_result;
} else {
encoded += encode_result;
}
return encoded;
}
int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *securitymodereject, uint8_t *buffer, uint32_t len){
int decoded = 0;
/* Decode the Cause, which has no IEI */
if((decoded = decode_fgs_nas_cause(&securitymodereject->cause, 0, buffer, len)) < 0) {
return decoded;
}
return decoded;
}

View File

@@ -0,0 +1,57 @@
/*
* 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
*/
/*! \file FGSNASSecurityModeComplete.h
\brief security mode reject procedures for gNB
\author Eduard Vlad
\email: eduard.vlad@rwth-aachen.de
\date 2025
\version 0.1
*/
#ifndef FGS_NAS_security_mode_reject_H_
#define FGS_NAS_security_mode_reject_H_
#include <stdint.h>
#include "MessageType.h"
#include "FGSNasCause.h"
/*
* Message name: security mode reject
* Description: The SECURITY MODE REJECT message is sent by the UE to the AMF to
* indicate that the corresponding security mode command has been rejected.
* See table 8.2.27.1.1.
*
* Significance: dual
* Direction: UE to AMF
*/
typedef struct {
/* Mandatory fields */
FGSNasCause cause;
} fgs_security_mode_reject_msg;
int encode_fgs_security_mode_reject(const fgs_security_mode_reject_msg *fgs_security_mode_comp, uint8_t *buffer, uint32_t len);
int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *securitymodereject, uint8_t *buffer, uint32_t len);
#endif /* ! defined(FGS_NAS_security_mode_reject_H_) */

View File

@@ -31,6 +31,7 @@
#include "FGSIdentityResponse.h"
#include "FGSMobileIdentity.h"
#include "FGSNASSecurityModeComplete.h"
#include "FGSNASSecurityModeReject.h"
#include "FGSUplinkNasTransport.h"
#include "RegistrationComplete.h"
#include "RegistrationRequest.h"
@@ -224,6 +225,7 @@ typedef struct {
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;
fgs_security_mode_reject_msg fgs_security_mode_reject;
registration_complete_msg registration_complete;
fgs_uplink_nas_transport_msg uplink_nas_transport;
} mm_msg; /* 5GS Mobility Management messages */

View File

@@ -76,6 +76,9 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
case FGS_SECURITY_MODE_COMPLETE:
enc_msg = encode_fgs_security_mode_complete(&p->mm_msg.fgs_security_mode_complete, buffer, len);
break;
case FGS_SECURITY_MODE_REJECT:
enc_msg = encode_fgs_security_mode_reject(&p->mm_msg.fgs_security_mode_reject, buffer, len);
break;
case FGS_UPLINK_NAS_TRANSPORT:
enc_msg = encode_fgs_uplink_nas_transport(&p->mm_msg.uplink_nas_transport, buffer, len);
break;

View File

@@ -126,6 +126,149 @@ static const char *print_info(uint8_t id, const text_info_t *array, uint8_t arra
return "N/A";
}
/**
* @brief Get the MAC of a Security Protected NAS message
* @param[in] pdu_buffer The buffer containing the NAS message
* @param[in] pdu_length The length of the NAS message
* @param[out] mac The MAC of the NAS message
* @return true if the MAC was successfully extracted, false otherwise
*/
bool nas_security_get_mac(uint8_t *pdu_buffer, int pdu_length, uint8_t *mac)
{
/* Check for Security Protected Header */
/* at least 8 bytes for Security Protected MM Message */
if (pdu_length < 8)
return false;
/* Only message type, that is not protected (c.f.
TS 24.501 9.3 Security Header Type) */
if((Security_header_t)pdu_buffer[1] == PLAIN_5GS_MSG)
return false;
/* Get the MAC [EPD][SecHdr][MAC0]..[MAC3] - success */
for (int i = 0; i < 4; i++)
mac[i] = pdu_buffer[2 + i];
return true;
}
/*
* @brief Get the Security Header of a NAS message
* @param[in] msg The buffer containing the NAS message
* @param[in] msg_length The length of the NAS message
* @param[out] sec_hdr The Security Header of the NAS message
* @return true if the Security Header was successfully extracted, false otherwise
*/
bool nas_security_get_sec_hdr(uint8_t *msg, int msg_length, Security_header_t *sec_hdr)
{
/* Shortest message is [EPD][SecHdrType][Payl]*/
if (msg_length < 3){
LOG_E(NAS, "Invalid NAS message length %d\n", msg_length);
return false;
}
/* Get the SecHdr and check for validity */
uint8_t sec_hdr_type = msg[1] & 0x0f;
if(sec_hdr_type > INTEGRITY_PROTECTED_AND_CIPHERED_WITH_NEW_SECU_CTX){
LOG_E(NAS, "Invalid Security Header Type %d\n", sec_hdr_type);
return false;
}
/* Check ok. */
*sec_hdr = (Security_header_t)sec_hdr_type;
return true;
}
/*
* @brief Compute the MAC of a NAS message
* @param[in] nas The NAS context
* @param[in] pdu_buffer The buffer containing the NAS message
* @param[in] is_uplink True if the message is uplink, false Downlink
* @param[in] is3gpp_access True if the message is 3GPP access, false otherwise
* @param[in] pdu_length The length of the NAS message
* @param[out] mac The MAC of the NAS message
*/
void nas_security_compute_mac(nr_ue_nas_t *nas, uint8_t *pdu_buffer, bool is_uplink, bool is3gpp_access, int pdu_length, uint8_t *mac)
{
/* Compute the MAC */
nas_stream_cipher_t stream_cipher;
stream_cipher.context = nas->security_container->integrity_context;
/* Select the right count in the context */
if(is_uplink)
stream_cipher.count = nas->security.nas_count_ul;
else
stream_cipher.count = nas->security.nas_count_dl;
/* 3GPP access is 1, non-3GPP access is 2 - see 3GPP TS 33.501 6.4.2.2 */
stream_cipher.bearer = is3gpp_access ? 1 : 2;
/* Configure Direction for MAC protection */
stream_cipher.direction = is_uplink ? 0 : 1;
/* Possibly encrypted message */
stream_cipher.message = pdu_buffer;
/* length in bits */
stream_cipher.blength = pdu_length << 3;
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
}
/*
* @brief: Decrypt the payload of a NAS message. The buffer is modified in place
* @param[in] nas The NAS context
* @param[in] pdu_buffer The buffer containing the full (header + payload) NAS message
* @param[in] is_uplink True if the message is uplink, false Downlink
* @param[in] is3gpp_access True if the message is 3GPP access, false otherwise
* @param[in] pdu_length The length of the NAS message
*/
void nas_security_decrypt_payload(nr_ue_nas_t *nas, uint8_t *pdu_buffer, bool is_uplink, bool is3gpp_access, int pdu_length){
Security_header_t sec_hdr;
if(!nas_security_get_sec_hdr(pdu_buffer, pdu_length, &sec_hdr)){
LOG_E(NAS, "Failed to get Security Header\n");
return;
}
/* Nothing to do for unencrypted msgs */
if(sec_hdr == PLAIN_5GS_MSG || sec_hdr == INTEGRITY_PROTECTED){
return;
}
/* Get integrity keys, and algorithms */
nas_stream_cipher_t stream_cipher;
stream_cipher.context = nas->security_container->ciphering_context;
/* Use the estimated count the right count in the context */
stream_cipher.count = nas->security.nas_count_dl;
/* 3GPP access is 1, non-3GPP access is 2 - see 3GPP TS 33.501 6.4.2.2 */
stream_cipher.bearer = is3gpp_access ? 1 : 2;
/* Decryption only in downlink direction */
stream_cipher.direction = 1;
/* [EPD][SHR][MAC0]..[MAC3][PDU...]*/
uint8_t *plain_payload = pdu_buffer + 7;
stream_cipher.message = plain_payload;
/* length in bits */
stream_cipher.blength = (pdu_length - 7) << 3;
/* Allocate output buffer for body only */
unsigned int plain_length = pdu_length - 7;
uint8_t *decrypted = malloc(plain_length);
stream_compute_encrypt(nas->security_container->ciphering_algorithm, &stream_cipher, decrypted);
/* Override and free the decrypted payload */
memcpy(plain_payload, decrypted, plain_length);
free(decrypted);
}
static security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_buffer, int pdu_length)
{
if (nas->security_container == NULL)
@@ -169,35 +312,18 @@ static security_state_t nas_security_rx_process(nr_ue_nas_t *nas, uint8_t *pdu_b
}
/* check integrity */
uint8_t computed_mac[NAS_INTEGRITY_SIZE];
nas_stream_cipher_t stream_cipher;
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.nas_count_dl;
stream_cipher.bearer = 1; /* todo: don't hardcode */
stream_cipher.direction = 1;
stream_cipher.message = pdu_buffer + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH - 1;
/* length in bits */
stream_cipher.blength = (pdu_length - SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH + 1) << 3;
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, computed_mac);
/* [EPD][SHD][MAC0]...[MAC3][SEQNO][PAYL]*/
uint8_t *received_mac = pdu_buffer + 2;
uint8_t computed_mac[4];
nas_security_compute_mac(nas, pdu_buffer + 6, false, true, pdu_length - 6, computed_mac);
if (memcmp(received_mac, computed_mac, NAS_INTEGRITY_SIZE) != 0)
return NAS_SECURITY_INTEGRITY_FAILED;
/* decipher */
uint8_t payload_len = pdu_length - SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH;
uint8_t buf[payload_len];
stream_cipher.context = nas->security_container->ciphering_context;
stream_cipher.count = nas->security.nas_count_dl;
stream_cipher.bearer = 1; /* todo: don't hardcode */
stream_cipher.direction = 1;
stream_cipher.message = pdu_buffer + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH;
/* length in bits */
stream_cipher.blength = (payload_len) << 3;
stream_compute_encrypt(nas->security_container->ciphering_algorithm, &stream_cipher, buf);
memcpy(pdu_buffer + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH, buf, payload_len);
nas_security_decrypt_payload(nas, pdu_buffer, false, true, pdu_length);
/* update estimated DL Counter */
nas->security.nas_count_dl++;
return NAS_SECURITY_INTEGRITY_PASSED;
@@ -917,8 +1043,56 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
}
}
static void generateSecurityModeReject(as_nas_info_t *initialNasMsg, cause_id_t cause)
{
size_t size = 0;
// Set 5GMM plain header
fgmm_nas_message_plain_t plain = {0};
plain.header = set_mm_header(FGS_SECURITY_MODE_REJECT, PLAIN_5GS_MSG);
size += 3; /* = sizeof(plain.header) */
// Set plain FGMM Security Mode Reject
fgs_security_mode_reject_msg *smc_rej_msg = &plain.mm_msg.fgs_security_mode_reject;
// Cause
smc_rej_msg->cause = cause;
size += 1; /* += sizeof(fgs_security_mode_reject_msg) */
// Encode the message, with total length = 4 (fixed)
initialNasMsg->nas_data = malloc_or_fail(size); /* * sizeof(*initialNasMsg->nas_data) = 1*/
initialNasMsg->length =
mm_msg_encode(&plain, (uint8_t *)initialNasMsg->nas_data, size);
}
static void handle_security_mode_command(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, uint8_t *pdu, int pdu_length)
{
/* Handle security mode command: must be authenticated, especially if no security
context has been previously established. */
uint8_t recv_mac[4];
Security_header_t sec_hdr;
/* Must have valid security header*/
if(!nas_security_get_sec_hdr(pdu, pdu_length, &sec_hdr)) {
LOG_E(NAS, "Received Security Mode Command without integrity protection.\n");
generateSecurityModeReject(initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* Must be integrity protected with new context (=3), see 3GPP TS 24.501 5.4.2.2 */
if(sec_hdr != INTEGRITY_PROTECTED_WITH_NEW_SECU_CTX) {
LOG_E(NAS, "Received Security Mode Command with invalid security header type %d.\n", sec_hdr);
generateSecurityModeReject(initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* Must have a MAC - checked after deriving keys */
if(!nas_security_get_mac(pdu, pdu_length, recv_mac)) {
LOG_E(NAS, "Received Security Mode Command with invalid MAC.\n");
generateSecurityModeReject(initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* retrieve integrity and ciphering algorithms */
AssertFatal(pdu_length > 10, "nas: bad pdu\n");
int ciphering_algorithm = (pdu[10] >> 4) & 0x0f;
@@ -944,8 +1118,37 @@ static void handle_security_mode_command(nr_ue_nas_t *nas, as_nas_info_t *initia
}
printf("\n");
/* todo: stream_security_container_delete() is not called anywhere, deal with that */
nas->security_container = stream_security_container_init(ciphering_algorithm, integrity_algorithm, knas_enc, knas_int);
if (integrity_algorithm != EIA0_ALG_ID) {
nas->security_container = stream_security_container_init(ciphering_algorithm, integrity_algorithm, knas_enc, knas_int);
} else {
LOG_E(NAS, "Rejecting Invalid NULL integrity %d for 5G!\n",
integrity_algorithm);
nas->security_container = NULL;
}
/* Handle the invalid container with a reject message */
if(nas->security_container == NULL) {
LOG_W(NAS, "Could not create security container!\n");
generateSecurityModeReject(initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* Check MAC and delete context if it does not match */
uint8_t computed_mac[4];
nas_security_compute_mac(nas, pdu + 6, false, true, pdu_length - 6, computed_mac);
/* Teardown security container if mismatch. */
if(memcmp(computed_mac, recv_mac, 4) != 0) {
LOG_W(NAS, "MAC does not match\n");
LOG_W(NAS, "Expected: %x %x %x %x\n", computed_mac[0], computed_mac[1], computed_mac[2], computed_mac[3]);
LOG_W(NAS, "Received: %x %x %x %x\n", recv_mac[0], recv_mac[1], recv_mac[2], recv_mac[3]);
stream_security_container_delete(nas->security_container);
nas->security_container = NULL;
/* Signal rejection */
generateSecurityModeReject(initialNasMsg, Security_mode_rejected_unspecified);
return;
}
nas_itti_kgnb_refresh_req(nas->UE_id, nas->security.kgnb);
generateSecurityModeComplete(nas, initialNasMsg);