diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c index 1b607589d9..e53e3a2993 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c @@ -25,8 +25,12 @@ #include // For malloc and free #include "common/utils/ds/byte_array.h" +#define IEI_LEN 1 #define GPRS_TIMER_LENGTH 3 // octets #define FGS_NAS_CAUSE_LENGTH 1 +#define MIN_EAP_MSG_LEN 7 +#define MIN_EAP_CONTENTS_LEN 4 +#define MAX_EAP_CONTENTS_LEN 1500 /** * Encode PDU Session Status and PDU session reactivation result (optional IEs) @@ -152,12 +156,72 @@ bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b) return true; } -/* Decode EAP Message (todo) */ -int decode_eap_msg_ie(const byte_array_t *buffer) +/** @brief Encode EAP message IE (3GPP TS 24.501 9.11.2.2) */ +int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg) { - int eap_msg_len = (buffer->buf[0] << 8) | buffer->buf[1]; - PRINT_NAS_ERROR("EAP message IE in NAS Service Reject is not handled\n"); - return eap_msg_len + 2; // content length + 2 octets for the length IE + int encoded = 0; + + // Sanity check on buffer length + if (buffer->len < MIN_EAP_MSG_LEN) { + PRINT_NAS_ERROR("Invalid buffer length %ld", buffer->len); + return -1; + } + + // Sanity check on input length + if (msg->len < MIN_EAP_CONTENTS_LEN || msg->len > MAX_EAP_CONTENTS_LEN) { + PRINT_NAS_ERROR("Invalid EAP message length %ld", msg->len); + return -1; + } + + // Encode IEI + buffer->buf[encoded++] = IEI_EAPMSG; + + // Encode length of EAP message content + uint16_t len = htons(msg->len); + memcpy(&buffer->buf[encoded], &len, sizeof(len)); + encoded += sizeof(len); + + // Encode EAP message content + memcpy(&buffer->buf[encoded], msg->buf, msg->len); + encoded += msg->len; + + return encoded; +} + +/** @brief Decode EAP message IE (3GPP TS 24.501 9.11.2.2): + length of contents and message payload */ +int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer) +{ + int decoded = 0; + int min_len_to_decode = MIN_EAP_MSG_LEN - IEI_LEN; + + // Check buffer length validity + if (buffer->len < min_len_to_decode) { + PRINT_NAS_ERROR("Invalid buffer for decoding EAP message IE"); + return -1; + } + + // Decode length IE + eap_msg->len = (buffer->buf[decoded] << 8) | buffer->buf[decoded + 1]; + decoded += 2; + + // Check payload length validity + if (eap_msg->len < MIN_EAP_CONTENTS_LEN || eap_msg->len > MAX_EAP_CONTENTS_LEN) { + PRINT_NAS_ERROR("Invalid EAP message length %ld", eap_msg->len); + return -1; + } + + // Check for buffer overflow + if (buffer->len < decoded + eap_msg->len) { + PRINT_NAS_ERROR("Buffer too short for EAP message: %ld < %ld", buffer->len, decoded + eap_msg->len); + return -1; + } + + // Copy EAP payload + memcpy(eap_msg->buf, &buffer->buf[decoded], eap_msg->len); + decoded += eap_msg->len; + + return decoded; } int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause) diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h index 25118f2742..7a4e1da857 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h @@ -164,7 +164,8 @@ int decode_pdu_session_ie(uint8_t *psi, const byte_array_t *buffer); int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs_timer_t *timer); int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer); bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b); -int decode_eap_msg_ie(const byte_array_t *buffer); +int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer); +int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg); int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause); int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer); diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.c index 797deede84..63e2901f61 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.c +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.c @@ -133,7 +133,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t break; case IEI_EAPMSG: - DECODE_NAS_IE(ba, decode_eap_msg_ie(&ba), decoded); + DECODE_NAS_IE(ba, decode_eap_msg_ie(&msg->eap_msg, &ba), decoded); break; default: diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.h index 9f82f47eb1..c5d042b674 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.h +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_accept.h @@ -47,6 +47,9 @@ typedef struct { // T3448 Value (Optional) gprs_timer_t *t3448; + + // EAP Message (Optional) + byte_array_t eap_msg; } fgs_service_accept_msg_t; int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t *buffer); diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.c index 74175fda36..14078637a3 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.c +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.c @@ -59,6 +59,11 @@ int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg ENCODE_NAS_IE(ba, encode_gprs_timer_ie(&ba, IEI_T3448_VALUE, msg->t3448), encoded); } + // EAP message (Optional) + if (msg->eap_msg) { + ENCODE_NAS_IE(ba, encode_eap_msg_ie(&ba, msg->eap_msg), encoded); + } + return encoded; } @@ -99,7 +104,7 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t break; case IEI_EAPMSG: - DECODE_NAS_IE(ba, decode_eap_msg_ie((const byte_array_t *)&ba), decoded); + DECODE_NAS_IE(ba, decode_eap_msg_ie(msg->eap_msg, &ba), decoded); break; case IEI_CAG_INFO_LIST: { diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.h index 61337d8525..29c8ab9b72 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.h +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_service_reject.h @@ -35,6 +35,8 @@ typedef struct { bool has_psi_status; // T3448 Value (Optional) gprs_timer_t *t3448; + // EAP message (optional) + byte_array_t *eap_msg; } fgs_service_reject_msg_t; int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t *buffer);