From 299ce4a9bd247984df5fe578eaa92d264bb86002 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 15 Nov 2024 22:44:56 +0100 Subject: [PATCH] Add enc/dec lib for NAS Authentication Reject and unit test --- .../NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt | 1 + .../5GS/5GMM/MSG/fgmm_authentication_reject.c | 69 +++++++++++++++++++ .../5GS/5GMM/MSG/fgmm_authentication_reject.h | 38 ++++++++++ openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c | 40 +++++++++++ 4 files changed, 148 insertions(+) create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.c create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.h diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt index 0f4445c353..7aafc588e2 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt @@ -14,6 +14,7 @@ add_library(fgs_5gmm_lib OBJECT FGSUplinkNasTransport.c FGSDeregistrationRequestUEOriginating.c fgmm_authentication_failure.c + fgmm_authentication_reject.c ) target_link_libraries(fgs_5gmm_lib PUBLIC fgs_5gmm_ies_lib) diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.c new file mode 100644 index 0000000000..193df8f7dd --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.c @@ -0,0 +1,69 @@ +/* + * 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 "fgmm_authentication_reject.h" +#include +#include // For htons and ntohs +#include // For malloc and free +#include "fgmm_lib.h" + +#define MIN_AUTH_REJECT_LEN 3 + +/** @brief Encode Authentication Reject (8.2.5 of 3GPP TS 24.501) */ +int encode_fgmm_auth_reject(byte_array_t *buffer, const fgmm_auth_reject_msg_t *msg) +{ + uint32_t encoded = 0; + + const byte_array_t *eap_msg = &msg->eap_msg; + if (eap_msg->len > 0) { + return encode_eap_msg_ie(buffer, eap_msg); + } + return encoded; +} + +/** @brief Decode Authentication Reject (8.2.5 of 3GPP TS 24.501) + * the message contains only optional IEIs (EAP MSG) */ +int decode_fgmm_auth_reject(fgmm_auth_reject_msg_t *msg, const byte_array_t *buffer) +{ + if (buffer->len < MIN_AUTH_REJECT_LEN) { + // No optional IEIs present + return 0; + } + byte_array_t ba = *buffer; // Local copy of buffer + uint32_t decoded = 0; + // Decode the IEI + uint8_t iei = buffer->buf[decoded++]; + UPDATE_BYTE_ARRAY(ba, decoded); + if (iei == IEI_EAPMSG) { + return (decoded + decode_eap_msg_ie(&msg->eap_msg, &ba)); + } + PRINT_NAS_ERROR("Expected EAP MSG but it is not present"); + return -1; +} + +bool eq_auth_reject(fgmm_auth_reject_msg_t *a, fgmm_auth_reject_msg_t *b) +{ + _NAS_EQ_CHECK_LONG(a->eap_msg.len, b->eap_msg.len); + if (a->eap_msg.len > 0) { + return !memcmp(a->eap_msg.buf, b->eap_msg.buf, a->eap_msg.len); + } + return true; +} diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.h new file mode 100644 index 0000000000..33ae7a5181 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_reject.h @@ -0,0 +1,38 @@ +/* + * 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 FGMM_AUTH_REJECT_H +#define FGMM_AUTH_REJECT_H + +#include +#include "fgmm_lib.h" +#include "common/utils/ds/byte_array.h" + +typedef struct { + // EAP Message (Optional) + byte_array_t eap_msg; +} fgmm_auth_reject_msg_t; + +int decode_fgmm_auth_reject(fgmm_auth_reject_msg_t *msg, const byte_array_t *buffer); +int encode_fgmm_auth_reject(byte_array_t *buffer, const fgmm_auth_reject_msg_t *msg); +bool eq_auth_reject(fgmm_auth_reject_msg_t *a, fgmm_auth_reject_msg_t *b); + +#endif /* FGMM_AUTH_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 f733bdd3a5..d9f837d6b0 100644 --- a/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c +++ b/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c @@ -9,6 +9,7 @@ #include "fgmm_service_reject.h" #include "fgmm_authentication_failure.h" #include "FGSNASSecurityModeReject.h" +#include "fgmm_authentication_reject.h" #include "nr_nas_msg.h" void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) @@ -298,6 +299,44 @@ static void test_security_mode_reject(void) AssertFatal(eq_sec_mode_reject(&orig, &dec), "test_sec_mode_reject() failed: original and decoded messages do not match\n"); } +/** + * @brief Test NAS Authentication Reject enc/dec + */ +static void test_auth_reject(void) +{ + // Dummy NAS Authentication Reject message + uint8_t dummy_eap_msg[] = {0x12, 0x34, 0x56, 0x78, 0x91, 0x01, 0x23}; // Example EAP message + fgmm_auth_reject_msg_t orig = { + .eap_msg.len = sizeof(dummy_eap_msg), + }; + orig.eap_msg.buf = dummy_eap_msg; + + // Expected encoded data + uint8_t expected_enc[] = {0x78, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78, 0x91, 0x01, 0x23}; + + // Buffer + uint8_t buf[10] = {0}; + byte_array_t buffer = {.buf = buf, .len = sizeof(buf)}; + + // Encode + int encoded_length = encode_fgmm_auth_reject(&buffer, &orig); + AssertFatal(encoded_length >= 0, "encode_fgmm_auth_reject() failed\n"); + + // Compare the raw encoded buffer with expected encoded data + AssertFatal(encoded_length == sizeof(expected_enc), "Encoded length mismatch %d != %ld \n", encoded_length, sizeof(expected_enc)); + AssertFatal(memcmp(buffer.buf, expected_enc, encoded_length) == 0, "Encoding mismatch!\n"); + + // Decode + fgmm_auth_reject_msg_t dec = {0}; + uint8_t eap_msg[1500] = {0}; + dec.eap_msg.buf = eap_msg; + int decoded_length = decode_fgmm_auth_reject(&dec, &buffer); + AssertFatal(decoded_length >= 0, "decode_fgmm_auth_reject() failed\n"); + + // Compare original and decoded messages + AssertFatal(eq_auth_reject(&orig, &dec), "test_auth_reject() failed: original and decoded messages do not match\n"); +} + int main() { test_regression_registration_accept(); @@ -305,6 +344,7 @@ int main() test_service_accept(); test_service_reject(); test_auth_failure(); + test_auth_reject(); test_security_mode_reject(); return 0; }