Ejemplo n.º 1
0
/****************************************************************************
 **                                                                        **
 ** Name:    emm_as_set_security_data()                                    **
 **                                                                        **
 ** Description: Setup security data according to the given EPS security   **
 **      context when data transfer to lower layers is requested   **
 **                                                                        **
 ** Inputs:  args:      EPS security context currently in use      **
 **      is_new:    Indicates whether a new security context   **
 **             has just been taken into use               **
 **      is_ciphered:   Indicates whether the NAS message has to   **
 **             be sent ciphered                           **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     data:      EPS NAS security data to be setup          **
 **      Return:    None                                       **
 **      Others:    None                                       **
 **                                                                        **
 ***************************************************************************/
void emm_as_set_security_data(emm_as_security_data_t *data, const void *args,
                              int is_new, int is_ciphered)
{
  LOG_FUNC_IN;

  const emm_security_context_t *context = (emm_security_context_t *)(args);

  memset(data, 0, sizeof(emm_as_security_data_t));

  if ( context && (context->type != EMM_KSI_NOT_AVAILABLE) ) {
    /* 3GPP TS 24.301, sections 5.4.3.3 and 5.4.3.4
     * Once a valid EPS security context exists and has been taken
     * into use, UE and MME shall cipher and integrity protect all
     * NAS signalling messages with the selected NAS ciphering and
     * NAS integrity algorithms */
    LOG_TRACE(INFO,
              "EPS security context exists is new %u KSI %u SQN %u count %u",
              is_new,
              context->eksi,
              context->ul_count.seq_num,
              *(uint32_t *)(&context->ul_count));
    LOG_TRACE(INFO,
              "knas_int %s",dump_octet_string(&context->knas_int));
    LOG_TRACE(INFO,
              "knas_enc %s",dump_octet_string(&context->knas_enc));
    LOG_TRACE(INFO,
              "kasme %s",dump_octet_string(&context->kasme));

    data->is_new = is_new;
    data->ksi    = context->eksi;
    data->sqn    = context->ul_count.seq_num;
    // LG data->count = *(uint32_t *)(&context->ul_count);
    data->count  = 0x00000000 | (context->ul_count.overflow << 8 ) | context->ul_count.seq_num;
    /* NAS integrity and cyphering keys may not be available if the
     * current security context is a partial EPS security context
     * and not a full native EPS security context */
    data->k_int = &context->knas_int;

    if (is_ciphered) {
      /* 3GPP TS 24.301, sections 4.4.5
       * When the UE establishes a new NAS signalling connection,
       * it shall send initial NAS messages integrity protected
       * and unciphered */
      /* 3GPP TS 24.301, section 5.4.3.2
       * The MME shall send the SECURITY MODE COMMAND message integrity
       * protected and unciphered */
      LOG_TRACE(WARNING,
                "EPS security context exists knas_enc");
      data->k_enc = &context->knas_enc;
    }
  } else {
    LOG_TRACE(WARNING, "EMM_AS_NO_KEY_AVAILABLE");
    /* No valid EPS security context exists */
    data->ksi = EMM_AS_NO_KEY_AVAILABLE;
  }

  LOG_FUNC_OUT;
}
Ejemplo n.º 2
0
/****************************************************************************
 **                                                                        **
 ** Name:        usim_api_authenticate()                                   **
 **                                                                        **
 ** Description: Performs mutual authentication of the USIM to the network,**
 **              checking whether authentication token AUTN can be accep-  **
 **              ted. If so, returns an authentication response RES and    **
 **              the ciphering and integrity keys.                         **
 **              In case of synch failure, returns a re-synchronization    **
 **              token AUTS.                                               **
 **                                                                        **
 **              3GPP TS 31.102, section 7.1.1.1                           **
 **                                                                        **
 **              Authentication and key generating function algorithms are **
 **              specified in 3GPP TS 35.206.                              **
 **                                                                        **
 ** Inputs:      rand_pP:          Random challenge number                    **
 **              autn_pP:          Authentication token                       **
 **                             AUTN = (SQN xor AK) || AMF || MAC          **
 **                                         48          16     64 bits     **
 **              Others:        Security key                               **
 **                                                                        **
 ** Outputs:     auts_pP:          Re-synchronization token                   **
 **              res_pP:           Authentication response                    **
 **              ck_pP:            Ciphering key                              **
 **              ik_pP             Integrity key                              **
 **                                                                        **
 **              Return:        RETURNerror, RETURNok                      **
 **              Others:        None                                       **
 **                                                                        **
 ***************************************************************************/
int usim_api_authenticate(const OctetString* rand_pP, const OctetString* autn_pP,
                          OctetString* auts_pP, OctetString* res_pP,
                          OctetString* ck_pP, OctetString* ik_pP)
{
  LOG_FUNC_IN;

  int rc;
  int i;

  LOG_TRACE(DEBUG, "USIM-API  - rand :%s",dump_octet_string(rand_pP));
  LOG_TRACE(DEBUG, "USIM-API  - autn :%s",dump_octet_string(autn_pP));

  /* Compute the authentication response RES = f2K (RAND) */
  /* Compute the cipher key CK = f3K (RAND) */
  /* Compute the integrity key IK = f4K (RAND) */
  /* Compute the anonymity key AK = f5K (RAND) */
#define USIM_API_AK_SIZE 6
  u8 ak[USIM_API_AK_SIZE];
  f2345(_usim_api_k, rand_pP->value,
        res_pP->value, ck_pP->value, ik_pP->value, ak);
  LOG_TRACE(DEBUG, "USIM-API  - res(f2)  :%s",dump_octet_string(res_pP));
  LOG_TRACE(DEBUG, "USIM-API  - ck(f3)   :%s",dump_octet_string(ck_pP));
  LOG_TRACE(DEBUG, "USIM-API  - ik(f4)   :%s",dump_octet_string(ik_pP));
  LOG_TRACE(DEBUG, "USIM-API  - ak(f5)   : %02X%02X%02X%02X%02X%02X",
            ak[0],ak[1],ak[2],ak[3],ak[4],ak[5]);

  /* Retrieve the sequence number SQN = (SQN ⊕ AK) ⊕ AK */
#define USIM_API_SQN_SIZE USIM_API_AK_SIZE
  u8 sqn[USIM_API_SQN_SIZE];

  for (i = 0; i < USIM_API_SQN_SIZE; i++) {
    sqn[i] = autn_pP->value[i] ^ ak[i];
  }

  LOG_TRACE(DEBUG, "USIM-API  - Retrieved SQN %02X%02X%02X%02X%02X%02X",
            sqn[0],sqn[1],sqn[2],sqn[3],sqn[4],sqn[5]);

  /* Compute XMAC = f1K (SQN || RAND || AMF) */
#define USIM_API_XMAC_SIZE 8
  u8 xmac[USIM_API_XMAC_SIZE];
  f1(_usim_api_k, rand_pP->value, sqn, &autn_pP->value[USIM_API_SQN_SIZE], xmac);
  LOG_TRACE(DEBUG,
            "USIM-API  - Computed XMAC %02X%02X%02X%02X%02X%02X%02X%02X",
            xmac[0],xmac[1],xmac[2],xmac[3],
            xmac[4],xmac[5],xmac[6],xmac[7]);

  /* Compare the XMAC with the MAC included in AUTN */
#define USIM_API_AMF_SIZE 2

  if ( memcmp(xmac, &autn_pP->value[USIM_API_SQN_SIZE + USIM_API_AMF_SIZE],
              USIM_API_XMAC_SIZE) != 0 ) {
    LOG_TRACE(INFO,
              "USIM-API  - Comparing the XMAC with the MAC included in AUTN Failed");
    //LOG_FUNC_RETURN (RETURNerror);
  } else {
    LOG_TRACE(INFO,
              "USIM-API  - Comparing the XMAC with the MAC included in AUTN Succeeded");
  }

  /* Verify that the received sequence number SQN is in the correct range */
  rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]);

  if (rc != RETURNok) {
    /* Synchronisation failure; compute the AUTS parameter */

    /* Concealed value of the counter SQNms in the USIM:
     * Conc(SQNMS) = SQNMS ⊕ f5*K(RAND) */
    f5star(_usim_api_k, rand_pP->value, ak);

#define USIM_API_SQNMS_SIZE USIM_API_SQN_SIZE
    u8 sqn_ms[USIM_API_SQNMS_SIZE];
    memset(sqn_ms, 0, USIM_API_SQNMS_SIZE);
#define USIM_API_SQN_MS_SIZE  3

    for (i = 0; i < USIM_API_SQN_MS_SIZE; i++) {
#warning "LG:BUG HERE TODO"
      sqn_ms[USIM_API_SQNMS_SIZE - i] =
        ((uint8_t*)(_usim_api_data.sqn_ms))[USIM_API_SQN_MS_SIZE - i];
    }

    u8 sqnms[USIM_API_SQNMS_SIZE];

    for (i = 0; i < USIM_API_SQNMS_SIZE; i++) {
      sqnms[i] = sqn_ms[i] ^ ak[i];
    }

    LOG_TRACE(DEBUG, "USIM-API  - SQNms %02X%02X%02X%02X%02X%02X",
              sqnms[0],sqnms[1],sqnms[2],sqnms[3],sqnms[4],sqnms[5]);

    /* Synchronisation message authentication code:
     * MACS = f1*K(SQNMS || RAND || AMF) */
#define USIM_API_MACS_SIZE USIM_API_XMAC_SIZE
    u8 macs[USIM_API_MACS_SIZE];
    f1star(_usim_api_k, rand_pP->value, sqn_ms,
           &rand_pP->value[USIM_API_SQN_SIZE], macs);
    LOG_TRACE(DEBUG, "USIM-API  - MACS %02X%02X%02X%02X%02X%02X%02X%02X",
              macs[0],macs[1],macs[2],macs[3],
              macs[4],macs[5],macs[6],macs[7]);

    /* Synchronisation authentication token:
     * AUTS = Conc(SQNMS) || MACS */
    memcpy(&auts_pP->value[0], sqnms, USIM_API_SQNMS_SIZE);
    memcpy(&auts_pP->value[USIM_API_SQNMS_SIZE], macs, USIM_API_MACS_SIZE);
  }

  LOG_FUNC_RETURN (RETURNok);
}
Ejemplo n.º 3
0
/****************************************************************************
 **                                                                        **
 ** Name:    esm_send_activate_default_eps_bearer_context_request()    **
 **                                                                        **
 ** Description: Builds Activate Default EPS Bearer Context Request        **
 **      message                                                   **
 **                                                                        **
 **      The activate default EPS bearer context request message   **
 **      is sent by the network to the UE to request activation of **
 **      a default EPS bearer context.                             **
 **                                                                        **
 ** Inputs:  pti:       Procedure transaction identity             **
 **      ebi:       EPS bearer identity                        **
 **      qos:       Subscribed EPS quality of service          **
 **      apn:       Access Point Name in used                  **
 **      pdn_addr:  PDN IPv4 address and/or IPv6 suffix        **
 **      esm_cause: ESM cause code                             **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     msg:       The ESM message to be sent                 **
 **      Return:    RETURNok, RETURNerror                      **
 **      Others:    None                                       **
 **                                                                        **
 ***************************************************************************/
int
esm_send_activate_default_eps_bearer_context_request (
  int pti,
  int ebi,
  activate_default_eps_bearer_context_request_msg * msg,
  const OctetString * apn,
  const ProtocolConfigurationOptions * pco,
  int pdn_type,
  const OctetString * pdn_addr,
  const EpsQualityOfService * qos,
  int esm_cause)
{
  LOG_FUNC_IN;
  /*
   * Mandatory - ESM message header
   */
  msg->protocoldiscriminator = EPS_SESSION_MANAGEMENT_MESSAGE;
  msg->epsbeareridentity = ebi;
  msg->messagetype = ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST;
  msg->proceduretransactionidentity = pti;
  /*
   * Mandatory - EPS QoS
   */
  msg->epsqos = *qos;
  LOG_TRACE (INFO, "ESM-SAP   - epsqos  qci:  %u", qos->qci);

  if (qos->bitRatesPresent) {
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  maxBitRateForUL:  %u", qos->bitRates.maxBitRateForUL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  maxBitRateForDL:  %u", qos->bitRates.maxBitRateForDL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  guarBitRateForUL: %u", qos->bitRates.guarBitRateForUL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  guarBitRateForDL: %u", qos->bitRates.guarBitRateForDL);
  } else {
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  no bit rates defined");
  }

  if (qos->bitRatesExtPresent) {
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  maxBitRateForUL  Ext: %u", qos->bitRatesExt.maxBitRateForUL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  maxBitRateForDL  Ext: %u", qos->bitRatesExt.maxBitRateForDL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  guarBitRateForUL Ext: %u", qos->bitRatesExt.guarBitRateForUL);
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  guarBitRateForDL Ext: %u", qos->bitRatesExt.guarBitRateForDL);
  } else {
    LOG_TRACE (INFO, "ESM-SAP   - epsqos  no bit rates ext defined");
  }

  if ((apn == NULL) || ((apn != NULL) && (apn->value == NULL))) {
    LOG_TRACE (WARNING, "ESM-SAP   - apn is NULL!");
  }

  LOG_TRACE (INFO, "ESM-SAP   - apn is %s", apn->value);
  /*
   * Mandatory - Access Point Name
   */
  msg->accesspointname.accesspointnamevalue = *apn;
  /*
   * Mandatory - PDN address
   */
  LOG_TRACE (INFO, "ESM-SAP   - pdn_type is %u", pdn_type);
  msg->pdnaddress.pdntypevalue = pdn_type;
  LOG_TRACE (INFO, "ESM-SAP   - pdn_addr is %u", dump_octet_string (pdn_addr));
  msg->pdnaddress.pdnaddressinformation = *pdn_addr;
  /*
   * Optional - ESM cause code
   */
  msg->presencemask = 0;

  if (esm_cause != ESM_CAUSE_SUCCESS) {
    msg->presencemask |= ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_ESM_CAUSE_PRESENT;
    msg->esmcause = esm_cause;
  }

  if (pco != NULL) {
    msg->presencemask |= ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT;
    msg->protocolconfigurationoptions = *pco;
  }
#warning "TEST LG FORCE APN-AMBR"
  LOG_TRACE (INFO, "ESM-SAP   - FORCE APN-AMBR");
  msg->presencemask |= ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST_APNAMBR_PRESENT;
  msg->apnambr.apnambrfordownlink = 0xfe;       // (8640kbps)
  msg->apnambr.apnambrforuplink = 0xfe; // (8640kbps)
  msg->apnambr.apnambrfordownlink_extended = 0xde;      // (200Mbps)
  msg->apnambr.apnambrforuplink_extended = 0x9e;        // (100Mbps)
  msg->apnambr.apnambrfordownlink_extended2 = 0;
  msg->apnambr.apnambrforuplink_extended2 = 0;
  msg->apnambr.extensions = 0 | APN_AGGREGATE_MAXIMUM_BIT_RATE_MAXIMUM_EXTENSION_PRESENT;
  LOG_TRACE (INFO, "ESM-SAP   - Send Activate Default EPS Bearer Context " "Request message (pti=%d, ebi=%d)", msg->proceduretransactionidentity, msg->epsbeareridentity);
  LOG_FUNC_RETURN (RETURNok);
}