/**************************************************************************** ** ** ** Name: _authentication_t3460_handler() ** ** ** ** Description: T3460 timeout handler ** ** Upon T3460 timer expiration, the authentication request ** ** message is retransmitted and the timer restarted. When ** ** retransmission counter is exceed, the MME shall abort the ** ** authentication procedure and any ongoing EMM specific ** ** procedure and release the NAS signalling connection. ** ** ** ** 3GPP TS 24.301, section 5.4.2.7, case b ** ** ** ** Inputs: args: handler parameters ** ** Others: None ** ** ** ** Outputs: None ** ** Return: None ** ** Others: None ** ** ** ***************************************************************************/ static void * _authentication_t3460_handler ( void *args) { LOG_FUNC_IN; int rc; authentication_data_t *data = (authentication_data_t *) (args); /* * Increment the retransmission counter */ data->retransmission_count += 1; LOG_TRACE (WARNING, "EMM-PROC - T3460 timer expired, retransmission " "counter = %d", data->retransmission_count); if (data->retransmission_count < AUTHENTICATION_COUNTER_MAX) { /* * Send authentication request message to the UE */ rc = _authentication_request (data); } else { unsigned int ueid = data->ueid; /* * Set the failure notification indicator */ data->notify_failure = TRUE; /* * Abort the authentication procedure */ rc = _authentication_abort (data); /* * Release the NAS signalling connection */ if (rc != RETURNerror) { emm_sap_t emm_sap; emm_sap.primitive = EMMAS_RELEASE_REQ; emm_sap.u.emm_as.u.release.guti = NULL; emm_sap.u.emm_as.u.release.ueid = ueid; emm_sap.u.emm_as.u.release.cause = EMM_AS_CAUSE_AUTHENTICATION; rc = emm_sap_send (&emm_sap); } } LOG_FUNC_RETURN (NULL); }
/* *----------------------------------------------------------------------------- * Process EPS Mobility Management NAS message *----------------------------------------------------------------------------- */ static int _nas_process_emm( char* buffer, int length, const EMM_msg* msg) { int index = 0; const EsmMessageContainer* esm_container = NULL; printf("INFO\t: Process %s\n", emmMsgType(msg->header.message_type)); index += snprintf(buffer + index, length - index, "%s (", emmMsgType(msg->header.message_type)); switch (msg->header.message_type) { case ATTACH_REQUEST: esm_container = &msg->attach_request.esmmessagecontainer; index += _attach_request(buffer + index, length - index, &msg->attach_request); break; case ATTACH_ACCEPT: esm_container = &msg->attach_accept.esmmessagecontainer; index += _attach_accept(buffer + index, length - index, &msg->attach_accept); break; case ATTACH_REJECT: esm_container = &msg->attach_reject.esmmessagecontainer; index += _attach_reject(buffer + index, length - index, &msg->attach_reject); break; case ATTACH_COMPLETE: esm_container = &msg->attach_complete.esmmessagecontainer; index += _attach_complete(buffer + index, length - index, &msg->attach_complete); break; case DETACH_REQUEST: index += _detach_request(buffer + index, length - index, &msg->detach_request); break; case DETACH_ACCEPT: index += _detach_accept(buffer + index, length - index, &msg->detach_accept); break; case IDENTITY_REQUEST: index += _identity_request(buffer + index, length - index, &msg->identity_request); break; case IDENTITY_RESPONSE: index += _identity_response(buffer + index, length - index, &msg->identity_response); break; case AUTHENTICATION_REQUEST: index += _authentication_request(buffer + index, length - index, &msg->authentication_request); break; case AUTHENTICATION_RESPONSE: index += _authentication_response(buffer + index, length - index, &msg->authentication_response); break; case AUTHENTICATION_FAILURE: index += _authentication_failure(buffer + index, length - index, &msg->authentication_failure); break; case AUTHENTICATION_REJECT: index += _authentication_reject(buffer + index, length - index, &msg->authentication_reject); break; case SECURITY_MODE_COMMAND: index += _security_mode_command(buffer + index, length - index, &msg->security_mode_command); break; case SECURITY_MODE_COMPLETE: index += _security_mode_complete(buffer + index, length - index, &msg->security_mode_complete); break; case SECURITY_MODE_REJECT: index += _security_mode_reject(buffer + index, length - index, &msg->security_mode_reject); break; case EMM_STATUS: index += _emm_status(buffer + index, length - index, &msg->emm_status); break; default: printf("WARNING\t: %s - EMM NAS message is not valid (0x%x)\n", __FUNCTION__, msg->header.message_type); break; } index += snprintf(buffer + index, length - index, ")"); /* Process ESM message container */ if (esm_container) { index += _esm_message_container(buffer + index, length - index, esm_container); } return (index); }
/**************************************************************************** ** ** ** Name: emm_proc_authentication() ** ** ** ** Description: Initiates authentication procedure to establish partial ** ** native EPS security context in the UE and the MME. ** ** ** ** 3GPP TS 24.301, section 5.4.2.2 ** ** The network initiates the authentication procedure by ** ** sending an AUTHENTICATION REQUEST message to the UE and ** ** starting the timer T3460. The AUTHENTICATION REQUEST mes- ** ** sage contains the parameters necessary to calculate the ** ** authentication response. ** ** ** ** Inputs: ueid: UE lower layer identifier ** ** ksi: NAS key set identifier ** ** rand: Random challenge number ** ** autn: Authentication token ** ** success: Callback function executed when the authen-** ** tication procedure successfully completes ** ** reject: Callback function executed when the authen-** ** tication procedure fails or is rejected ** ** failure: Callback function executed whener a lower ** ** layer failure occured before the authenti- ** ** cation procedure comnpletes ** ** Others: None ** ** ** ** Outputs: None ** ** Return: RETURNok, RETURNerror ** ** Others: None ** ** ** ***************************************************************************/ int emm_proc_authentication(void *ctx, unsigned int ueid, int ksi, const OctetString *_rand, const OctetString *autn, emm_common_success_callback_t success, emm_common_reject_callback_t reject, emm_common_failure_callback_t failure) { int rc = RETURNerror; authentication_data_t *data; LOG_FUNC_IN; LOG_TRACE(INFO, "EMM-PROC - Initiate authentication KSI = %d, ctx = %p", ksi, ctx); /* Allocate parameters of the retransmission timer callback */ data = (authentication_data_t *)malloc(sizeof(authentication_data_t)); if (data != NULL) { /* Setup ongoing EMM procedure callback functions */ rc = emm_proc_common_initialize(ueid, success, reject, failure, _authentication_abort, data); if (rc != RETURNok) { LOG_TRACE(WARNING, "Failed to initialize EMM callback functions"); LOG_FUNC_RETURN (RETURNerror); } /* Set the UE identifier */ data->ueid = ueid; /* Reset the retransmission counter */ data->retransmission_count = 0; /* Set the key set identifier */ data->ksi = ksi; /* Set the authentication random challenge number */ if (_rand->length > 0) { data->rand.value = (uint8_t *)malloc(_rand->length); data->rand.length = 0; if (data->rand.value) { memcpy(data->rand.value, _rand->value, _rand->length); data->rand.length = _rand->length; } } /* Set the authentication token */ if (autn->length > 0) { data->autn.value = (uint8_t *)malloc(autn->length); data->autn.length = 0; if (data->autn.value) { memcpy(data->autn.value, autn->value, autn->length); data->autn.length = autn->length; } } /* Set the failure notification indicator */ data->notify_failure = FALSE; /* Send authentication request message to the UE */ rc = _authentication_request(data); if (rc != RETURNerror) { /* * Notify EMM that common procedure has been initiated */ MSC_LOG_TX_MESSAGE( MSC_NAS_EMM_MME, MSC_NAS_EMM_MME, NULL,0, "0 EMMREG_COMMON_PROC_REQ ue id "NAS_UE_ID_FMT" (authentication)", ueid); emm_sap_t emm_sap; emm_sap.primitive = EMMREG_COMMON_PROC_REQ; emm_sap.u.emm_reg.ueid = ueid; emm_sap.u.emm_reg.ctx = ctx; rc = emm_sap_send(&emm_sap); } } LOG_FUNC_RETURN (rc); }