/****************************************************************************
 **                                                                        **
 ** 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);
}
Exemplo n.º 2
0
/****************************************************************************
 **                                                                        **
 ** 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);
}
Exemplo n.º 8
0
/****************************************************************************
 **                                                                        **
 ** 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);
}