Add NAS Authentication Failure enc/dec lib and unit tests
This commit is contained in:
@@ -11,6 +11,7 @@ add_library(fgs_5gmm_lib OBJECT
|
||||
RegistrationComplete.c
|
||||
FGSUplinkNasTransport.c
|
||||
FGSDeregistrationRequestUEOriginating.c
|
||||
fgmm_authentication_failure.c
|
||||
)
|
||||
|
||||
target_link_libraries(fgs_5gmm_lib PUBLIC fgs_5gmm_ies_lib)
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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_failure.h"
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h> // For htons and ntohs
|
||||
#include <stdlib.h> // For malloc and free
|
||||
#include "fgmm_lib.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
#define MIN_AUTH_FAILURE_LEN 1
|
||||
#define AUTH_FAILURE_PARAM_LEN 16
|
||||
#define AUTH_FAIL_PARAM_IEI 0x30
|
||||
|
||||
/** @brief Encode Authentication Failure (8.2.4 of 3GPP TS 24.501) */
|
||||
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg)
|
||||
{
|
||||
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
|
||||
PRINT_NAS_ERROR("Missing mandatory IE in Authentication Failure");
|
||||
return -1; // missing mandatory IE
|
||||
}
|
||||
// 5GMM cause (Mandatory)
|
||||
int encoded = encode_fgs_nas_cause(buffer, &msg->cause);
|
||||
// Authentication failure parameter (see 8.2.4.2 3GPP TS 24.501)
|
||||
if (msg->cause == Synch_failure) {
|
||||
// Authentication failure parameter shall be present with cause Synch Failure
|
||||
if (msg->authentication_failure_param.len == 0) {
|
||||
PRINT_NAS_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
|
||||
return -1;
|
||||
}
|
||||
if (buffer->len - encoded < msg->authentication_failure_param.len + 2) {
|
||||
PRINT_NAS_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
|
||||
return -1;
|
||||
}
|
||||
// Encode the IEI
|
||||
buffer->buf[encoded++] = AUTH_FAIL_PARAM_IEI;
|
||||
buffer->buf[encoded++] = msg->authentication_failure_param.len;
|
||||
for (int i = 0; i < msg->authentication_failure_param.len; i++) {
|
||||
buffer->buf[encoded++] = msg->authentication_failure_param.buf[i];
|
||||
}
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/** @brief Decode Authentication Failure (8.2.4 of 3GPP TS 24.501) */
|
||||
int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer)
|
||||
{
|
||||
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
|
||||
return -1; // missing mandatory IE
|
||||
}
|
||||
byte_array_t ba = *buffer; // Local copy of buffer
|
||||
// 5GMM Cause (Mandatory)
|
||||
uint32_t decoded = decode_fgs_nas_cause(&msg->cause, buffer);
|
||||
// Authentication Failure Parameters (Optional)
|
||||
if (msg->cause == Synch_failure) {
|
||||
uint8_t iei = buffer->buf[decoded++];
|
||||
if (iei == AUTH_FAIL_PARAM_IEI) {
|
||||
msg->authentication_failure_param.len = ba.buf[decoded++];
|
||||
if (msg->authentication_failure_param.len > AUTH_FAILURE_PARAM_LEN - 2) { // maximum length of contents is 14 octets
|
||||
PRINT_NAS_ERROR("Length of Authentication Failure Parameter contents is too large");
|
||||
return -1;
|
||||
}
|
||||
msg->authentication_failure_param.buf = malloc_or_fail(msg->authentication_failure_param.len);
|
||||
for (int i = 0; i < msg->authentication_failure_param.len; i++) {
|
||||
msg->authentication_failure_param.buf[i] = buffer->buf[decoded++];
|
||||
}
|
||||
}
|
||||
}
|
||||
return decoded;
|
||||
}
|
||||
|
||||
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b)
|
||||
{
|
||||
_NAS_EQ_CHECK_INT(a->cause, b->cause);
|
||||
eq_byte_array(&a->authentication_failure_param, &b->authentication_failure_param);
|
||||
return true;
|
||||
}
|
||||
|
||||
void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg)
|
||||
{
|
||||
free(msg->authentication_failure_param.buf);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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_FAILURE_H
|
||||
#define FGMM_AUTH_FAILURE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fgmm_lib.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
typedef struct {
|
||||
// 5GMM cause (Mandatory)
|
||||
cause_id_t cause;
|
||||
// Authentication failure parameter (Optional)
|
||||
byte_array_t authentication_failure_param;
|
||||
} fgmm_auth_failure_t;
|
||||
|
||||
int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer);
|
||||
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg);
|
||||
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b);
|
||||
void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg);
|
||||
|
||||
#endif /* FGMM_AUTH_FAILURE_H */
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
|
||||
#define GPRS_TIMER_LENGTH 3 // octets
|
||||
#define FGS_NAS_CAUSE_LENGTH 1
|
||||
|
||||
/**
|
||||
* Encode PDU Session Status and PDU session reactivation result (optional IEs)
|
||||
@@ -158,3 +159,27 @@ int decode_eap_msg_ie(const byte_array_t *buffer)
|
||||
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 encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause)
|
||||
{
|
||||
uint32_t encoded = 0;
|
||||
|
||||
if (buffer->len < FGS_NAS_CAUSE_LENGTH)
|
||||
return -1;
|
||||
|
||||
buffer->buf[encoded++] = *cause;
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer)
|
||||
{
|
||||
int decoded = 0;
|
||||
|
||||
if (buffer->len < FGS_NAS_CAUSE_LENGTH)
|
||||
return -1; // nothing to decode
|
||||
|
||||
*cause = buffer->buf[decoded++];
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
@@ -165,5 +165,7 @@ int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs
|
||||
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 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);
|
||||
|
||||
#endif /* FGS_LIB_H */
|
||||
@@ -12,6 +12,7 @@ target_link_libraries(fgs_lib PUBLIC
|
||||
fgs_5gsm_lib
|
||||
fgs_5gmm_ies_lib
|
||||
nas_common_ies_lib
|
||||
ds
|
||||
)
|
||||
|
||||
target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "fgs_service_request.h"
|
||||
#include "fgmm_service_accept.h"
|
||||
#include "fgmm_service_reject.h"
|
||||
#include "fgmm_authentication_failure.h"
|
||||
#include "nr_nas_msg.h"
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
@@ -170,10 +171,46 @@ static void test_service_reject(void)
|
||||
free_fgs_service_reject(&orig);
|
||||
}
|
||||
|
||||
/** @brief Test NAS Authentication Failure enc/dec */
|
||||
static void test_auth_failure(void)
|
||||
{
|
||||
// Dummy NAS Authentication Failure message
|
||||
uint8_t afp[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
const fgmm_auth_failure_t orig = {
|
||||
.cause = Synch_failure,
|
||||
.authentication_failure_param.len = 6,
|
||||
.authentication_failure_param.buf = afp,
|
||||
};
|
||||
|
||||
// Expected encoded data
|
||||
uint8_t expected_enc[] = {0x15, 0x30, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
|
||||
// Buffer
|
||||
uint8_t buf[16] = {0};
|
||||
byte_array_t buffer = {.buf = buf, .len = sizeof(buf)};
|
||||
|
||||
// Encode
|
||||
int encoded_length = encode_fgmm_auth_failure(&buffer, &orig);
|
||||
AssertFatal(encoded_length == sizeofArray(expected_enc), "encode_fgmm_auth_failure() failed\n");
|
||||
|
||||
// Compare the raw encoded buffer with expected encoded data
|
||||
AssertFatal(memcmp(buffer.buf, expected_enc, encoded_length) == 0, "Encoding mismatch!\n");
|
||||
|
||||
// Decode
|
||||
fgmm_auth_failure_t dec = {0};
|
||||
int decoded_length = decode_fgmm_auth_failure(&dec, &buffer);
|
||||
AssertFatal(decoded_length >= 0, "decode_fgmm_auth_failure() failed\n");
|
||||
|
||||
// Compare original and decoded messages
|
||||
AssertFatal(eq_fgmm_auth_failure(&orig, &dec), "test_auth_failure() failed: original and decoded messages do not match\n");
|
||||
free_fgmm_auth_failure(&dec);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_service_request();
|
||||
test_service_accept();
|
||||
test_service_reject();
|
||||
test_auth_failure();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ target_link_libraries(nr_nas PUBLIC
|
||||
fgs_5gmm_ies_lib
|
||||
nas_common_ies_lib
|
||||
nas_utils
|
||||
ds
|
||||
)
|
||||
|
||||
target_include_directories(nr_nas PUBLIC . 5GS/)
|
||||
|
||||
Reference in New Issue
Block a user