From 4262203e2de1df6635a5daed6815b5915c009633 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 18 Feb 2025 07:27:57 +0000 Subject: [PATCH] Add NAS Security Mode Reject enc/dec lib and unit test This 5GMM message is required for an invalid security mode command, e.g. when the MAC integrity fails, or the wrong Security Header is set. * Add encode/decode functions for common IEs in fgmm_lib: this library provides encoding/decoding helpers for IEs shared across multiple NAS messages. The goal is to avoid the legacy approach of creating separate files per IE * add NAS Cause enc/dec lib * Adopted byte_array_t to handle the buffer Co-authored-by: Eduard Vlad --- .../NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt | 1 + .../5GS/5GMM/MSG/FGSNASSecurityModeReject.c | 50 +++++++++++++++++++ .../5GS/5GMM/MSG/FGSNASSecurityModeReject.h | 47 +++++++++++++++++ openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c | 33 ++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.c create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.h diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt index bf47e478b9..0f4445c353 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(fgs_5gmm_lib OBJECT FGSIdentityResponse.c FGSAuthenticationResponse.c FGSNASSecurityModeComplete.c + FGSNASSecurityModeReject.c RegistrationComplete.c FGSUplinkNasTransport.c FGSDeregistrationRequestUEOriginating.c diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.c new file mode 100644 index 0000000000..3f61b14ad7 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.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 +#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; +} diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.h new file mode 100644 index 0000000000..28c10e3700 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/FGSNASSecurityModeReject.h @@ -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 +#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_) */ diff --git a/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c b/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c index 88de4f13aa..f733bdd3a5 100644 --- a/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c +++ b/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c @@ -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; }