diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h new file mode 100644 index 0000000000..3735974889 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h @@ -0,0 +1,37 @@ +/* + * 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 +#include +#include "NasKeySetIdentifier.h" + +#ifndef FGS_AUTHENTICATION_REQUEST_H_ +#define FGS_AUTHENTICATION_REQUEST_H_ + +typedef struct { + // NAS key set identifier (Mandatory) + NasKeySetIdentifier ngKSI; + // ABBA (Mandatory) + int abba; +} fgs_authentication_request_t; + +#endif /* ! defined(FGS_AUTHENTICATION_REQUEST_H_) */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 3640c40aaa..a8c8f54ed7 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -49,6 +49,7 @@ #include "RegistrationAccept.h" #include "SORTransparentContainer.h" #include "FGSIdentityResponse.h" +#include "fgmm_authentication_request.h" #include "T.h" #include "aka_functions.h" #include "assertions.h" @@ -856,6 +857,40 @@ static void generateAuthenticationFailure(nr_ue_nas_t *nas, as_nas_info_t *initi initialNasMsg->length = mm_msg_encode(&plain, initialNasMsg->nas_data, size); } +static void handle_fgmm_authentication_request(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, byte_array_t *buffer) +{ + LOG_D(NAS, "Received NAS Authentication Request\n"); + fgs_authentication_request_t msg = {0}; + int size = 0; + int decoded = 0; + + // decode plain 5GMM message header + fgmm_msg_header_t mm_header = {0}; + if ((decoded = decode_5gmm_msg_header(&mm_header, buffer->buf + size, buffer->len - size)) < 0) { + LOG_E(NAS, "decode_5gmm_msg_header failure in NAS Authentication Request handling\n"); + return; + } + size += decoded; + // NAS key set identifier (Mandatory) + if ((decoded = decode_nas_key_set_identifier(&msg.ngKSI, 0, buffer->buf[decoded])) < 0) { + LOG_E(NAS, "decode_nas_key_set_identifier failure in NAS Authentication Request handling\n"); + return; + } + size += decoded; + if (!nas->ksi) { + nas->ksi = malloc_or_fail(sizeof(*nas->ksi)); + *nas->ksi = msg.ngKSI.naskeysetidentifier; + LOG_D(NAS, "Stored NAS Key Set Identifier %d\n", *nas->ksi); + } else if (*nas->ksi == msg.ngKSI.naskeysetidentifier) { + /* If the ngKSI value received is already associated with one + of the 5G security contexts stored in the UE, send failure message */ + LOG_E(NAS, "Invalid NAS Key Set Identifier: send Authentication Failure\n"); + generateAuthenticationFailure(nas, initialNasMsg, ngKSI_already_in_use); + return; + } + generateAuthenticationResp(nas, initialNasMsg, buffer->buf); +} + int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32]) { MessageDef *message_p; @@ -1735,9 +1770,11 @@ void *nas_nrue(void *args_p) case FGS_IDENTITY_REQUEST: generateIdentityResponse(&initialNasMsg, *(pdu_buffer + 3), nas->uicc); break; - case FGS_AUTHENTICATION_REQUEST: - generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer); + case FGS_AUTHENTICATION_REQUEST: { + byte_array_t buffer = {.buf = pdu_buffer, .len = pdu_length}; + handle_fgmm_authentication_request(nas, &initialNasMsg, &buffer); break; + } case FGS_SECURITY_MODE_COMMAND: handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length); break; diff --git a/openair3/NAS/NR_UE/nr_nas_msg.h b/openair3/NAS/NR_UE/nr_nas_msg.h index c4f1d04e28..4be7222920 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.h +++ b/openair3/NAS/NR_UE/nr_nas_msg.h @@ -102,6 +102,8 @@ typedef struct { int t3448; // Timer t3446 in seconds (-1 = disabled) int t3446; + /* NAS Key Set Identifier associated to the security context */ + uint8_t *ksi; } nr_ue_nas_t; nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);