Commit 2817ad4d authored by Cedric Roux's avatar Cedric Roux

- 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
parent ae4b3650
......@@ -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 {
......
......@@ -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"
......
......@@ -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
......@@ -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;
......
......@@ -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)
......
......@@ -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
......@@ -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
......@@ -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));
......
......@@ -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_ */
......@@ -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: {
......
......@@ -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 {
......
......@@ -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;
}
......@@ -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
......
......@@ -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;
......
......@@ -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
/*
......
......@@ -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) {
......
/*****************************************************************************
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);
}
/*****************************************************************************
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_ */
/*****************************************************************************
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__ */
......@@ -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);
}
......
......@@ -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;
......
......@@ -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;
/****************************************************************************/
......
......@@ -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
/****************************************************************************/
......
......@@ -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__*/
......@@ -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);
......
......@@ -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 \
......
......@@ -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;
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment