From 2817ad4d29ec4b07723c71715b5f118ccc479bff Mon Sep 17 00:00:00 2001 From: Cedric Roux <cedric.roux@eurecom.fr> Date: Thu, 5 Dec 2013 13:14:43 +0000 Subject: [PATCH] - Added upper layer support for NAS MME * Correctly fetch user authentication vector from HSS * Trigger authentication procedure based on the returned vector - Removed unused security types git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4608 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/COMMON/common_types.h | 8 +- openair-cn/COMMON/messages_types.h | 2 + openair-cn/COMMON/nas_messages_def.h | 8 +- openair-cn/COMMON/nas_messages_types.h | 34 ++++- openair-cn/COMMON/security_types.h | 65 +-------- openair-cn/MME_APP/Makefile.am | 1 + openair-cn/MME_APP/mme_app_authentication.c | 137 ++++++++++++------ openair-cn/MME_APP/mme_app_context.c | 6 +- openair-cn/MME_APP/mme_app_defs.h | 5 +- openair-cn/MME_APP/mme_app_main.c | 8 +- openair-cn/MME_APP/mme_app_ue_context.h | 14 +- openair-cn/MME_APP/s6a_2_nas_cause.c | 25 +--- openair-cn/Makefile.am | 2 +- openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c | 72 +++++---- openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h | 2 + .../NAS/EURECOM-NAS/src/emm/sap/emm_as.c | 31 ++-- .../NAS/EURECOM-NAS/src/emm/sap/emm_cn.c | 134 +++++++++++++++++ .../NAS/EURECOM-NAS/src/emm/sap/emm_cn.h | 28 ++++ .../NAS/EURECOM-NAS/src/emm/sap/emm_cnDef.h | 48 ++++++ .../NAS/EURECOM-NAS/src/emm/sap/emm_sap.c | 16 +- .../NAS/EURECOM-NAS/src/emm/sap/emm_sap.h | 33 +++-- .../NAS/EURECOM-NAS/src/include/securityDef.h | 17 ++- openair-cn/NAS/EURECOM-NAS/src/nas_proc.c | 36 ++++- openair-cn/NAS/EURECOM-NAS/src/nas_proc.h | 12 ++ .../NAS/EURECOM-NAS/src/util/OctetString.h | 4 +- openair-cn/NAS/Makefile.inc | 3 +- openair-cn/NAS/nas_itti_messaging.c | 4 +- openair-cn/NAS/nas_itti_messaging.h | 49 ++++++- openair-cn/NAS/nas_main.c | 14 +- openair-cn/S6A/s6a_auth_info.c | 26 ++-- 30 files changed, 608 insertions(+), 236 deletions(-) create mode 100644 openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c create mode 100644 openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.h create mode 100644 openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cnDef.h diff --git a/openair-cn/COMMON/common_types.h b/openair-cn/COMMON/common_types.h index 74af62ef085..3631ce6b588 100644 --- a/openair-cn/COMMON/common_types.h +++ b/openair-cn/COMMON/common_types.h @@ -32,6 +32,8 @@ #include "commonDef.h" +#include "security_types.h" + #include "queue.h" #ifndef COMMON_TYPES_H_ @@ -215,9 +217,9 @@ typedef struct { rau_tau_timer_t rau_tau_timer; } subscription_data_t; -typedef struct { - uint8_t nb_of_vectors; - STAILQ_HEAD(e_utran_vector_list, eutran_vector_s) e_utran_vectors; +typedef struct authentication_info_s { + uint8_t nb_of_vectors; + eutran_vector_t eutran_vector; } authentication_info_t; typedef enum { diff --git a/openair-cn/COMMON/messages_types.h b/openair-cn/COMMON/messages_types.h index fc5048c4510..e73fc627931 100644 --- a/openair-cn/COMMON/messages_types.h +++ b/openair-cn/COMMON/messages_types.h @@ -10,6 +10,8 @@ #include "timer_messages_types.h" +#include "security_types.h" + #include "gtpv1_u_messages_types.h" #include "ip_forward_messages_types.h" #include "mme_app_messages_types.h" diff --git a/openair-cn/COMMON/nas_messages_def.h b/openair-cn/COMMON/nas_messages_def.h index a7a1e3154e0..d01c51d648e 100644 --- a/openair-cn/COMMON/nas_messages_def.h +++ b/openair-cn/COMMON/nas_messages_def.h @@ -13,14 +13,16 @@ MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_RESP, MESSAGE_PRIORITY_MED, nas_rab_est_ MESSAGE_DEF(NAS_RAB_RELEASE_REQ, MESSAGE_PRIORITY_MED, nas_rab_rel_req_t, nas_rab_rel_req) /* NAS layer -> MME app messages */ -MESSAGE_DEF(NAS_AUTHENTICATION_REQ, MESSAGE_PRIORITY_MED, nas_auth_req_t, nas_auth_req) MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_REQ, MESSAGE_PRIORITY_MED, nas_auth_param_req_t, nas_auth_param_req) /* MME app -> NAS layer messages */ -MESSAGE_DEF(NAS_BEARER_PARAM, MESSAGE_PRIORITY_MED, nas_bearer_param_t, nas_bearer_param) -MESSAGE_DEF(NAS_AUTHENTICATION_RESP, MESSAGE_PRIORITY_MED, nas_auth_resp_t, nas_auth_resp) +MESSAGE_DEF(NAS_BEARER_PARAM, MESSAGE_PRIORITY_MED, nas_bearer_param_t, nas_bearer_param) +MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_RSP, MESSAGE_PRIORITY_MED, nas_auth_param_rsp_t, nas_auth_param_rsp) +MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_FAIL, MESSAGE_PRIORITY_MED, nas_auth_param_fail_t, nas_auth_param_fail) #if defined(DISABLE_USE_NAS) MESSAGE_DEF(NAS_ATTACH_REQ, MESSAGE_PRIORITY_MED, nas_attach_req_t, nas_attach_req) MESSAGE_DEF(NAS_ATTACH_ACCEPT, MESSAGE_PRIORITY_MED, nas_attach_accept_t, nas_attach_accept) +MESSAGE_DEF(NAS_AUTHENTICATION_RESP, MESSAGE_PRIORITY_MED, nas_auth_resp_t, nas_auth_resp) +MESSAGE_DEF(NAS_AUTHENTICATION_REQ, MESSAGE_PRIORITY_MED, nas_auth_req_t, nas_auth_req) #endif \ No newline at end of file diff --git a/openair-cn/COMMON/nas_messages_types.h b/openair-cn/COMMON/nas_messages_types.h index 7031eec40c1..a3a0fa1349a 100644 --- a/openair-cn/COMMON/nas_messages_types.h +++ b/openair-cn/COMMON/nas_messages_types.h @@ -11,6 +11,8 @@ #define NAS_BEARER_PARAM(mSGpTR) (mSGpTR)->ittiMsg.nas_bearer_param #define NAS_AUTHENTICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_req #define NAS_AUTHENTICATION_PARAM_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_req +#define NAS_AUTHENTICATION_PARAM_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_rsp +#define NAS_AUTHENTICATION_PARAM_FAIL(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_fail typedef struct { @@ -25,6 +27,8 @@ typedef struct { s1ap_initial_ue_message_t transparent; } nas_conn_est_ind_t; +typedef nas_establish_rsp_t nas_conn_est_rej_t; + typedef struct nas_conn_est_cnf_s { uint32_t ue_id; @@ -107,12 +111,36 @@ typedef struct { } nas_auth_resp_t; typedef struct nas_auth_param_req_s { - uint8_t imsi_length; - char imsi[15]; + /* UE identifier */ + uint32_t ue_id; + + /* Imsi of the UE (In case of initial request) */ + char imsi[16]; + uint8_t imsi_length; - uint8_t initial_req:1; + /* Indicates whether the procedure corresponds to a new connection or not */ + uint8_t initial_req:1; } nas_auth_param_req_t; +typedef struct nas_auth_param_rsp_s { + /* UE identifier */ + uint32_t ue_id; + + /* For future use: nb of vectors provided */ + uint8_t nb_vectors; + + /* Consider only one E-UTRAN vector for the moment... */ + eutran_vector_t vector; +} nas_auth_param_rsp_t; + +typedef struct nas_auth_param_fail_s { + /* UE identifier */ + uint32_t ue_id; + + /* S6A mapped to NAS cause */ + nas_cause_t cause; +} nas_auth_param_fail_t; + typedef struct nas_attach_accept_s { } nas_attach_accept_t; diff --git a/openair-cn/COMMON/security_types.h b/openair-cn/COMMON/security_types.h index 9affe8ad1ce..1806a39efd3 100644 --- a/openair-cn/COMMON/security_types.h +++ b/openair-cn/COMMON/security_types.h @@ -35,65 +35,6 @@ sscanf(sTRING, "%" SCNu64, cONTAINER) */ -/* GCC supports 128 bits integers on certain architectures */ -#if defined(ENABLE_GMP_TYPES) -/* Use gmplib in case GCC doesn't support 128 bits integers natively */ -typedef mpz_t rand_t; -typedef mpz_t auth_key_t; -typedef mpz_t auth_res_t; -typedef mpz_t kasme_t; -typedef mpz_t autn_t; - -/* RES amd XRES can have a variable length of 4-16 octets */ -typedef struct { - ssize_t size; - auth_res_t data; -} res_t; - -/* Converts a string to 128 bits gmplib integer holder */ -# define STRING_TO_XBITS(sTRING, lENGTH, cONTAINER, rET) \ -do { \ - char temp[129]; \ - if (lENGTH > 64) { \ - rET = -1; \ - } else { \ - hexa_to_ascii(sTRING, temp, lENGTH); \ - temp[2 * lENGTH] = '\0'; \ - rET = mpz_init_set_str (cONTAINER, temp, 16); \ - } \ -} while(0) - -# define STRING_TO_128BITS(sTRING, cONTAINER, rET) \ -STRING_TO_XBITS(sTRING, 16, cONTAINER, rET) - -# define STRING_TO_256BITS(sTRING, cONTAINER, rET) \ -STRING_TO_XBITS(sTRING, 32, cONTAINER, rET) - -# define STRING_TO_RAND STRING_TO_128BITS -# define STRING_TO_AUTH_KEY STRING_TO_128BITS -# define STRING_TO_AUTH_RES STRING_TO_128BITS -# define STRING_TO_AUTN STRING_TO_128BITS -# define STRING_TO_KASME STRING_TO_256BITS -# define STRING_TO_XRES(sTRING, lENGTH, cONTAINER, rET) \ -do { \ - STRING_TO_XBITS(sTRING, lENGTH, (cONTAINER)->data, rET); \ - if (rET != -1) \ - (cONTAINER)->size = mpz_sizeinbase((cONTAINER)->data, 16); \ -} while(0) - -/* Holds an E-UTRAN authentication vector */ -typedef struct eutran_vector_s { - rand_t rand; - res_t xres; - autn_t autn; - kasme_t kasme; - - /* one UE can have multiple vectors so use STAILQ lists for easy management */ - STAILQ_ENTRY(eutran_vector_s) entries; -} eutran_vector_t; - -#else /* defined(ENABLE_GMP_TYPES) */ - /* Converts a string to 128 bits gmplib integer holder */ # define STRING_TO_XBITS(sTRING, lENGTH, cONTAINER, rET) \ do { \ @@ -121,7 +62,7 @@ do { \ /* RES amd XRES can have a variable length of 4-16 octets */ typedef struct { - ssize_t size; + uint8_t size; uint8_t data[XRES_LENGTH_MAX]; } res_t; @@ -151,11 +92,11 @@ typedef struct eutran_vector_s { uint8_t kasme[KASME_LENGTH_OCTETS]; /* one UE can have multiple vectors so use STAILQ lists for easy management */ +#if 0 STAILQ_ENTRY(eutran_vector_s) entries; +#endif } eutran_vector_t; -#endif /* defined(ENABLE_GMP_TYPES) */ - #define FC_KASME (0x10) #define FC_KENB (0x11) #define FC_NH (0x12) diff --git a/openair-cn/MME_APP/Makefile.am b/openair-cn/MME_APP/Makefile.am index 6ee2feae263..89abde0d8ff 100644 --- a/openair-cn/MME_APP/Makefile.am +++ b/openair-cn/MME_APP/Makefile.am @@ -20,4 +20,5 @@ libmmeapp_la_SOURCES = \ mme_app_authentication.c \ mme_app_statistics.c mme_app_statistics.h \ mme_app_defs.h mme_app_extern.h \ + mme_app_itti_messaging.h \ s6a_2_nas_cause.c diff --git a/openair-cn/MME_APP/mme_app_authentication.c b/openair-cn/MME_APP/mme_app_authentication.c index 448c9872360..d0ed75c1499 100644 --- a/openair-cn/MME_APP/mme_app_authentication.c +++ b/openair-cn/MME_APP/mme_app_authentication.c @@ -31,8 +31,10 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "intertask_interface.h" +#include "mme_app_itti_messaging.h" #include "mme_config.h" @@ -56,8 +58,6 @@ int mme_app_request_authentication_info(const mme_app_imsi_t imsi, message_p = itti_alloc_new_message(TASK_MME_APP, S6A_AUTH_INFO_REQ); - if (message_p == NULL) return -1; - auth_info_req = &message_p->ittiMsg.s6a_auth_info_req; MME_APP_IMSI_TO_STRING(imsi, auth_info_req->imsi); memcpy(&auth_info_req->visited_plmn, plmn, sizeof(plmn_t)); @@ -77,7 +77,8 @@ int mme_app_handle_nas_auth_resp(nas_auth_resp_t *nas_auth_resp_p) MME_APP_DEBUG("Handling imsi %"IMSI_FORMAT"\n", imsi); - if ((ue_context = mme_ue_context_exists_imsi(&mme_app_desc.mme_ue_contexts, imsi)) == NULL) { + if ((ue_context = mme_ue_context_exists_imsi(&mme_app_desc.mme_ue_contexts, + imsi)) == NULL) { MME_APP_ERROR("That's embarrassing as we don't know this IMSI\n"); return -1; } @@ -111,39 +112,26 @@ int mme_app_handle_nas_auth_resp(nas_auth_resp_t *nas_auth_resp_p) return -1; } -int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t *s6a_auth_info_ans_p) +int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t + *s6a_auth_info_ans_p) { struct ue_context_s *ue_context; uint64_t imsi; - nas_auth_req_t *nas_auth_req_p; - MessageDef *message_p = NULL; - DevAssert(s6a_auth_info_ans_p != NULL); - message_p = itti_alloc_new_message(TASK_MME_APP, NAS_AUTHENTICATION_REQ); - - if (message_p == NULL) { - return -1; - } - - nas_auth_req_p = &message_p->ittiMsg.nas_auth_req; - MME_APP_STRING_TO_IMSI((char *)s6a_auth_info_ans_p->imsi, &imsi); MME_APP_DEBUG("Handling imsi %"IMSI_FORMAT"\n", imsi); - memcpy(nas_auth_req_p->imsi, s6a_auth_info_ans_p->imsi, 16); - - if ((ue_context = mme_ue_context_exists_imsi(&mme_app_desc.mme_ue_contexts, imsi)) == NULL) { + if ((ue_context = mme_ue_context_exists_imsi(&mme_app_desc.mme_ue_contexts, + imsi)) == NULL) { MME_APP_ERROR("That's embarrassing as we don't know this IMSI\n"); - free(message_p); return -1; } if ((s6a_auth_info_ans_p->result.present == S6A_RESULT_BASE) && - (s6a_auth_info_ans_p->result.choice.base == DIAMETER_SUCCESS)) - { + (s6a_auth_info_ans_p->result.choice.base == DIAMETER_SUCCESS)) { /* S6A procedure has succeeded. * We have to request UE authentication. */ @@ -151,28 +139,37 @@ int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t *s6a_auth_info /* Check that list is not empty and contain only one element */ DevCheck(s6a_auth_info_ans_p->auth_info.nb_of_vectors == 1, s6a_auth_info_ans_p->auth_info.nb_of_vectors, 1, 0); - DevAssert(!STAILQ_EMPTY(&s6a_auth_info_ans_p->auth_info.e_utran_vectors)); - /* Concat both lists */ - STAILQ_CONCAT(&ue_context->vector_list, - &s6a_auth_info_ans_p->auth_info.e_utran_vectors); - - ue_context->nb_of_vectors += s6a_auth_info_ans_p->auth_info.nb_of_vectors; + if (ue_context->vector_list == NULL) { + ue_context->vector_list = malloc(sizeof(eutran_vector_t)); + DevAssert(ue_context->vector_list != NULL); + } else { + /* Some vector already exist */ + ue_context->vector_list = realloc(ue_context->vector_list, + (ue_context->nb_of_vectors + 1) * sizeof(eutran_vector_t)); + DevAssert(ue_context->vector_list != NULL); + } + memcpy(&ue_context->vector_list[ue_context->nb_of_vectors], + &s6a_auth_info_ans_p->auth_info.eutran_vector, sizeof(eutran_vector_t)); - nas_auth_req_p->failure = NAS_FAILURE_OK; + ue_context->vector_in_use = &ue_context->vector_list[ue_context->nb_of_vectors]; - ue_context->vector_in_use = STAILQ_FIRST(&ue_context->vector_list); + ue_context->nb_of_vectors += s6a_auth_info_ans_p->auth_info.nb_of_vectors; -// mme_app_dump_ue_contexts(); + mme_app_itti_auth_rsp(ue_context->ue_id, 1, + &s6a_auth_info_ans_p->auth_info.eutran_vector); } else { - // nas_auth_req_p->failure = NAS_FAILURE_IND; - // nas_auth_req_p->cause = s6a_error_2_nas_cause( -// s6a_auth_info_ans_p->result.choice.base, 0); - DevMessage("TODO: Handle s6a_auth_info_ans_p->result.present " - "!= S6A_RESULT_BASE"); + /* Inform NAS layer with the right failure */ + if (s6a_auth_info_ans_p->result.present == S6A_RESULT_BASE) { + mme_app_itti_auth_fail(ue_context->ue_id, s6a_error_2_nas_cause( + s6a_auth_info_ans_p->result.choice.base, 0)); + } else { + mme_app_itti_auth_fail(ue_context->ue_id, s6a_error_2_nas_cause( + s6a_auth_info_ans_p->result.choice.experimental, 1)); + } } - return itti_send_msg_to_task(TASK_NAS, INSTANCE_DEFAULT, message_p); + return 0; } #if defined(DISABLE_USE_NAS) @@ -227,16 +224,14 @@ int mme_app_handle_attach_req(nas_attach_req_t *attach_req_p) ue_context->mme_ue_s1ap_id = attach_req_p->transparent.mme_ue_s1ap_id; if ((ue_context->imsi_auth == IMSI_AUTHENTICATED) && - (attach_req_p->initial != INITIAL_REQUEST)) - { + (attach_req_p->initial != INITIAL_REQUEST)) { /* We have to send an update location request to the HSS */ MME_APP_DEBUG("UE is authenticated\n"); } else { MME_APP_DEBUG("UE is not authenticated\n"); /* UE is not authenticated or an initial request */ if (STAILQ_EMPTY(&ue_context->vector_list)) -request_auth: - { +request_auth: { /* We have no vector for this UE, send an authentication request * to the HSS. */ @@ -250,7 +245,7 @@ request_auth: }; memcpy(&ue_context->e_utran_cgi, &attach_req_p->transparent.e_utran_cgi, - sizeof(cgi_t)); + sizeof(cgi_t)); /* Acquire the current time */ time(&ue_context->cell_age); @@ -270,8 +265,8 @@ request_auth: MessageDef *message_p; /* We have a vector... USE it */ MME_APP_DEBUG("but we have an auth. vector for it, request" - " authentication from NAS\n"); - message_p = itti_alloc_new_message(TASK_MME_APP, NAS_AUTHENTICATION_REQ); + " authentication from NAS\n"); + message_p = itti_alloc_new_message(TASK_MME_APP, NAS_AUTHENTICATION_PARAM_FAIL); nas_auth_req_p = &message_p->ittiMsg.nas_auth_req; @@ -284,4 +279,60 @@ request_auth: } return 0; } +#else +void mme_app_handle_nas_auth_param_req(nas_auth_param_req_t + *nas_auth_param_req_p) +{ + struct ue_context_s *ue_context; + uint64_t imsi = 0; + + DevAssert(nas_auth_param_req_p != NULL); + + MME_APP_STRING_TO_IMSI(nas_auth_param_req_p->imsi, &imsi); + + MME_APP_DEBUG("Handling imsi %"IMSI_FORMAT"\n", imsi); + + /* Fetch the context associated with this IMSI */ + ue_context = mme_ue_context_exists_imsi(&mme_app_desc.mme_ue_contexts, imsi); + + if (ue_context == NULL) { + /* Currently no context available -> trigger an authentication request + * to the HSS. + */ + MME_APP_DEBUG("UE context doesn't exist -> create one\n"); + if ((ue_context = mme_create_new_ue_context()) == NULL) { + /* Error during ue context malloc */ + /* TODO */ + DevMessage("mme_create_new_ue_context"); + return; + } + + ue_context->imsi = imsi; + ue_context->ue_id = nas_auth_param_req_p->ue_id; + + DevAssert(mme_insert_ue_context(&mme_app_desc.mme_ue_contexts, ue_context) == 0); + + /* We have no vector for this UE, send an authentication request + * to the HSS. + */ + plmn_t plmn = { + .MCCdigit2 = 0, + .MCCdigit1 = 8, + .MCCdigit3 = 2, + .MNCdigit1 = 0, + .MNCdigit2 = 4, + .MNCdigit3 = 3, + }; + + /* Acquire the current time */ + time(&ue_context->cell_age); + + memcpy(&ue_context->guti.gummei.plmn, &plmn, sizeof(plmn_t)); + MME_APP_DEBUG("and we have no auth. vector for it, request" + " authentication information\n"); + mme_app_request_authentication_info(imsi, 1, &plmn); + } else { + DevMessage("not handled\n"); + } +} #endif diff --git a/openair-cn/MME_APP/mme_app_context.c b/openair-cn/MME_APP/mme_app_context.c index fe1d37a6004..613dfcc2d77 100644 --- a/openair-cn/MME_APP/mme_app_context.c +++ b/openair-cn/MME_APP/mme_app_context.c @@ -190,7 +190,6 @@ void mme_app_dump_ue_contexts(mme_ue_context_t *mme_ue_context) MME_APP_DEBUG("-----------------------UE contexts-----------------------\n"); RB_FOREACH(context_p, ue_context_map, &mme_ue_context->ue_context_tree) { - struct eutran_vector_s *vector_p; uint8_t j; MME_APP_DEBUG(" - IMSI ...........: %"SCNu64"\n", context_p->imsi); @@ -252,10 +251,13 @@ void mme_app_dump_ue_contexts(mme_ue_context_t *mme_ue_context) MME_APP_DEBUG(" Allocated ....: (%010"PRIu64"|%010"PRIu64")\n", context_p->used_ambr.br_dl, context_p->used_ambr.br_ul); MME_APP_DEBUG(" - Known vectors ..: %u\n", context_p->nb_of_vectors); - STAILQ_FOREACH(vector_p, &context_p->vector_list, entries) + for (j = 0; j < context_p->nb_of_vectors; j++) { int k; char xres_string[3 * XRES_LENGTH_MAX + 1]; + eutran_vector_t *vector_p; + + vector_p = &context_p->vector_list[j]; MME_APP_DEBUG(" - RAND ..: "RAND_FORMAT"\n", RAND_DISPLAY(vector_p->rand)); diff --git a/openair-cn/MME_APP/mme_app_defs.h b/openair-cn/MME_APP/mme_app_defs.h index d5e023cac29..829c6adc74f 100644 --- a/openair-cn/MME_APP/mme_app_defs.h +++ b/openair-cn/MME_APP/mme_app_defs.h @@ -33,6 +33,7 @@ * Use mme_app_extern.h to expose mme applicative layer procedures/data. */ +#include "intertask_interface.h" #include "mme_app_ue_context.h" #ifndef MME_APP_DEFS_H_ @@ -69,6 +70,8 @@ int mme_app_handle_authentication_info_answer(s6a_auth_info_ans_t *s6a_auth_info int mme_app_handle_nas_auth_resp(nas_auth_resp_t *nas_auth_resp_p); -int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental); +nas_cause_t s6a_error_2_nas_cause(uint32_t s6a_error, int experimental); + +void mme_app_handle_nas_auth_param_req(nas_auth_param_req_t *nas_auth_param_req); #endif /* MME_APP_DEFS_H_ */ diff --git a/openair-cn/MME_APP/mme_app_main.c b/openair-cn/MME_APP/mme_app_main.c index 9bb8f130f4a..38209421b6e 100644 --- a/openair-cn/MME_APP/mme_app_main.c +++ b/openair-cn/MME_APP/mme_app_main.c @@ -78,14 +78,18 @@ void *mme_app_thread(void *args) mme_app_handle_create_sess_resp(&received_message_p->ittiMsg.sgwCreateSessionResponse); } break; - case NAS_AUTHENTICATION_RESP: { - mme_app_handle_nas_auth_resp(&received_message_p->ittiMsg.nas_auth_resp); + case NAS_AUTHENTICATION_PARAM_REQ: { + mme_app_handle_nas_auth_param_req(&received_message_p->ittiMsg.nas_auth_param_req); } break; #if defined(DISABLE_USE_NAS) case NAS_ATTACH_REQ: { mme_app_handle_attach_req(&received_message_p->ittiMsg.nas_attach_req); } break; + + case NAS_AUTHENTICATION_RESP: { + mme_app_handle_nas_auth_resp(&received_message_p->ittiMsg.nas_auth_resp); + } break; #endif case TIMER_HAS_EXPIRED: { diff --git a/openair-cn/MME_APP/mme_app_ue_context.h b/openair-cn/MME_APP/mme_app_ue_context.h index 45173eeca46..cf7a2c1dd03 100644 --- a/openair-cn/MME_APP/mme_app_ue_context.h +++ b/openair-cn/MME_APP/mme_app_ue_context.h @@ -92,6 +92,9 @@ typedef struct bearer_context_s { * according to 3GPP TS.23.401 #5.7.2 */ typedef struct ue_context_s { + /* Tree entry */ + RB_ENTRY(ue_context_s) rb_entry; + /* Basic identifier for ue. IMSI is encoded on maximum of 15 digits of 4 bits, * so usage of an unsigned integer on 64 bits is necessary. */ @@ -104,11 +107,14 @@ typedef struct ue_context_s { unsigned eNB_ue_s1ap_id:24; uint32_t mme_ue_s1ap_id; + /* ue_id is equal to mme_ue_s1ap_id */ + uint32_t ue_id; + uint8_t nb_of_vectors; - struct eutran_vector_s *vector_in_use; /* List of authentication vectors for E-UTRAN */ - STAILQ_HEAD(auth_vectors, eutran_vector_s) vector_list; + eutran_vector_t *vector_list; + eutran_vector_t *vector_in_use; #define SUBSCRIPTION_UNKNOWN 0x0 #define SUBSCRIPTION_KNOWN 0x1 @@ -160,10 +166,6 @@ typedef struct ue_context_s { uint32_t sgw_s11_teid; bearer_context_t eps_bearers[BEARERS_PER_UE]; - - /* Tree entry */ - RB_ENTRY(ue_context_s) rb_entry; - } ue_context_t; typedef struct { diff --git a/openair-cn/MME_APP/s6a_2_nas_cause.c b/openair-cn/MME_APP/s6a_2_nas_cause.c index 9031c6d0073..e27c55dd6ef 100644 --- a/openair-cn/MME_APP/s6a_2_nas_cause.c +++ b/openair-cn/MME_APP/s6a_2_nas_cause.c @@ -31,18 +31,9 @@ #include "as_message.h" #include "common_types.h" #include "s6a_defs.h" +#include "mme_app_defs.h" -// int send_nas_failure(uint32_t nas_cause) -// { -// MessageDef *message_p; -// -// message_p = itti_alloc_new_message(TASK_MME_APP, TASK_NAS, -// SGW_CREATE_SESSION_REQUEST); -// -// return itti_send_msg_to_task(TASK_NAS, message_p); -// } - -int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) +nas_cause_t s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) { if (experimental == 0) { /* Base protocol errors */ @@ -53,7 +44,7 @@ int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) case ER_DIAMETER_REALM_NOT_SERVED: /* Fall through */ /* 5003 */ case ER_DIAMETER_AUTHORIZATION_REJECTED: - return NO_SUITABLE_CELLS_IN_TRACKING_AREA; + return NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA; /* 5012 */ case ER_DIAMETER_UNABLE_TO_COMPLY: /* Fall through */ /* 5004 */ @@ -66,11 +57,11 @@ int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) switch (s6a_error) { /* 5001 */ case DIAMETER_ERROR_USER_UNKNOWN: - return EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED; + return NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED; /* TODO: distinguish GPRS_DATA_SUBSCRIPTION */ /* 5420 */ case DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION: - return NO_SUITABLE_CELLS_IN_TRACKING_AREA; + return NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA; /* 5421 */ case DIAMETER_ERROR_RAT_NOT_ALLOWED: /* One of the following parameter can be sent depending on @@ -79,10 +70,10 @@ int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) * TRACKING_AREA_NOT_ALLOWED * NO_SUITABLE_CELLS_IN_TRACKING_AREA */ - return TRACKING_AREA_NOT_ALLOWED; + return NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED; /* 5004 without error diagnostic */ case DIAMETER_ERROR_ROAMING_NOT_ALLOWED: - return PLMN_NOT_ALLOWED; + return NAS_CAUSE_PLMN_NOT_ALLOWED; /* TODO: 5004 with error diagnostic of ODB_HPLMN_APN or * ODB_VPLMN_APN */ @@ -91,5 +82,5 @@ int s6a_error_2_nas_cause(uint32_t s6a_error, int experimental) break; } } - return NETWORK_FAILURE; + return NAS_CAUSE_NETWORK_FAILURE; } diff --git a/openair-cn/Makefile.am b/openair-cn/Makefile.am index c7e7cc3c1a7..4a69ba53afa 100644 --- a/openair-cn/Makefile.am +++ b/openair-cn/Makefile.am @@ -42,7 +42,7 @@ messages.xml: $(top_srcdir)/INTERTASK_INTERFACE/intertask_interface_types.h $(me messages_xml.h: messages.xml @echo "Generating $<" - @sed -e 's/[ ]*//' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/"/' messages.xml > messages_xml.h + @sed -e 's/[ ]*//' -e 's/"/\\"/g' -e 's/^/"/' -e 's/$$/\\n"/' messages.xml > messages_xml.h clean-local: @rm -rf -v messages.xml messages_xml.h diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c index 681a954472f..4161bed1d5b 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c @@ -1143,21 +1143,21 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, /**************************************************************************** ** ** - ** Name: emm_proc_attach_reject() ** + ** Name: emm_proc_attach_reject() ** ** ** ** Description: Performs the protocol error abnormal case ** ** ** ** 3GPP TS 24.301, section 5.5.1.2.7, case b ** - ** If the ATTACH REQUEST message is received with a protocol ** - ** error, the network shall return an ATTACH REJECT message. ** + ** If the ATTACH REQUEST message is received with a protocol ** + ** error, the network shall return an ATTACH REJECT message. ** ** ** - ** Inputs: ueid: UE lower layer identifier ** - ** emm_cause: EMM cause code to be reported ** - ** Others: None ** + ** Inputs: ueid: UE lower layer identifier ** + ** emm_cause: EMM cause code to be reported ** + ** Others: None ** ** ** ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ int emm_proc_attach_reject(unsigned int ueid, int emm_cause) @@ -1174,7 +1174,7 @@ int emm_proc_attach_reject(unsigned int ueid, int emm_cause) /* Update the EMM cause code */ #if defined(EPC_BUILD) - if (ueid == 0) + if (ueid > 0) #else if (ueid < EMM_DATA_NB_UE_MAX) #endif @@ -1828,33 +1828,39 @@ static int _emm_attach_abort(void *args) ***************************************************************************/ static int _emm_attach_identify(void *args) { - LOG_FUNC_IN; - int rc = RETURNerror; emm_data_context_t *emm_ctx = (emm_data_context_t *)(args); int guti_reallocation = FALSE; + LOG_FUNC_IN; + LOG_TRACE(INFO, "EMM-PROC - Identify incoming UE (ueid=0x%08x) using %s", emm_ctx->ueid, (emm_ctx->imsi)? "IMSI" : (emm_ctx->guti)? "GUTI" : (emm_ctx->imei)? "IMEI" : "none"); -#if defined(EPC_BUILD) - nas_itti_auth_info_req(emm_ctx->imsi, 1); -#endif - /* * UE's identification * ------------------- */ if (emm_ctx->imsi) { /* The UE identifies itself using an IMSI */ - rc = mme_api_identify_imsi(emm_ctx->imsi, &emm_ctx->vector); - if (rc != RETURNok) { - LOG_TRACE(WARNING, "EMM-PROC - " - "Failed to identify the UE using provided IMSI"); - emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; +#if defined(EPC_BUILD) + if (!emm_ctx->security) { + /* Ask upper layer to fetch new security context */ + nas_itti_auth_info_req(emm_ctx->ueid, emm_ctx->imsi, 1); + + rc = RETURNok; + } else +#endif + { + rc = mme_api_identify_imsi(emm_ctx->imsi, &emm_ctx->vector); + if (rc != RETURNok) { + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to identify the UE using provided IMSI"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } + guti_reallocation = TRUE; } - guti_reallocation = TRUE; } else if (emm_ctx->guti) { /* The UE identifies itself using a GUTI */ rc = mme_api_identify_guti(emm_ctx->guti, &emm_ctx->vector); @@ -1945,7 +1951,9 @@ static int _emm_attach_identify(void *args) * execution of the security mode control procedure. */ rc = _emm_attach_security(emm_ctx); - } else { + } +#if !defined(EPC_BUILD) + else { /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a * No EMM context exists for the UE in the network; authentication * and NAS security setup to activate integrity protection and NAS @@ -1956,7 +1964,7 @@ static int _emm_attach_identify(void *args) const OctetString autn = {AUTH_AUTN_SIZE, (uint8_t *)auth->autn}; rc = emm_proc_authentication(emm_ctx->ueid, 0, // TODO: eksi != 0 &loc_rand, &autn, - _emm_attach_security, + emm_attach_security, _emm_attach_release, _emm_attach_release); if (rc != RETURNok) { @@ -1966,6 +1974,7 @@ static int _emm_attach_identify(void *args) emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; } } +#endif } if (rc != RETURNok) { @@ -1977,18 +1986,25 @@ static int _emm_attach_identify(void *args) /**************************************************************************** ** ** - ** Name: _emm_attach_security() ** + ** Name: _emm_attach_security() ** ** ** ** Description: Initiates security mode control EMM common procedure. ** ** ** - ** Inputs: args: security argument parameters ** - ** Others: None ** + ** Inputs: args: security argument parameters ** + ** Others: None ** ** ** ** Outputs: None ** - ** Return: RETURNok, RETURNerror ** - ** Others: _emm_data ** + ** Return: RETURNok, RETURNerror ** + ** Others: _emm_data ** ** ** ***************************************************************************/ +#if defined(EPC_BUILD) +int emm_attach_security(void *args) +{ + return _emm_attach_security(args); +} +#endif + static int _emm_attach_security(void *args) { LOG_FUNC_IN; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h index 9f24fa67ad7..44b7b8ab663 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emm_proc.h @@ -199,6 +199,8 @@ int emm_proc_authentication(unsigned int ueid, int ksi, emm_common_failure_callback_t failure); int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, const OctetString *res); + +int emm_attach_security(void *args); #endif /* diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c index 47b80210dd7..5b3c7c28b75 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c @@ -1078,6 +1078,12 @@ static int _emm_as_send(const emm_as_t *msg) /* Send the message to the Access Stratum or S1AP in case of MME */ if (as_msg.msgID > 0) { #if defined(EPC_BUILD) && defined(NAS_MME) + LOG_TRACE(DEBUG, "EMMAS-SAP - " + "Sending msg with id 0x%x, primitive %s (%d) to S1AP layer for transmission", + as_msg.msgID, + _emm_as_primitive_str[msg->primitive - _EMMAS_START - 1], + msg->primitive); + switch (as_msg.msgID) { case AS_DL_INFO_TRANSFER_REQ: { nas_itti_dl_data_req(as_msg.msg.dl_info_transfer_req.UEid, @@ -1086,14 +1092,14 @@ static int _emm_as_send(const emm_as_t *msg) } break; case AS_NAS_ESTABLISH_RSP: { - /* The attach procedure succeeded wihtin MME. - * This message should trigger an S1AP initial context setup - * request. - * NOTE: we support only one bearer per message... - */ -// nas_itti_establish_cnf(as_msg.msg.nas_establish_cnf.errCode, -// as_msg.msg.nas_establish_cnf.nasMsg.data, -// as_msg.msg.nas_establish_cnf.nasMsg.length); + if (as_msg.msg.nas_establish_rsp.errCode != AS_SUCCESS) { + nas_itti_dl_data_req(as_msg.msg.nas_establish_rsp.UEid, + as_msg.msg.nas_establish_rsp.nasMsg.data, + as_msg.msg.nas_establish_rsp.nasMsg.length); + LOG_FUNC_RETURN (RETURNok); + } else { + /* Handle success case */ + } } break; default: @@ -1679,13 +1685,14 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, static int _emm_as_establish_rej(const emm_as_establish_t *msg, nas_establish_rsp_t *as_msg) { - LOG_FUNC_IN; - + EMM_msg *emm_msg; int size = 0; + nas_message_t nas_msg; + + LOG_FUNC_IN; LOG_TRACE(INFO, "EMMAS-SAP - Send AS connection establish reject"); - nas_message_t nas_msg; memset(&nas_msg, 0 , sizeof(nas_message_t)); /* Setup the AS message */ @@ -1697,7 +1704,7 @@ static int _emm_as_establish_rej(const emm_as_establish_t *msg, } /* Setup the NAS security header */ - EMM_msg *emm_msg = _emm_as_set_header(&nas_msg, &msg->sctx); + emm_msg = _emm_as_set_header(&nas_msg, &msg->sctx); /* Setup the NAS information message */ if (emm_msg != NULL) switch (msg->NASinfo) { diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c new file mode 100644 index 00000000000..37728ff8191 --- /dev/null +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c @@ -0,0 +1,134 @@ +/***************************************************************************** + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom + +Source emm_cn.c + +Version 0.1 + +Date 2013/12/05 + +Product NAS stack + +Subsystem EPS Core Network + +Author Sebastien Roux + +Description + +*****************************************************************************/ + +#include <string.h> + +#include "nas_log.h" +#include "commonDef.h" + +#include "emm_cn.h" +#include "emm_sap.h" +#include "emm_proc.h" +#include "emm_cause.h" + +/* + * String representation of EMMCN-SAP primitives + */ +static const char *_emm_cn_primitive_str[] = { + "EMMCN_AUTHENTICATION_PARAM_RES", + "EMMCN_AUTHENTICATION_PARAM_FAIL", +}; + +static int _emm_cn_authentication_res(const emm_cn_auth_res_t *msg) +{ + emm_data_context_t *emm_ctx = NULL; + int rc = RETURNerror; + OctetString loc_rand; + OctetString autn; + + /* We received security vector from HSS. Try to setup security with UE */ + + LOG_FUNC_IN; + + emm_ctx = emm_data_context_get(&_emm_data, msg->ue_id); + if (emm_ctx == NULL) { + LOG_TRACE(ERROR, "EMM-PROC - " + "Failed to find UE associated to id %u...", msg->ue_id); + LOG_FUNC_RETURN (rc); + } + + /* Copy provided vector to user context */ + memcpy(emm_ctx->vector.kasme, msg->vector.kasme, AUTH_KASME_SIZE); + memcpy(emm_ctx->vector.autn, msg->vector.autn, AUTH_AUTN_SIZE); + memcpy(emm_ctx->vector.rand, msg->vector.rand, AUTH_RAND_SIZE); + memcpy(emm_ctx->vector.xres, msg->vector.xres.data, msg->vector.xres.size); + + loc_rand.value = emm_ctx->vector.rand; + loc_rand.length = AUTH_RAND_SIZE; + + autn.value = emm_ctx->vector.autn; + autn.length = AUTH_AUTN_SIZE; + + emm_ctx->vector.xres_size = msg->vector.xres.size; + + /* 3GPP TS 24.401, Figure 5.3.2.1-1, point 5a + * No EMM context exists for the UE in the network; authentication + * and NAS security setup to activate integrity protection and NAS + * ciphering are mandatory. + */ + rc = emm_proc_authentication(emm_ctx->ueid, 0, // TODO: eksi != 0 + &loc_rand, &autn, + emm_attach_security, + NULL, + NULL); + if (rc != RETURNok) { + /* Failed to initiate the authentication procedure */ + LOG_TRACE(WARNING, "EMM-PROC - " + "Failed to initiate authentication procedure"); + emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; + } + + LOG_FUNC_RETURN (rc); +} + +static int _emm_cn_authentication_fail(const emm_cn_auth_fail_t *msg) +{ + int rc = RETURNerror; + + LOG_FUNC_IN; + + rc = emm_proc_attach_reject(msg->ue_id, msg->cause); + + LOG_FUNC_RETURN (rc); +} + +int emm_cn_send(const emm_cn_t *msg) +{ + int rc = RETURNerror; + emm_cn_primitive_t primitive = msg->primitive; + + LOG_FUNC_IN; + + LOG_TRACE(INFO, "EMMCN-SAP - Received primitive %s (%d)", + _emm_cn_primitive_str[primitive - _EMMCN_START - 1], primitive); + + switch (primitive) { + case _EMMCN_AUTHENTICATION_PARAM_RES: + rc = _emm_cn_authentication_res(msg->u.auth_res); + break; + + case _EMMCN_AUTHENTICATION_PARAM_FAIL: + rc = _emm_cn_authentication_fail(msg->u.auth_fail); + break; + + default: + /* Other primitives are forwarded to the Access Stratum */ + rc = RETURNerror; + break; + } + + if (rc != RETURNok) { + LOG_TRACE(ERROR, "EMMCN-SAP - Failed to process primitive %s (%d)", + _emm_cn_primitive_str[primitive - _EMMCN_START - 1], + primitive); + } + + LOG_FUNC_RETURN (rc); +} diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.h b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.h new file mode 100644 index 00000000000..143fc77e341 --- /dev/null +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.h @@ -0,0 +1,28 @@ +/***************************************************************************** + Eurecom OpenAirInterface 3 + Copyright(c) 2013 Eurecom + +Source emm_cn.h + +Version 0.1 + +Date 2013/12/05 + +Product NAS stack + +Subsystem EPS Core Network + +Author Sebastien Roux + +Description + +*****************************************************************************/ + +#include "emm_cnDef.h" + +#ifndef _EMM_CN_H_ +#define _EMM_CN_H_ + +int emm_cn_send(const emm_cn_t *msg); + +#endif /* _EMM_CN_H_ */ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cnDef.h b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cnDef.h new file mode 100644 index 00000000000..577d5c403ad --- /dev/null +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cnDef.h @@ -0,0 +1,48 @@ +/***************************************************************************** + Eurecom OpenAirInterface 3 + Copyright(c) 2012 Eurecom + +Source emm_cnDef.h + +Version 0.1 + +Date 2013/12/05 + +Product NAS stack + +Subsystem EPS Core Network + +Author Sebastien Roux + +Description + +*****************************************************************************/ + +#include "intertask_interface.h" + +#ifndef __EMM_CNDEF_H__ +#define __EMM_CNDEF_H__ + +typedef enum emmcn_primitive_s { + _EMMCN_START = 400, +#if defined(EPC_BUILD) + _EMMCN_AUTHENTICATION_PARAM_RES, + _EMMCN_AUTHENTICATION_PARAM_FAIL, +#endif + _EMMCN_END +} emm_cn_primitive_t; + +typedef nas_auth_param_rsp_t emm_cn_auth_res_t; +typedef nas_auth_param_fail_t emm_cn_auth_fail_t; + +#if defined(EPC_BUILD) +typedef struct emm_mme_ul_s { + emm_cn_primitive_t primitive; + union { + emm_cn_auth_res_t *auth_res; + emm_cn_auth_fail_t *auth_fail; + } u; +} emm_cn_t; +#endif + +#endif /* __EMM_CNDEF_H__ */ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.c index b02b82d87ee..4ab81e9bfdf 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.c @@ -28,6 +28,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_reg.h" #include "emm_esm.h" #include "emm_as.h" +#include "emm_cn.h" /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -82,12 +83,12 @@ void emm_sap_initialize(void) ***************************************************************************/ int emm_sap_send(emm_sap_t *msg) { - LOG_FUNC_IN; - int rc = RETURNerror; emm_primitive_t primitive = msg->primitive; + LOG_FUNC_IN; + /* Check the EMM-SAP primitive */ if ( (primitive > EMMREG_PRIMITIVE_MIN) && (primitive < EMMREG_PRIMITIVE_MAX) ) { @@ -104,7 +105,16 @@ int emm_sap_send(emm_sap_t *msg) /* Forward to the EMMAS-SAP */ msg->u.emm_as.primitive = primitive; rc = emm_as_send(&msg->u.emm_as); - } else { + } +#if defined(EPC_BUILD) + else if ( (primitive > EMMCN_PRIMITIVE_MIN) && + (primitive < EMMCN_PRIMITIVE_MAX) ) { + /* Forward to the EMMCN-SAP */ + msg->u.emm_cn.primitive = primitive; + rc = emm_cn_send(&msg->u.emm_cn); + } +#endif + else { LOG_TRACE(WARNING, "EMM-SAP - Out of range primitive (%d)", primitive); } diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.h b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.h index 12a43bc3c33..e5291572c21 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_sap.h @@ -26,6 +26,7 @@ Description Defines the EMM Service Access Points at which the EPS #include "emm_regDef.h" #include "emm_esmDef.h" #include "emm_asDef.h" +#include "emm_cnDef.h" /****************************************************************************/ /********************* G L O B A L C O N S T A N T S *******************/ @@ -46,8 +47,8 @@ typedef enum { #ifdef NAS_UE EMMREG_S1_ENABLED = _EMMREG_S1_ENABLED, EMMREG_S1_DISABLED = _EMMREG_S1_DISABLED, - EMMREG_NO_IMSI = _EMMREG_NO_IMSI, - EMMREG_NO_CELL = _EMMREG_NO_CELL, + EMMREG_NO_IMSI = _EMMREG_NO_IMSI, + EMMREG_NO_CELL = _EMMREG_NO_CELL, EMMREG_REGISTER_REQ = _EMMREG_REGISTER_REQ, EMMREG_REGISTER_CNF = _EMMREG_REGISTER_CNF, EMMREG_REGISTER_REJ = _EMMREG_REGISTER_REJ, @@ -55,7 +56,7 @@ typedef enum { EMMREG_ATTACH_REQ = _EMMREG_ATTACH_REQ, EMMREG_ATTACH_FAILED = _EMMREG_ATTACH_FAILED, EMMREG_ATTACH_EXCEEDED = _EMMREG_ATTACH_EXCEEDED, - EMMREG_AUTH_REJ = _EMMREG_AUTH_REJ, + EMMREG_AUTH_REJ = _EMMREG_AUTH_REJ, #endif #ifdef NAS_MME EMMREG_COMMON_PROC_REQ = _EMMREG_COMMON_PROC_REQ, @@ -69,9 +70,9 @@ typedef enum { EMMREG_DETACH_REQ = _EMMREG_DETACH_REQ, EMMREG_DETACH_FAILED = _EMMREG_DETACH_FAILED, EMMREG_DETACH_CNF = _EMMREG_DETACH_CNF, - EMMREG_TAU_REQ = _EMMREG_TAU_REQ, - EMMREG_TAU_CNF = _EMMREG_TAU_CNF, - EMMREG_TAU_REJ = _EMMREG_TAU_REJ, + EMMREG_TAU_REQ = _EMMREG_TAU_REQ, + EMMREG_TAU_CNF = _EMMREG_TAU_CNF, + EMMREG_TAU_REJ = _EMMREG_TAU_REJ, EMMREG_SERVICE_REQ = _EMMREG_SERVICE_REQ, EMMREG_SERVICE_CNF = _EMMREG_SERVICE_CNF, EMMREG_SERVICE_REJ = _EMMREG_SERVICE_REJ, @@ -97,13 +98,18 @@ typedef enum { EMMAS_ESTABLISH_REJ = _EMMAS_ESTABLISH_REJ, EMMAS_RELEASE_REQ = _EMMAS_RELEASE_REQ, EMMAS_RELEASE_IND = _EMMAS_RELEASE_IND, - EMMAS_DATA_REQ = _EMMAS_DATA_REQ, - EMMAS_DATA_IND = _EMMAS_DATA_IND, - EMMAS_PAGE_IND = _EMMAS_PAGE_IND, + EMMAS_DATA_REQ = _EMMAS_DATA_REQ, + EMMAS_DATA_IND = _EMMAS_DATA_IND, + EMMAS_PAGE_IND = _EMMAS_PAGE_IND, EMMAS_STATUS_IND = _EMMAS_STATUS_IND, EMMAS_CELL_INFO_REQ = _EMMAS_CELL_INFO_REQ, EMMAS_CELL_INFO_RES = _EMMAS_CELL_INFO_RES, EMMAS_CELL_INFO_IND = _EMMAS_CELL_INFO_IND, + +#ifdef EPC_BUILD + EMMCN_AUTHENTICATION_PARAM_RES = _EMMCN_AUTHENTICATION_PARAM_RES, + EMMCN_AUTHENTICATION_PARAM_FAIL = _EMMCN_AUTHENTICATION_PARAM_FAIL, +#endif } emm_primitive_t; /* @@ -111,14 +117,16 @@ typedef enum { */ #define EMMREG_PRIMITIVE_MIN _EMMREG_START #define EMMESM_PRIMITIVE_MIN _EMMESM_START -#define EMMAS_PRIMITIVE_MIN _EMMAS_START +#define EMMAS_PRIMITIVE_MIN _EMMAS_START +#define EMMCN_PRIMITIVE_MIN _EMMCN_START /* * Maximal identifier for EMM-SAP primitives */ #define EMMREG_PRIMITIVE_MAX _EMMREG_END #define EMMESM_PRIMITIVE_MAX _EMMESM_END -#define EMMAS_PRIMITIVE_MAX _EMMAS_END +#define EMMAS_PRIMITIVE_MAX _EMMAS_END +#define EMMCN_PRIMITIVE_MAX _EMMCN_END /****************************************************************************/ /************************ G L O B A L T Y P E S ************************/ @@ -133,6 +141,9 @@ typedef struct { emm_reg_t emm_reg; /* EMMREG-SAP primitives */ emm_esm_t emm_esm; /* EMMESM-SAP primitives */ emm_as_t emm_as; /* EMMAS-SAP primitives */ +#if defined(EPC_BUILD) + emm_cn_t emm_cn; /* EMMCN-SAP primitives */ +#endif } u; } emm_sap_t; diff --git a/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h b/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h index fe4412f3516..605f14b71be 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h +++ b/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h @@ -42,12 +42,12 @@ Description Contains global security definitions AUTN = (SQN ⊕ AK) || AMF || MAC */ #define AUTH_MACS_SIZE 8 /* Re-synchronization MAC: 64 bits */ #define AUTH_AUTS_SIZE 16 /* Re-synchronization AUT: 128 bits */ -#define AUTH_RAND_SIZE 16 /* Random challenge: 128 bits */ -#define AUTH_CK_SIZE 16 /* Ciphering key: 128 bits */ -#define AUTH_IK_SIZE 16 /* Integrity key: 128 bits */ +#define AUTH_RAND_SIZE 16 /* Random challenge: 128 bits */ +#define AUTH_CK_SIZE 16 /* Ciphering key: 128 bits */ +#define AUTH_IK_SIZE 16 /* Integrity key: 128 bits */ #define AUTH_RES_SIZE 16 /* Authentication response: 128 bits */ #define AUTH_SNID_SIZE 3 /* Serving network's identity: 24 bits */ -#define AUTH_KASME_SIZE 32 /* ASME security key: 256 bits */ +#define AUTH_KASME_SIZE 32 /* KASME security key: 256 bits */ #define AUTH_KNAS_INT_SIZE AUTH_KASME_SIZE /* NAS integrity key */ #define AUTH_KNAS_ENC_SIZE AUTH_KASME_SIZE /* NAS cyphering key */ #define AUTH_KENB_SIZE AUTH_KASME_SIZE /* eNodeB security key */ @@ -64,14 +64,15 @@ Description Contains global security definitions */ typedef struct { /* ASME security key */ - char kasme[AUTH_KASME_SIZE + 1]; + uint8_t kasme[AUTH_KASME_SIZE]; /* Random challenge parameter */ - char rand[AUTH_RAND_SIZE + 1]; + uint8_t rand[AUTH_RAND_SIZE]; /* Authentication token parameter */ - char autn[AUTH_AUTN_SIZE + 1]; + uint8_t autn[AUTH_AUTN_SIZE]; /* Expected Authentication response parameter */ #define AUTH_XRES_SIZE AUTH_RES_SIZE - char xres[AUTH_XRES_SIZE + 1]; + uint8_t xres_size; + uint8_t xres[AUTH_XRES_SIZE]; } auth_vector_t; /****************************************************************************/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/nas_proc.c b/openair-cn/NAS/EURECOM-NAS/src/nas_proc.c index c7728d8df88..77c07bc88d4 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/nas_proc.c +++ b/openair-cn/NAS/EURECOM-NAS/src/nas_proc.c @@ -1421,10 +1421,10 @@ int nas_proc_dl_transfer_rej(UInt32_t ueid) ***************************************************************************/ int nas_proc_ul_transfer_ind(UInt32_t ueid, const Byte_t *data, UInt32_t len) { - LOG_FUNC_IN; - int rc = RETURNerror; + LOG_FUNC_IN; + if (len > 0) { emm_sap_t emm_sap; /* @@ -1441,6 +1441,38 @@ int nas_proc_ul_transfer_ind(UInt32_t ueid, const Byte_t *data, UInt32_t len) LOG_FUNC_RETURN (rc); } + +# if defined(EPC_BUILD) +int nas_proc_auth_param_res(emm_cn_auth_res_t *emm_cn_auth_res) +{ + int rc = RETURNerror; + emm_sap_t emm_sap; + + LOG_FUNC_IN; + + emm_sap.primitive = EMMCN_AUTHENTICATION_PARAM_RES; + emm_sap.u.emm_cn.u.auth_res = emm_cn_auth_res; + + rc = emm_sap_send(&emm_sap); + + LOG_FUNC_RETURN (rc); +} + +int nas_proc_auth_param_fail(emm_cn_auth_fail_t *emm_cn_auth_fail) +{ + int rc = RETURNerror; + emm_sap_t emm_sap; + + LOG_FUNC_IN; + + emm_sap.primitive = EMMCN_AUTHENTICATION_PARAM_FAIL; + emm_sap.u.emm_cn.u.auth_fail = emm_cn_auth_fail; + + rc = emm_sap_send(&emm_sap); + + LOG_FUNC_RETURN (rc); +} +# endif #endif // NAS_MME /****************************************************************************/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/nas_proc.h b/openair-cn/NAS/EURECOM-NAS/src/nas_proc.h index 205e76e4dc4..158a8540d54 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/nas_proc.h +++ b/openair-cn/NAS/EURECOM-NAS/src/nas_proc.h @@ -22,6 +22,7 @@ Description NAS procedure call manager #if defined(EPC_BUILD) # include "mme_config.h" +# include "emm_cnDef.h" #endif #include "commonDef.h" @@ -128,4 +129,15 @@ int nas_proc_dl_transfer_rej(UInt32_t ueid); int nas_proc_ul_transfer_ind(UInt32_t ueid, const Byte_t *data, UInt32_t len); #endif +/* + * -------------------------------------------------------------------------- + * NAS procedures triggered by the mme applicative layer + * -------------------------------------------------------------------------- + */ +#if defined(NAS_MME) && defined(EPC_BUILD) +int nas_proc_auth_param_res(emm_cn_auth_res_t *emm_cn_auth_res); + +int nas_proc_auth_param_fail(emm_cn_auth_fail_t *emm_cn_auth_fail); +#endif + #endif /* __NAS_PROC_H__*/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h index 82ef86989c5..4dc1715c7c4 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h +++ b/openair-cn/NAS/EURECOM-NAS/src/util/OctetString.h @@ -4,8 +4,8 @@ #define OCTET_STRING_H_ typedef struct OctetString_tag { - uint32_t length; - uint8_t *value; + uint32_t length; + uint8_t *value; } OctetString; int encode_octet_string(OctetString *octetstring, uint8_t *buffer, uint32_t len); diff --git a/openair-cn/NAS/Makefile.inc b/openair-cn/NAS/Makefile.inc index f1e6d9214e1..771ea1c3036 100644 --- a/openair-cn/NAS/Makefile.inc +++ b/openair-cn/NAS/Makefile.inc @@ -90,8 +90,9 @@ libnas_emm_msg_SRCS = \ EURECOM-NAS/src/emm/msg/TrackingAreaUpdateComplete.c libnas_emm_sap_SRCS = \ - EURECOM-NAS/src/emm/sap/emm_as.c \ \ EURECOM-NAS/src/emm/sap/emm_as.c \ + EURECOM-NAS/src/emm/sap/emm_cn.c \ + EURECOM-NAS/src/emm/sap/emm_cn.h \ EURECOM-NAS/src/emm/sap/EmmDeregisteredNoImsi.c \ EURECOM-NAS/src/emm/sap/emm_reg.c \ EURECOM-NAS/src/emm/sap/EmmRegisteredUpdateNeeded.c \ diff --git a/openair-cn/NAS/nas_itti_messaging.c b/openair-cn/NAS/nas_itti_messaging.c index 64ce5074ecd..ddf3bbe04b5 100644 --- a/openair-cn/NAS/nas_itti_messaging.c +++ b/openair-cn/NAS/nas_itti_messaging.c @@ -33,7 +33,7 @@ #include "intertask_interface.h" #include "nas_itti_messaging.h" -int nas_itti_dl_data_req(const uint32_t ue_id, void * const data, +int nas_itti_dl_data_req(const uint32_t ue_id, void *const data, const uint32_t length) { MessageDef *message_p; @@ -47,7 +47,7 @@ int nas_itti_dl_data_req(const uint32_t ue_id, void * const data, return itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p); } -void nas_itti_establish_cnf(const nas_error_code_t error_code, void * const data, +void nas_itti_establish_cnf(const nas_error_code_t error_code, void *const data, const uint32_t length) { MessageDef *message_p; diff --git a/openair-cn/NAS/nas_itti_messaging.h b/openair-cn/NAS/nas_itti_messaging.h index 5f60d505dcc..7f6dba899de 100644 --- a/openair-cn/NAS/nas_itti_messaging.h +++ b/openair-cn/NAS/nas_itti_messaging.h @@ -27,6 +27,8 @@ 06410 Biot FRANCE *******************************************************************************/ +#include <stdint.h> +#include <ctype.h> #include "intertask_interface.h" #include "conversions.h" @@ -34,23 +36,56 @@ #ifndef NAS_ITTI_MESSAGING_H_ #define NAS_ITTI_MESSAGING_H_ -int nas_itti_dl_data_req(const uint32_t ue_id, void * const data, +int nas_itti_dl_data_req(const uint32_t ue_id, void *const data, const uint32_t length); -void nas_itti_establish_cnf(const nas_error_code_t error_code, void * const data, +void nas_itti_establish_cnf(const nas_error_code_t error_code, void *const data, const uint32_t length); -static inline void nas_itti_auth_info_req(const imsi_t * const imsi, - uint8_t initial_req) +static inline void nas_itti_auth_info_req(const uint32_t ue_id, + const imsi_t *const imsi, uint8_t initial_req) { MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS, NAS_AUTHENTICATION_PARAM_REQ); - hexa_to_ascii((uint8_t *)imsi->u.value, NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi, - imsi->length); + hexa_to_ascii((uint8_t *)imsi->u.value, + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi, 8); + + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[15] = '\0'; + + if (isdigit(NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[14])) { + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = 15; + } else { + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = 14; + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[14] = '\0'; + } + NAS_AUTHENTICATION_PARAM_REQ(message_p).initial_req = initial_req; + NAS_AUTHENTICATION_PARAM_REQ(message_p).ue_id = ue_id; + + itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p); +} + +static inline void nas_itti_establish_rej(const uint32_t ue_id, + const imsi_t *const imsi, uint8_t initial_req) +{ + MessageDef *message_p; + + message_p = itti_alloc_new_message(TASK_NAS, NAS_AUTHENTICATION_PARAM_REQ); + + hexa_to_ascii((uint8_t *)imsi->u.value, + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi, 8); + + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[15] = '\0'; + + if (isdigit(NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[14])) { + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = 15; + } else { + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = 14; + NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi[14] = '\0'; + } NAS_AUTHENTICATION_PARAM_REQ(message_p).initial_req = initial_req; - NAS_AUTHENTICATION_PARAM_REQ(message_p).imsi_length = imsi->length - imsi->u.num.parity; + NAS_AUTHENTICATION_PARAM_REQ(message_p).ue_id = ue_id; itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p); } diff --git a/openair-cn/NAS/nas_main.c b/openair-cn/NAS/nas_main.c index a32a494e051..906da44ffc0 100644 --- a/openair-cn/NAS/nas_main.c +++ b/openair-cn/NAS/nas_main.c @@ -113,9 +113,7 @@ next_message: itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p); } break; -#endif - -#if !defined(DISABLE_USE_NAS) +#else case NAS_UPLINK_DATA_IND: { nas_proc_ul_transfer_ind(NAS_UL_DATA_IND(received_message_p).UEid, NAS_UL_DATA_IND(received_message_p).nasMsg.data, @@ -125,6 +123,14 @@ next_message: case NAS_DOWNLINK_DATA_CNF: { // nas_proc_dl_transfer_cnf(NAS_DL_DATA_CNF(received_message_p).UEid); } break; + + case NAS_AUTHENTICATION_PARAM_RSP: { + nas_proc_auth_param_res(&NAS_AUTHENTICATION_PARAM_RSP(received_message_p)); + } break; + + case NAS_AUTHENTICATION_PARAM_FAIL: { + nas_proc_auth_param_fail(&NAS_AUTHENTICATION_PARAM_FAIL(received_message_p)); + } break; #endif case TERMINATE_MESSAGE: { @@ -148,7 +154,7 @@ int nas_init(mme_config_t *mme_config_p) NAS_DEBUG("Initializing NAS task interface\n"); #if !defined(DISABLE_USE_NAS) - nas_log_init(LOG_DEBUG); + nas_log_init(0x2F); nas_network_initialize(mme_config_p); #endif diff --git a/openair-cn/S6A/s6a_auth_info.c b/openair-cn/S6A/s6a_auth_info.c index a3ebd04711f..e7b900198da 100644 --- a/openair-cn/S6A/s6a_auth_info.c +++ b/openair-cn/S6A/s6a_auth_info.c @@ -152,8 +152,6 @@ int s6a_parse_authentication_info_avp(struct avp *avp_auth_info, DevCheck(hdr->avp_code == AVP_CODE_AUTHENTICATION_INFO, hdr->avp_code, AVP_CODE_AUTHENTICATION_INFO, 0); - /* Init the list of vectors */ - STAILQ_INIT(&authentication_info->e_utran_vectors); authentication_info->nb_of_vectors = 0; CHECK_FCT(fd_msg_browse(avp_auth_info, MSG_BRW_FIRST_CHILD, &avp, NULL)); @@ -162,11 +160,8 @@ int s6a_parse_authentication_info_avp(struct avp *avp_auth_info, switch(hdr->avp_code) { case AVP_CODE_E_UTRAN_VECTOR: { - struct eutran_vector_s *vector; - vector = calloc(1, sizeof(struct eutran_vector_s)); - CHECK_FCT(s6a_parse_e_utran_vector(avp, vector)); - STAILQ_INSERT_TAIL(&authentication_info->e_utran_vectors, - vector, entries); + DevAssert(authentication_info->nb_of_vectors == 0); + CHECK_FCT(s6a_parse_e_utran_vector(avp, &authentication_info->eutran_vector)); authentication_info->nb_of_vectors ++; } break; default: @@ -192,6 +187,8 @@ int s6a_aia_cb(struct msg **msg, struct avp *paramavp, MessageDef *message_p; s6a_auth_info_ans_t *s6a_auth_info_ans_p; + int skip_auth_res = 0; + DevAssert(msg != NULL); ans = *msg; @@ -240,7 +237,7 @@ int s6a_aia_cb(struct msg **msg, struct avp *paramavp, s6a_auth_info_ans_p->result.present = S6A_RESULT_EXPERIMENTAL; s6a_parse_experimental_result(avp, &s6a_auth_info_ans_p->result.choice.experimental); - goto err; + skip_auth_res = 1; } else { /* Neither result-code nor experimental-result is present -> * totally incorrect behaviour here. @@ -250,11 +247,14 @@ int s6a_aia_cb(struct msg **msg, struct avp *paramavp, goto err; } } - CHECK_FCT(fd_msg_search_avp(ans, s6a_fd_cnf.dataobj_s6a_authentication_info, &avp)); - if (avp) { - CHECK_FCT(s6a_parse_authentication_info_avp(avp, &s6a_auth_info_ans_p->auth_info)); - } else { - DevMessage("We requested E-UTRAN vectors with an immediate response...\n"); + + if (skip_auth_res == 0) { + CHECK_FCT(fd_msg_search_avp(ans, s6a_fd_cnf.dataobj_s6a_authentication_info, &avp)); + if (avp) { + CHECK_FCT(s6a_parse_authentication_info_avp(avp, &s6a_auth_info_ans_p->auth_info)); + } else { + DevMessage("We requested E-UTRAN vectors with an immediate response...\n"); + } } itti_send_msg_to_task(TASK_MME_APP, INSTANCE_DEFAULT, message_p); -- GitLab