/**************************************************************************** ** ** ** 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); }