Merge remote-tracking branch 'origin/nr-ue-nas-sec-mode-reject' into integration_2025_w24 (!3369)

Add Security Mode Reject lib/unit test and adopt in stack

This MR is adding the library for the NAS Security Mode Reject, and
relevant unit test.

The UE shall send a SECURITY MODE REJECT containing a 5GMM cause that
typically indicates one of the following cause values: (23) UE security
capabilities mismatch. (24) security mode rejected, unspecified

- The message shall be protected if a security context is available.
- The message is adopted in the handling of Security Mode Command failure.

See 3GPP TS 24.501 5.4.2.5 "NAS security mode command not accepted by
the UE".

This MR includes changes from !3262:

> This patch series addresses a security issue where the UE improperly
> accepts a Security Mode Command (SMC) without an authentication header
> (Security Header 0). This behavior violates TS 24.501 and enables an
> attacker to bypass authentication, set integrity protection to NULL
> (NIA0), and reconfigure the UE without proper verification.
>
> We identified the following issues:
>
> 1. The UE currently accepts unauthenticated SMC messages, even
>    allowing NIA0 and EIA0 to be set outside emergency mode.
> 2. When applying NIA0, the MAC field remains uninitialized,
>    consistently containing the sequence 0xFF3F0000, making it feasible
>    to bypass authentication and enforce insecure configurations.
> 3. The UE does not properly signal security mode failures to the Core
>    Network.
>
> This patch series tries to address the above-mentioned issues:
>
> 1. Reject unauthenticated SMC messages, enforcing the requirement that
>    they must be integrity-protected.
> 2. Validate MAC before applying security settings, ensuring that only
>    authenticated messages are accepted.
> 3. Tear down the security context if an integrity check fails.
> 4. Introduce the Security Mode Reject message to inform the Core
>    Network of failed SMC procedures, as required by TS 24.501.
This commit is contained in:
Robert Schmidt
2025-06-12 14:44:17 +02:00
7 changed files with 420 additions and 25 deletions
@@ -9,6 +9,7 @@ add_library(fgs_5gmm_lib OBJECT
FGSIdentityResponse.c
FGSAuthenticationResponse.c
FGSNASSecurityModeComplete.c
FGSNASSecurityModeReject.c
RegistrationComplete.c
FGSUplinkNasTransport.c
FGSDeregistrationRequestUEOriginating.c
@@ -0,0 +1,50 @@
/*
* 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 <stdint.h>
#include "FGSNASSecurityModeReject.h"
#include "common/utils/ds/byte_array.h"
#include "fgmm_lib.h"
int encode_fgs_security_mode_reject(byte_array_t *buffer, const fgs_security_mode_reject_msg *msg)
{
if (buffer->len < 1)
return -1; // nothing to encode
// 5GMM cause (Mandatory)
return encode_fgs_nas_cause(buffer, &msg->cause);
}
/** @brief Decode Security Mode Reject (8.2.18 of 3GPP TS 24.501) */
int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *msg, const byte_array_t *buffer)
{
if (buffer->len < 1)
return -1; // nothing to decode
// 5GMM cause (Mandatory)
return decode_fgs_nas_cause(&msg->cause, buffer);
}
bool eq_sec_mode_reject(const fgs_security_mode_reject_msg *a, const fgs_security_mode_reject_msg *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
return true;
}
@@ -0,0 +1,47 @@
/*
* 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_security_mode_reject_H_
#define FGS_NAS_security_mode_reject_H_
#include <stdint.h>
#include "fgmm_lib.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 3GPP TS 24.501 table 8.2.27.1.1
*
* Significance: dual
* Direction: UE to AMF
*/
typedef struct {
// 5GMM cause (Mandatory)
cause_id_t cause;
} fgs_security_mode_reject_msg;
int encode_fgs_security_mode_reject(byte_array_t *buffer, const fgs_security_mode_reject_msg *msg);
int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *msg, const byte_array_t *buffer);
bool eq_sec_mode_reject(const fgs_security_mode_reject_msg *a, const fgs_security_mode_reject_msg *b);
#endif /* ! defined(FGS_NAS_security_mode_reject_H_) */
+2
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"
@@ -226,6 +227,7 @@ typedef struct {
fgmm_auth_failure_t fgmm_auth_failure;
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 */
+5
View File
@@ -81,6 +81,11 @@ 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: {
byte_array_t ba = {.buf = buffer, .len = len};
enc_msg = encode_fgs_security_mode_reject(&ba, &p->mm_msg.fgs_security_mode_reject);
break;
}
case FGS_UPLINK_NAS_TRANSPORT:
enc_msg = encode_fgs_uplink_nas_transport(&p->mm_msg.uplink_nas_transport, buffer, len);
break;
@@ -8,6 +8,7 @@
#include "fgmm_service_accept.h"
#include "fgmm_service_reject.h"
#include "fgmm_authentication_failure.h"
#include "FGSNASSecurityModeReject.h"
#include "nr_nas_msg.h"
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
@@ -266,6 +267,37 @@ static void test_auth_failure(void)
free_fgmm_auth_failure(&dec);
}
/** @brief Test NAS Security Mode Reject enc/dec */
static void test_security_mode_reject(void)
{
// Dummy NAS Security Mode Reject message
const fgs_security_mode_reject_msg orig = {
.cause = Illegal_UE,
};
// Expected encoded data
uint8_t expected_enc[] = {0x03};
// Buffer
uint8_t buf[8] = {0};
byte_array_t buffer = {.buf = buf, .len = sizeof(buf)};
// Encode
int encoded_length = encode_fgs_security_mode_reject(&buffer, &orig);
AssertFatal(encoded_length == sizeofArray(expected_enc), "encode_fgs_security_mode_reject() failed\n");
// Compare the raw encoded buffer with expected encoded data
AssertFatal(memcmp(buffer.buf, expected_enc, encoded_length) == 0, "Encoding mismatch!\n");
// Decode
fgs_security_mode_reject_msg dec = {0};
int decoded_length = decode_fgs_security_mode_reject(&dec, &buffer);
AssertFatal(decoded_length >= 0, "decode_fgs_security_mode_reject() failed\n");
// Compare original and decoded messages
AssertFatal(eq_sec_mode_reject(&orig, &dec), "test_sec_mode_reject() failed: original and decoded messages do not match\n");
}
int main()
{
test_regression_registration_accept();
@@ -273,5 +305,6 @@ int main()
test_service_accept();
test_service_reject();
test_auth_failure();
test_security_mode_reject();
return 0;
}
+282 -25
View File
@@ -152,6 +152,153 @@ static bool unprotected_allowed(byte_array_t buffer, fgs_nas_msg_t msg_type)
}
}
/**
* @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
*/
static void nas_security_compute_mac(nr_ue_nas_t *nas,
byte_array_t buffer,
const bool is_uplink,
const bool is3gpp_access,
uint8_t *mac)
{
uint8_t *buf = buffer.buf + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH - 1;
int len = buffer.len - SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH + 1;
/* 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 = buf;
/* length in bits */
stream_cipher.blength = len << 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
*/
static void nas_security_decrypt_payload(nr_ue_nas_t *nas, byte_array_t buffer, const bool is_uplink, const bool is3gpp_access)
{
Security_header_t sec_hdr;
if (!nas_security_get_sec_hdr(buffer.buf, buffer.len, &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 = buffer.buf + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH;
stream_cipher.message = plain_payload;
/* length in bits */
int plain_length = buffer.len - SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH;
stream_cipher.blength = plain_length << 3;
/* Allocate output buffer for body only */
uint8_t *decrypted = malloc_or_fail(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, byte_array_t buffer, fgs_nas_msg_t msg_type)
{
if (nas->security_container == NULL)
@@ -210,35 +357,22 @@ static security_state_t nas_security_rx_process(nr_ue_nas_t *nas, byte_array_t 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 = buffer.buf + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH - 1;
/* length in bits */
stream_cipher.blength = (buffer.len - 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 = buffer.buf + 2;
uint8_t computed_mac[NAS_INTEGRITY_SIZE];
nas_security_compute_mac(nas,
buffer,
false,
true,
computed_mac);
if (memcmp(received_mac, computed_mac, NAS_INTEGRITY_SIZE) != 0)
return NAS_SECURITY_INTEGRITY_FAILED;
/* decipher */
uint8_t payload_len = buffer.len - 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 = buffer.buf + 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(buffer.buf + SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH, buf, payload_len);
nas_security_decrypt_payload(nas, buffer, false, true);
/* update estimated DL Counter */
nas->security.nas_count_dl++;
return NAS_SECURITY_INTEGRITY_PASSED;
@@ -1008,10 +1142,103 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
}
}
/** @brief Generates the Security Mode Reject message to be sent by the UE to the AMF
* to indicate that the corresponding security mode command has been rejected */
static void generateSecurityModeReject(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, cause_id_t cause)
{
LOG_I(NAS, "Send Security Mode Reject\n");
fgmm_msg_header_t plain_header = set_mm_header(FGS_SECURITY_MODE_REJECT, PLAIN_5GS_MSG);
int size = sizeof(plain_header);
fgs_security_mode_reject_msg msg = {.cause = cause};
size += 1;
/** The UE shall apply the 5G NAS security context in use
* before the initiation of the security mode control procedure,
* if any, to protect the SECURITY MODE REJECT message */
bool has_security_context = nas->security_container && nas->security_container->integrity_context;
if (has_security_context) {
fgmm_nas_msg_security_protected_t sp = {0};
sp.header.protocol_discriminator = FGS_MOBILITY_MANAGEMENT_MESSAGE;
sp.header.security_header_type = INTEGRITY_PROTECTED;
sp.header.sequence_number = nas->security.nas_count_ul & 0xff;
size += sizeof(sp.header);
sp.plain.header = plain_header;
sp.plain.mm_msg.fgs_security_mode_reject = msg;
// Security protected header encoding
int security_header_len = nas_protected_security_header_encode(initialNasMsg->nas_data, &sp.header, size);
initialNasMsg->length =
security_header_len + mm_msg_encode(&sp.plain, initialNasMsg->nas_data + security_header_len, size - security_header_len);
/* ciphering */
uint8_t buf[initialNasMsg->length - 7];
nas_stream_cipher_t stream_cipher;
stream_cipher.context = nas->security_container->ciphering_context;
AssertFatal(nas->security.nas_count_ul <= 0xffffff, "fatal: NAS COUNT UL too big (todo: fix that)\n");
stream_cipher.count = nas->security.nas_count_ul;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
stream_cipher.message = (unsigned char *)(initialNasMsg->nas_data + 7);
/* length in bits */
stream_cipher.blength = (initialNasMsg->length - 7) << 3;
stream_compute_encrypt(nas->security_container->ciphering_algorithm, &stream_cipher, buf);
memcpy(stream_cipher.message, buf, initialNasMsg->length - 7);
/* integrity protection */
uint8_t mac[4];
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.nas_count_ul++;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
stream_cipher.message = (unsigned char *)(initialNasMsg->nas_data + 6);
/* length in bits */
stream_cipher.blength = (initialNasMsg->length - 6) << 3;
stream_compute_integrity(nas->security_container->integrity_algorithm, &stream_cipher, mac);
LOG_D(NAS, "Integrity protected initial NAS message: mac = %x %x %x %x \n", mac[0], mac[1], mac[2], mac[3]);
for (int i = 0; i < 4; i++)
initialNasMsg->nas_data[2 + i] = mac[i];
} else {
fgmm_nas_message_plain_t plain = {0};
plain.header = plain_header;
plain.mm_msg.fgs_security_mode_reject = msg;
// encode the message
initialNasMsg->nas_data = malloc_or_fail(size);
initialNasMsg->length = mm_msg_encode(&plain, 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(nas, 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(nas, 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(nas, initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* retrieve integrity and ciphering algorithms */
AssertFatal(pdu_length > 10, "nas: bad pdu\n");
if (pdu_length < 10) {
LOG_E(NAS, "Invalid pdu_length=%d : send Security Mode Reject\n", pdu_length);
// 3GPP TS 24.501 5.4.2.5 NAS security mode command not accepted by the UE
generateSecurityModeReject(nas, initialNasMsg, Security_mode_rejected_unspecified);
}
int ciphering_algorithm = (pdu[10] >> 4) & 0x0f;
int integrity_algorithm = pdu[10] & 0x0f;
@@ -1035,8 +1262,38 @@ 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(nas, initialNasMsg, Security_mode_rejected_unspecified);
return;
}
/* Check MAC and delete context if it does not match */
uint8_t computed_mac[NAS_INTEGRITY_SIZE];
byte_array_t ba = {.buf = pdu, .len = pdu_length};
nas_security_compute_mac(nas, ba, false, true, computed_mac);
/* Teardown security container if mismatch. */
if(memcmp(computed_mac, recv_mac, NAS_INTEGRITY_SIZE) != 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(nas, initialNasMsg, Security_mode_rejected_unspecified);
return;
}
nas_itti_kgnb_refresh_req(nas->UE_id, nas->security.kgnb);
generateSecurityModeComplete(nas, initialNasMsg);