fix (NAS UE): add Service Request NAS container with PDU status and align security and KgNB sync

Extend the UE 5GS Service Request path to carry `PDU session status`
inside a NAS message container and cipher only that container value when
valid NAS contexts exist. This aligns the initial Service
Request handling with the TS 24.501 rules for non-cleartext IEs.

Treat the generated Service Request as integrity-protected whenever an
integrity context is available, and keep the post-request KgNB refresh
aligned with the NAS UL count used for that protected message.

Changes:
- update `generateServiceRequest()` in `nr_nas_msg.c` to derive a
  `PDU session status` bitmap from configured UE PDU sessions and treat
  it as the non-cleartext trigger for the initial Service Request
- build an inner plain Service Request carrying `PDU session status`,
  place it in the `NAS message container`, cipher only the container
  value with the NAS ciphering context, and keep the outer Service
  Request integrity protected
- extend `fgs_service_request` lib to support optional `PDU session status`
  and `NAS message container` fields
- decode known optional Service Request TLV IEs with a `switch` and skip
  unsupported ones
- add `free_fgs_service_request()` and `eq_fgs_service_request()`
- extend `nas_lib_test` to cover Service Request encoding and decoding
  with `PDU session status`, `NAS message container`, and skipped
  optional IEs, and initialize the test logging/config stubs
- set the outgoing ngKSI with `set_fgs_ksi(nas)` instead of hardcoding
  `NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE`
- move `initialNasMsg->nas_data` allocation into the protected and plain
  branches so each path allocates after its final size accounting
- increment `nas->security.nas_count_ul` after integrity MAC computation
- derive a refreshed KgNB with `derive_kgnb()` and send it through
  `nas_itti_kgnb_refresh_req()` after the protected Service Request is
  built

Refs:
- TS 24.501 §4.4.6 (protection of initial NAS signalling messages)
- TS 24.501 §4.4.4.1 and §4.4.6 allow an initial Service Request to be
  integrity protected and unciphered when a valid 5G NAS security
  context exists and no NAS message container is included.
- TS 24.501 §8.2.16.1 (Service Request message content)
- TS 24.501 §8.2.16.3 (PDU session status)
- TS 24.501 §9.11.3.33 (NAS message container)
- TS 33.501 §6.4.3.1 (NAS integrity inputs)
- TS 33.501 §6.4.4.1 (NAS confidentiality inputs)
- TS 33.501 §6.8.1.2.2 derives KgNB from the UL NAS COUNT of the NAS
  message that moves the UE from CM-IDLE to CM-CONNECTED, unless a
  subsequent NAS Security Mode Complete exists, in which case that newer
  UL NAS COUNT becomes the freshness input.

Signed-off-by: Guido Casati <guido.casati@openairinterface.org>
This commit is contained in:
Guido Casati
2026-04-15 18:18:10 +02:00
parent d59a0a1a37
commit 607f9c0f33
5 changed files with 245 additions and 42 deletions

View File

@@ -76,15 +76,20 @@ typedef enum { PDU_SESSION_INACTIVE = 0, PDU_SESSION_ACTIVE } PSI_status_t;
typedef enum { REACTIVATION_SUCCESS = 0, REACTIVATION_FAILED } PSI_reactivation_t;
#define FOREACH_SA_IEI(IEI_DEF) \
IEI_DEF(IEI_PDU_SESSION_STATUS, 0x50) \
IEI_DEF(IEI_ALLOWED_PDU_SESSION_STATUS, 0x25) \
IEI_DEF(IEI_PDU_SESSION_REACT_RESULT, 0x26) \
IEI_DEF(IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE, 0x72) \
IEI_DEF(IEI_EAPMSG, 0x78) \
IEI_DEF(IEI_CAG_INFO_LIST, 0x75) \
IEI_DEF(IEI_PAGING_RESTRICTION, 0x28) \
IEI_DEF(IEI_UE_REQUEST_TYPE, 0x29) \
IEI_DEF(IEI_UPLINK_DATA_STATUS, 0x40) \
IEI_DEF(IEI_PDU_SESSION_STATUS, 0x50) \
IEI_DEF(IEI_T3446_VALUE, 0x5F) \
IEI_DEF(IEI_T3448_VALUE, 0x6B) \
IEI_DEF(IEI_T3446_VALUE, 0x5F)
IEI_DEF(IEI_FGS_NAS_MESSAGE_CONTAINER, 0x71) \
IEI_DEF(IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE, 0x72) \
IEI_DEF(IEI_CAG_INFO_LIST, 0x75) \
IEI_DEF(IEI_EAPMSG, 0x78)
// Enum for Service Accept IEIs
// Enum for Service Request procedure IEIs
typedef enum { FOREACH_SA_IEI(TO_ENUM) } nas_service_IEI_t;
static const text_info_t sa_iei_s[] = {FOREACH_SA_IEI(TO_TEXT)};

View File

@@ -6,9 +6,11 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "common/utils/eq_check.h"
#include "fgs_service_request.h"
#include "FGSMobileIdentity.h"
#include "NasKeySetIdentifier.h"
@@ -16,13 +18,29 @@
#define LEN_FGS_MOBILE_ID_CONTENTS_SIZE 2 // octets
#define MIN_LEN_FGS_SERVICE_REQUEST 10 // octets
#define TLV_IE_HEADER_LENGTH 2 // IEI + length
#define IEI_NULL 0x00
/** @brief Get the total encoded size of a (optional) TLV IE (IEI + length + value) */
static int get_tlv_ie_len(const uint8_t *buffer, uint32_t len)
{
if (len < TLV_IE_HEADER_LENGTH)
return -1;
uint8_t ie_len = buffer[1];
uint32_t total_ie_len = TLV_IE_HEADER_LENGTH + ie_len;
if (len < total_ie_len)
return -1;
return total_ie_len;
}
/**
* @brief Encode 5GMM NAS Service Request message (8.2.16 of 3GPP TS 24.501)
*/
int encode_fgs_service_request(uint8_t *buffer, const fgs_service_request_msg_t *service_request, uint32_t len)
{
const uint32_t total_len = len;
// Return if buffer is shorter than min length
if (len < MIN_LEN_FGS_SERVICE_REQUEST)
return -1;
@@ -43,6 +61,24 @@ int encode_fgs_service_request(uint8_t *buffer, const fgs_service_request_msg_t
uint16_t tmp = htons(encoded - LEN_FGS_MOBILE_ID_CONTENTS_SIZE - 1);
memcpy(buffer + 1, &tmp, sizeof(tmp));
if (service_request->has_pdu_session_status) {
byte_array_t ba = {.buf = buffer + encoded, .len = total_len - encoded};
int encoded_rc = encode_pdu_session_ie(&ba, IEI_PDU_SESSION_STATUS, service_request->pdu_session_status);
if (encoded_rc < 0)
return -1;
encoded += encoded_rc;
}
if (service_request->fgsnasmessagecontainer != NULL) {
int encoded_rc = encode_fgc_nas_message_container(service_request->fgsnasmessagecontainer,
IEI_FGS_NAS_MESSAGE_CONTAINER,
buffer + encoded,
total_len - encoded);
if (encoded_rc < 0)
return -1;
encoded += encoded_rc;
}
return encoded;
}
@@ -75,5 +111,93 @@ int decode_fgs_service_request(fgs_service_request_msg_t *sr, const uint8_t *buf
}
decoded += decoded_rc;
while (decoded < len) {
uint8_t iei = buffer[decoded];
switch (iei) {
case IEI_PDU_SESSION_STATUS: {
decoded++;
byte_array_t ba = create_byte_array(len - decoded, buffer + decoded);
decoded_rc = decode_pdu_session_ie(sr->pdu_session_status, &ba);
free_byte_array(ba);
if (decoded_rc < 0) {
LOG_E(NAS, "Failed to decode PDU Session Status\n");
return -1;
}
decoded += decoded_rc;
sr->has_pdu_session_status = true;
break;
}
case IEI_FGS_NAS_MESSAGE_CONTAINER: {
if (sr->fgsnasmessagecontainer != NULL)
return -1;
sr->fgsnasmessagecontainer = calloc_or_fail(1, sizeof(*sr->fgsnasmessagecontainer));
byte_array_t ba = create_byte_array(len - decoded, buffer + decoded);
decoded_rc = decode_fgc_nas_message_container(sr->fgsnasmessagecontainer, IEI_FGS_NAS_MESSAGE_CONTAINER, ba.buf, ba.len);
free_byte_array(ba);
if (decoded_rc < 0) {
LOG_E(NAS, "Failed to decode FGS NAS Message Container\n");
free(sr->fgsnasmessagecontainer);
return -1;
}
decoded += decoded_rc;
break;
}
case IEI_UPLINK_DATA_STATUS:
case IEI_ALLOWED_PDU_SESSION_STATUS:
case IEI_UE_REQUEST_TYPE:
case IEI_PAGING_RESTRICTION:
// Skip the TLV IE (IEI + length + value)
LOG_D(NAS, "Skipping TLV IE 0x%02x\n", iei);
decoded_rc = get_tlv_ie_len(buffer + decoded, len - decoded);
if (decoded_rc < 0)
return -1;
decoded += decoded_rc;
break;
default:
return -1;
}
}
return decoded;
}
void free_fgs_service_request(fgs_service_request_msg_t *msg)
{
DevAssert(msg);
if (msg->fgsnasmessagecontainer) {
free(msg->fgsnasmessagecontainer->nasmessagecontainercontents.value);
msg->fgsnasmessagecontainer->nasmessagecontainercontents.length = 0;
free(msg->fgsnasmessagecontainer);
}
}
bool eq_fgs_service_request(const fgs_service_request_msg_t *a, const fgs_service_request_msg_t *b)
{
_EQ_CHECK_INT(a->naskeysetidentifier.tsc, b->naskeysetidentifier.tsc);
_EQ_CHECK_INT(a->naskeysetidentifier.naskeysetidentifier, b->naskeysetidentifier.naskeysetidentifier);
_EQ_CHECK_INT(a->serviceType, b->serviceType);
_EQ_CHECK_INT(a->fiveg_s_tmsi.digit1, b->fiveg_s_tmsi.digit1);
_EQ_CHECK_INT(a->fiveg_s_tmsi.spare, b->fiveg_s_tmsi.spare);
_EQ_CHECK_INT(a->fiveg_s_tmsi.typeofidentity, b->fiveg_s_tmsi.typeofidentity);
_EQ_CHECK_INT(a->fiveg_s_tmsi.amfsetid, b->fiveg_s_tmsi.amfsetid);
_EQ_CHECK_INT(a->fiveg_s_tmsi.amfpointer, b->fiveg_s_tmsi.amfpointer);
_EQ_CHECK_UINT32(a->fiveg_s_tmsi.tmsi, b->fiveg_s_tmsi.tmsi);
_EQ_CHECK_INT(a->has_pdu_session_status, b->has_pdu_session_status);
if (a->has_pdu_session_status && b->has_pdu_session_status) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_EQ_CHECK_INT(a->pdu_session_status[i], b->pdu_session_status[i]);
}
_EQ_CHECK_OPTIONAL_PTR(a, b, fgsnasmessagecontainer);
if (a->fgsnasmessagecontainer != NULL) {
const OctetString *a_contents = &a->fgsnasmessagecontainer->nasmessagecontainercontents;
const OctetString *b_contents = &b->fgsnasmessagecontainer->nasmessagecontainercontents;
_EQ_CHECK_UINT32(a_contents->length, b_contents->length);
if (a_contents->length > 0)
EQ_CHECK_GENERIC(memcmp(a_contents->value, b_contents->value, a_contents->length) == 0, "%d", 1, 0);
}
return true;
}

View File

@@ -13,6 +13,7 @@
#include "FGCNasMessageContainer.h"
#include "MessageType.h"
#include "FGSMobileIdentity.h"
#include "fgmm_lib.h"
#ifndef FGS_SERVICE_REQUEST_H_
#define FGS_SERVICE_REQUEST_H_
@@ -33,10 +34,14 @@ typedef struct {
ServiceType serviceType: 4;
Stmsi5GSMobileIdentity_t fiveg_s_tmsi;
/* Optional fields */
bool has_pdu_session_status;
uint8_t pdu_session_status[MAX_NUM_PSI];
FGCNasMessageContainer *fgsnasmessagecontainer;
} fgs_service_request_msg_t;
int encode_fgs_service_request(uint8_t *buffer, const fgs_service_request_msg_t *servicerequest, uint32_t len);
int decode_fgs_service_request(fgs_service_request_msg_t *sr, const uint8_t *buffer, uint32_t len);
void free_fgs_service_request(fgs_service_request_msg_t *msg);
bool eq_fgs_service_request(const fgs_service_request_msg_t *a, const fgs_service_request_msg_t *b);
#endif /* ! defined(FGS_SERVICE_REQUEST_H_) */

View File

@@ -6,6 +6,7 @@
#include <stdint.h>
#include <stdio.h>
#include <arpa/inet.h>
#include "common/utils/LOG/log.h"
#include "common/utils/ds/byte_array.h"
#include "RegistrationAccept.h"
#include "fgs_service_request.h"
@@ -16,6 +17,8 @@
#include "fgmm_authentication_reject.h"
#include "nr_nas_msg.h"
configmodule_interface_t *uniqCfg = NULL;
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
printf("detected error at %s:%d:%s: %s\n", file, line, function, s);
@@ -25,15 +28,6 @@ void exit_function(const char *file, const char *function, const int line, const
/**
* @brief Equality check for NAS Service Request enc/dec
*/
static bool eq_service_request(const fgs_service_request_msg_t *a, const fgs_service_request_msg_t *b)
{
bool result = true;
result &= memcmp(&a->naskeysetidentifier, &b->naskeysetidentifier, sizeof(NasKeySetIdentifier)) == 0;
result &= a->serviceType == b->serviceType;
result &= memcmp(&a->fiveg_s_tmsi, &b->fiveg_s_tmsi, sizeof(Stmsi5GSMobileIdentity_t)) == 0;
return result;
}
/** @brief Test regression of NAS Registration Accept decoding
* This test verifies that the NAS Registration Accept message
* is correctly decoded. It decodes a message as it received from
@@ -102,27 +96,50 @@ static void test_service_request(void)
uint16_t amf_set_id = 0x48;
uint16_t amf_pointer = 0x34;
uint32_t tmsi = 0x56789ABC;
uint8_t container_data[] = {0xde, 0xad, 0xbe};
fgs_service_request_msg_t original_msg = {
.naskeysetidentifier = {.tsc = NAS_KEY_SET_IDENTIFIER_NATIVE, .naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE},
.serviceType = SERVICE_TYPE_DATA,
.fiveg_s_tmsi = {.spare = 0,
.fiveg_s_tmsi = {.digit1 = DIGIT1,
.typeofidentity = FGS_MOBILE_IDENTITY_5GS_TMSI,
.amfsetid = amf_set_id,
.amfpointer = amf_pointer,
.tmsi = tmsi}};
.tmsi = tmsi},
.has_pdu_session_status = true,
.pdu_session_status = {[2] = PDU_SESSION_ACTIVE, [4] = PDU_SESSION_ACTIVE},
.fgsnasmessagecontainer = NULL};
original_msg.fgsnasmessagecontainer = calloc_or_fail(1, sizeof(*original_msg.fgsnasmessagecontainer));
FGCNasMessageContainer *nas_container = original_msg.fgsnasmessagecontainer;
OctetString *nas_container_contents = &nas_container->nasmessagecontainercontents;
nas_container_contents->value = calloc_or_fail(sizeof(container_data), sizeof(*nas_container_contents->value));
memcpy(nas_container_contents->value, container_data, sizeof(container_data));
nas_container_contents->length = sizeof(container_data);
uint8_t expected_encoded_data[] = {0x71,
0x00,
0x00,
0x07,
0xF4,
(amf_set_id >> 2) & 0xFF,
(amf_set_id << 6) | (amf_pointer & 0x3F),
(tmsi >> 24) & 0xFF,
(tmsi >> 16) & 0xFF,
(tmsi >> 8) & 0xFF,
tmsi & 0xFF};
uint16_t tmp = htons(7); // length of 5GS mobile identity IE for 5G-S-TMSI (bytes)
memcpy(expected_encoded_data + 1, &tmp, sizeof(tmp));
tmsi & 0xFF,
IEI_PDU_SESSION_STATUS,
0x02,
0x14,
0x00,
IEI_FGS_NAS_MESSAGE_CONTAINER,
0x00,
0x03,
0xde,
0xad,
0xbe,
IEI_UE_REQUEST_TYPE,
0x01,
0x00};
int encoded_service_request_len = sizeof(expected_encoded_data) - 3;
// Buffer
uint8_t buffer[64];
@@ -131,18 +148,21 @@ static void test_service_request(void)
// Encode NAS Service Request
int encoded_length = encode_fgs_service_request(buffer, &original_msg, sizeof(buffer));
AssertFatal(encoded_length >= 0, "encode_fgs_service_request() failed\n");
AssertFatal(encoded_length == encoded_service_request_len, "Unexpected encoded SERVICE REQUEST length\n");
// Compare the raw encoded buffer with expected encoded data
// Compare the raw encoded buffer with expected encoded data, excluding the skipped optional IE.
AssertFatal(memcmp(buffer, expected_encoded_data, encoded_length) == 0, "Encoding mismatch!\n");
// Decode NAS Service Request
fgs_service_request_msg_t decoded_service_request = {0};
int decoded_length = decode_fgs_service_request(&decoded_service_request, buffer, sizeof(buffer));
AssertFatal(decoded_length >= 0, "decode_fgs_service_request() failed\n");
int decoded_length = decode_fgs_service_request(&decoded_service_request, expected_encoded_data, sizeof(expected_encoded_data));
AssertFatal(decoded_length == sizeof(expected_encoded_data), "decode_fgs_service_request() failed\n");
// Compare original and decoded messages
AssertFatal(eq_service_request(&original_msg, &decoded_service_request) == 0,
AssertFatal(eq_fgs_service_request(&original_msg, &decoded_service_request),
"test_service_request() failed: original and decoded messages do not match\n");
free_fgs_service_request(&decoded_service_request);
free_fgs_service_request(&original_msg);
}
/**
@@ -343,6 +363,11 @@ static void test_auth_reject(void)
int main()
{
// Initialize logging system
logInit();
// Set logging level for NAS to show INFO messages
set_log(NAS, OAILOG_DEBUG);
// Tests list
test_regression_registration_accept();
test_service_request();
test_service_accept();

View File

@@ -999,7 +999,7 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
int size = 0;
// NAS is security protected if has valid security contexts
bool security_protected = nas->security_container->ciphering_context && nas->security_container->integrity_context;
bool security_protected = nas->security_container && nas->security_container->integrity_context;
// Set 5GMM plain header
fgmm_nas_message_plain_t plain = {0};
@@ -1010,23 +1010,72 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
// Service Type
mm_msg->serviceType = SERVICE_TYPE_DATA;
// NAS key set identifier
mm_msg->naskeysetidentifier.naskeysetidentifier = NAS_KEY_SET_IDENTIFIER_NOT_AVAILABLE;
mm_msg->naskeysetidentifier.tsc = NAS_KEY_SET_IDENTIFIER_NATIVE;
mm_msg->naskeysetidentifier.naskeysetidentifier = set_fgs_ksi(nas);
size += 1;
// 5G-S-TMSI
size += fill_fgstmsi(&mm_msg->fiveg_s_tmsi, nas->guti);
// PDU session status is a non-cleartext Service Request IE (TS 24.501 8.2.16.3).
// Here configured UE PDU sessions are marked active to trigger the NAS container path.
uint8_t pdu_session_status[MAX_NUM_PSI] = {0};
bool has_non_cleartext_ies = false;
for (int i = 0; i < nas->uicc->n_pdu_sessions; ++i) {
const int pdu_id = nas->uicc->pdu_sessions[i].id;
if (pdu_id > 0 && pdu_id < MAX_NUM_PSI) {
pdu_session_status[pdu_id] = PDU_SESSION_ACTIVE;
has_non_cleartext_ies = true;
}
}
/* message encoding */
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
if (security_protected) {
fgmm_nas_msg_security_protected_t sp = {0};
FGCNasMessageContainer nas_container = {0};
// Set security protected 5GS NAS message header (see 9.1.1 of 3GPP TS 24.501)
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;
const int plain_sr_size = size;
size += sizeof(sp.header);
// TS 24.501 4.4.6.b.1: when non-cleartext IEs are present, place the full Service Request
// in the NAS message container and cipher only that container value before outer integrity.
if (has_non_cleartext_ies) {
fgmm_nas_message_plain_t full_sr = plain;
fgs_service_request_msg_t *full_mm_msg = &full_sr.mm_msg.service_request;
full_mm_msg->has_pdu_session_status = true;
memcpy(full_mm_msg->pdu_session_status, pdu_session_status, sizeof(full_mm_msg->pdu_session_status));
const int full_sr_size = plain_sr_size + MIN_PDU_SESSION_CONTENTS_LEN + 2;
uint8_t *inner_sr = calloc_or_fail(full_sr_size, sizeof(*inner_sr));
const int inner_sr_len = mm_msg_encode(&full_sr, inner_sr, full_sr_size);
if (inner_sr_len <= 0) {
free(inner_sr);
AssertFatal(false, "Failed to encode Service Request NAS container payload\n");
}
nas_container.nasmessagecontainercontents.value = inner_sr;
nas_container.nasmessagecontainercontents.length = inner_sr_len;
uint8_t ciphered_container[inner_sr_len];
nas_stream_cipher_t container_cipher = {0};
AssertFatal(nas->security.nas_count_ul <= 0xffffff, "fatal: NAS COUNT UL too big (todo: fix that)\n");
container_cipher.context = nas->security_container->ciphering_context;
container_cipher.count = nas->security.nas_count_ul;
container_cipher.bearer = 1;
container_cipher.message = inner_sr;
container_cipher.blength = inner_sr_len << 3;
stream_compute_encrypt(nas->security_container->ciphering_algorithm, &container_cipher, ciphered_container);
memcpy(inner_sr, ciphered_container, inner_sr_len);
mm_msg->fgsnasmessagecontainer = &nas_container;
size += inner_sr_len + 3;
}
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
// Payload: plain message
sp.plain = plain;
@@ -1035,23 +1084,13 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
initialNasMsg->length =
security_header_len
+ mm_msg_encode(&sp.plain, (uint8_t *)(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];
nas_stream_cipher_t stream_cipher = {0};
stream_cipher.context = nas->security_container->integrity_context;
stream_cipher.count = nas->security.nas_count_ul++;
const uint32_t sr_ul_count = nas->security.nas_count_ul;
stream_cipher.count = sr_ul_count;
nas->security.nas_count_ul++;
stream_cipher.bearer = 1;
stream_cipher.direction = 0;
stream_cipher.message = (unsigned char *)(initialNasMsg->nas_data + 6);
@@ -1061,7 +1100,12 @@ void generateServiceRequest(as_nas_info_t *initialNasMsg, nr_ue_nas_t *nas)
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];
/* Keep AS security in sync with updated NAS UL count for post-paging reconnect */
derive_kgnb(nas->security.kamf, sr_ul_count, nas->security.kgnb);
nas_itti_kgnb_refresh_req(nas->UE_id, nas->security.kgnb);
} else {
initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data));
// plain encoding
initialNasMsg->length = mm_msg_encode(&plain, initialNasMsg->nas_data, size);
LOG_I(NAS, "PLAIN_5GS_MSG initial NAS message: Service Request with length %d \n", initialNasMsg->length);