/**************************************************************************** ** ** ** Name: _authentication_reject() ** ** ** ** Description: Sends AUTHENTICATION REJECT message ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ static int _authentication_reject(unsigned int ueid) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx; /* * Notify EMM-AS SAP that Authentication Reject message has to be sent * to the UE */ emm_sap.primitive = EMMAS_SECURITY_REJ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; #if defined(NAS_BUILT_IN_EPC) emm_ctx = emm_data_context_get(&_emm_data, ueid); #else emm_ctx = _emm_data.ctx[ueid]; #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: emm_proc_common_abort() ** ** ** ** Description: The ongoing EMM procedure has been aborted. The network ** ** performs required actions related to the EMM common pro- ** ** cedure previously initiated between the UE with the spe- ** ** cified identifier and the MME. ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** Others: _emm_common_data ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_common_abort ( unsigned int ueid) { emm_common_data_t *emm_common_data_ctx = NULL; emm_common_failure_callback_t emm_callback; int rc = RETURNerror; LOG_FUNC_IN; #if NAS_BUILT_IN_EPC DevCheck (ueid > 0, ueid, 0, 0); emm_common_data_ctx = emm_common_data_context_get (&emm_common_data_head, ueid); #else assert (ueid < EMM_DATA_NB_UE_MAX); emm_common_data_ctx = _emm_common_data[ueid]; #endif assert (emm_common_data_ctx != NULL); emm_callback = emm_common_data_ctx->abort; if (emm_callback) { struct emm_data_context_s *ctx = NULL; #if NAS_BUILT_IN_EPC ctx = emm_data_context_get (&_emm_data, ueid); #else ctx = _emm_data.ctx[ueid]; #endif rc = (*emm_callback) (ctx); } _emm_common_cleanup (ueid); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _authentication_abort() ** ** ** ** Description: Aborts the authentication procedure currently in progress ** ** ** ** Inputs: args: Authentication data to be released ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3460 ** ** ** ***************************************************************************/ static int _authentication_abort ( void *args) { LOG_FUNC_IN; int rc = RETURNerror; struct emm_data_context_s *emm_ctx; authentication_data_t *data = (authentication_data_t *) (args); if (data) { unsigned int ueid = data->ueid; int notify_failure = data->notify_failure; LOG_TRACE (WARNING, "EMM-PROC - Abort authentication procedure " "(ueid=" NAS_UE_ID_FMT ")", ueid); #if NAS_BUILT_IN_EPC emm_ctx = emm_data_context_get (&_emm_data, ueid); #else emm_ctx = _emm_data.ctx[ueid]; #endif if (emm_ctx) { /* * Stop timer T3460 */ if (emm_ctx->T3460.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE (INFO, "EMM-PROC - Stop timer T3460 (%d)", emm_ctx->T3460.id); emm_ctx->T3460.id = nas_timer_stop (emm_ctx->T3460.id); MSC_LOG_EVENT (MSC_NAS_EMM_MME, "0 T3460 stopped UE " NAS_UE_ID_FMT " ", data->ueid); } } /* * Release retransmission timer paramaters */ if (data->rand.length > 0) { free (data->rand.value); } if (data->autn.length > 0) { free (data->autn.value); } free (data); /* * Notify EMM that the authentication procedure failed */ if (notify_failure) { emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send (&emm_sap); } else { rc = RETURNok; } } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _authentication_request() ** ** ** ** Description: Sends AUTHENTICATION REQUEST message and start timer T3460** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: T3460 ** ** ** ***************************************************************************/ int _authentication_request(authentication_data_t *data) { LOG_FUNC_IN; emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx; /* * Notify EMM-AS SAP that Authentication Request message has to be sent * to the UE */ emm_sap.primitive = EMMAS_SECURITY_REQ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = data->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_AUTH; emm_sap.u.emm_as.u.security.ksi = data->ksi; emm_sap.u.emm_as.u.security.rand = &data->rand; emm_sap.u.emm_as.u.security.autn = &data->autn; /* TODO: check for pointer validity */ #if defined(NAS_BUILT_IN_EPC) emm_ctx = emm_data_context_get(&_emm_data, data->ueid); #else emm_ctx = _emm_data.ctx[data->ueid]; #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMAS_SECURITY_REQ ue id "NAS_UE_ID_FMT" ", data->ueid); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { if (emm_ctx) { if (emm_ctx->T3460.id != NAS_TIMER_INACTIVE_ID) { /* Re-start T3460 timer */ emm_ctx->T3460.id = nas_timer_restart(emm_ctx->T3460.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 restarted UE "NAS_UE_ID_FMT" ", data->ueid); } else { /* Start T3460 timer */ emm_ctx->T3460.id = nas_timer_start(emm_ctx->T3460.sec, _authentication_t3460_handler, data); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 started UE "NAS_UE_ID_FMT" ", data->ueid); } } LOG_TRACE(INFO,"EMM-PROC - Timer T3460 (%d) expires in %ld seconds", emm_ctx->T3460.id, emm_ctx->T3460.sec); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _identification_request() ** ** ** ** Description: Sends IDENTITY REQUEST message and start timer T3470. ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3470 ** ** ** ***************************************************************************/ int _identification_request(identification_data_t *data) { emm_sap_t emm_sap; int rc; struct emm_data_context_s *emm_ctx = NULL; LOG_FUNC_IN; /* * Notify EMM-AS SAP that Identity Request message has to be sent * to the UE */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMAS_SECURITY_REQ ue id "NAS_UE_ID_FMT" ", data->ueid); emm_sap.primitive = EMMAS_SECURITY_REQ; emm_sap.u.emm_as.u.security.guti = NULL; emm_sap.u.emm_as.u.security.ueid = data->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; emm_sap.u.emm_as.u.security.identType = data->type; #if defined(NAS_BUILT_IN_EPC) if (data->ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, data->ueid); } #else if (data->ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[data->ueid]; } #endif /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, emm_ctx->security, FALSE, TRUE); rc = emm_sap_send(&emm_sap); if (rc != RETURNerror) { if (emm_ctx->T3470.id != NAS_TIMER_INACTIVE_ID) { /* Re-start T3470 timer */ emm_ctx->T3470.id = nas_timer_restart(emm_ctx->T3470.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 restarted UE "NAS_UE_ID_FMT" ", data->ueid); } else { /* Start T3470 timer */ emm_ctx->T3470.id = nas_timer_start(emm_ctx->T3470.sec, _identification_t3470_handler, data); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 started UE "NAS_UE_ID_FMT" ", data->ueid); } LOG_TRACE(INFO,"EMM-PROC - Timer T3470 (%d) expires in %ld seconds", emm_ctx->T3470.id, emm_ctx->T3470.sec); } LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: _identification_abort() ** ** ** ** Description: Aborts the identification procedure currently in progress ** ** ** ** Inputs: args: Identification data to be released ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: T3470 ** ** ** ***************************************************************************/ static int _identification_abort(void *args) { LOG_FUNC_IN; int rc = RETURNerror; identification_data_t *data = (identification_data_t *)(args); if (data) { unsigned int ueid = data->ueid; int notify_failure = data->notify_failure; struct emm_data_context_s *emm_ctx = NULL; /* Get the UE context */ #if defined(NAS_BUILT_IN_EPC) if (ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, ueid); } #else if (ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[ueid]; } #endif LOG_TRACE(WARNING, "EMM-PROC - Abort identification procedure " "(ueid="NAS_UE_ID_FMT")", ueid); /* Stop timer T3470 */ if (emm_ctx->T3470.id != NAS_TIMER_INACTIVE_ID) { LOG_TRACE(INFO, "EMM-PROC - Stop timer T3470 (%d)", emm_ctx->T3470.id); emm_ctx->T3470.id = nas_timer_stop(emm_ctx->T3470.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3470 stopped UE "NAS_UE_ID_FMT" ", data->ueid); } /* Release retransmission timer paramaters */ free(data); /* * Notify EMM that the identification procedure failed */ if (notify_failure) { MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_REJ ue id "NAS_UE_ID_FMT" ", ueid); emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; rc = emm_sap_send(&emm_sap); } else { rc = RETURNok; } } LOG_FUNC_RETURN(rc); }
/**************************************************************************** ** ** ** Name: emm_proc_authentication_complete() ** ** ** ** Description: Performs the authentication completion procedure executed ** ** by the network. ** ** ** ** 3GPP TS 24.301, section 5.4.2.4 ** ** Upon receiving the AUTHENTICATION RESPONSE message, the ** ** MME shall stop timer T3460 and check the correctness of ** ** the RES parameter. ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** emm_cause: Authentication failure EMM cause code ** ** res: Authentication response parameter. or auts ** ** in case of sync failure ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_data, T3460 ** ** ** ***************************************************************************/ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, const OctetString *res) { int rc; emm_sap_t emm_sap; LOG_FUNC_IN; LOG_TRACE(INFO, "EMM-PROC - Authentication complete (ueid="NAS_UE_ID_FMT", cause=%d)", ueid, emm_cause); /* Release retransmission timer paramaters */ authentication_data_t *data = (authentication_data_t *)(emm_proc_common_get_args(ueid)); if (data) { if (data->rand.length > 0) { free(data->rand.value); } if (data->autn.length > 0) { free(data->autn.value); } free(data); } /* Get the UE context */ emm_data_context_t *emm_ctx = NULL; #if defined(NAS_BUILT_IN_EPC) if (ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, ueid); } #else if (ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[ueid]; } #endif if (emm_ctx) { /* Stop timer T3460 */ LOG_TRACE(INFO, "EMM-PROC - Stop timer T3460 (%d)", emm_ctx->T3460.id); emm_ctx->T3460.id = nas_timer_stop(emm_ctx->T3460.id); MSC_LOG_EVENT(MSC_NAS_EMM_MME, "0 T3460 stopped UE "NAS_UE_ID_FMT" ", data->ueid); } if (emm_cause == EMM_CAUSE_SUCCESS) { /* Check the received RES parameter */ if ( (emm_ctx == NULL) || (memcmp(res->value, &emm_ctx->vector.xres, res->length) != 0) ) { /* RES does not match the XRES parameter */ LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE"); emm_cause = EMM_CAUSE_ILLEGAL_UE; } else { LOG_TRACE(DEBUG, "EMM-PROC - Success to authentify the UE RESP XRES == XRES UE CONTEXT"); } } if (emm_cause != EMM_CAUSE_SUCCESS) { switch (emm_cause) { #if defined(NAS_BUILT_IN_EPC) case EMM_CAUSE_SYNCH_FAILURE: /* USIM has detected a mismatch in SQN. * Ask for a new vector. */ MSC_LOG_EVENT( MSC_NAS_EMM_MME, "0 SQN SYNCH_FAILURE ue id "NAS_UE_ID_FMT" ", ueid); LOG_TRACE(DEBUG, "EMM-PROC - USIM has detected a mismatch in SQN Ask for a new vector"); nas_itti_auth_info_req(ueid, emm_ctx->imsi, 0, res->value); rc = RETURNok; LOG_FUNC_RETURN (rc); break; #endif default: LOG_TRACE(DEBUG, "EMM-PROC - The MME received an authentication failure message or the RES does not match the XRES parameter computed by the network"); /* The MME received an authentication failure message or the RES * contained in the Authentication Response message received from * the UE does not match the XRES parameter computed by the network */ (void) _authentication_reject(ueid); /* * Notify EMM that the authentication procedure failed */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_REJ ue id "NAS_UE_ID_FMT" ", ueid); emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = emm_ctx; break; } } else { /* * Notify EMM that the authentication procedure successfully completed */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_CNF ue id "NAS_UE_ID_FMT" ", ueid); LOG_TRACE(DEBUG, "EMM-PROC - Notify EMM that the authentication procedure successfully completed"); emm_sap.primitive = EMMREG_COMMON_PROC_CNF; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = emm_ctx; emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; } rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }
/**************************************************************************** ** ** ** Name: emm_proc_identification_complete() ** ** ** ** Description: Performs the identification completion procedure executed ** ** by the network. ** ** ** ** 3GPP TS 24.301, section 5.4.4.4 ** ** Upon receiving the IDENTITY RESPONSE message, the MME ** ** shall stop timer T3470. ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** imsi: The IMSI received from the UE ** ** imei: The IMEI received from the UE ** ** tmsi: The TMSI received from the UE ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: _emm_data, T3470 ** ** ** ***************************************************************************/ int emm_proc_identification_complete(unsigned int ueid, const imsi_t *imsi, const imei_t *imei, UInt32_t *tmsi) { int rc = RETURNerror; emm_sap_t emm_sap; emm_data_context_t *emm_ctx = NULL; LOG_FUNC_IN; LOG_TRACE(INFO, "EMM-PROC - Identification complete (ueid=%u)", ueid); /* Stop timer T3470 */ LOG_TRACE(INFO, "EMM-PROC - Stop timer T3470 (%d)", T3470.id); T3470.id = nas_timer_stop(T3470.id); /* Release retransmission timer paramaters */ identification_data_t *data = (identification_data_t *)(emm_proc_common_get_args(ueid)); if (data) { free(data); } /* Get the UE context */ #if defined(EPC_BUILD) if (ueid > 0) { emm_ctx = emm_data_context_get(&_emm_data, ueid); } #else if (ueid < EMM_DATA_NB_UE_MAX) { emm_ctx = _emm_data.ctx[ueid]; } #endif if (emm_ctx) { if (imsi) { /* Update the IMSI */ if (emm_ctx->imsi == NULL) { emm_ctx->imsi = (imsi_t *)malloc(sizeof(imsi_t)); } if (emm_ctx->imsi) { memcpy(emm_ctx->imsi, imsi, sizeof(imsi_t)); } } else if (imei) { /* Update the IMEI */ if (emm_ctx->imei == NULL) { emm_ctx->imei = (imei_t *)malloc(sizeof(imei_t)); } if (emm_ctx->imei) { memcpy(emm_ctx->imei, imei, sizeof(imei_t)); } } else if (tmsi) { /* Update the GUTI */ if (emm_ctx->guti == NULL) { emm_ctx->guti = (GUTI_t *)malloc(sizeof(GUTI_t)); } if (emm_ctx->guti) { memcpy(&emm_ctx->guti->gummei, &_emm_data.conf.gummei, sizeof(gummei_t)); emm_ctx->guti->m_tmsi = *tmsi; } } /* * Notify EMM that the identification procedure successfully completed */ emm_sap.primitive = EMMREG_COMMON_PROC_CNF; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = emm_ctx; emm_sap.u.emm_reg.u.common.is_attached = emm_ctx->is_attached; } else { LOG_TRACE(ERROR, "EMM-PROC - No EMM context exists"); /* * Notify EMM that the identification procedure failed */ emm_sap.primitive = EMMREG_COMMON_PROC_REJ; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = emm_ctx; } rc = emm_sap_send(&emm_sap); LOG_FUNC_RETURN (rc); }