|
|
|
@ -129,35 +129,31 @@ nas::handle_nas_authentication_response(srslte::byte_buffer_t *nas_msg, srslte::
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_buffer, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx;
|
|
|
|
|
ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx;
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_SECURITY_MODE_COMPLETE_MSG_STRUCT sm_comp;
|
|
|
|
|
|
|
|
|
|
//Get NAS authentication response
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_security_mode_complete_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &sm_comp);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info("Security Mode Command Complete -- IMSI: %lu\n", emm_ctx->imsi);
|
|
|
|
|
m_s1ap_log->console("Security Mode Command Complete -- IMSI: %lu\n", emm_ctx->imsi);
|
|
|
|
|
if (ecm_ctx->eit == true) {
|
|
|
|
|
pack_esm_information_request(reply_buffer, emm_ctx, ecm_ctx);
|
|
|
|
|
m_s1ap_log->console("Sending ESM information request\n");
|
|
|
|
|
m_s1ap_log->info_hex(reply_buffer->msg, reply_buffer->N_bytes, "Sending ESM information request\n");
|
|
|
|
|
m_nas_log->info("Security Mode Command Complete -- IMSI: %lu\n", m_emm_ctx.imsi);
|
|
|
|
|
m_nas_log->console("Security Mode Command Complete -- IMSI: %lu\n", m_emm_ctx.imsi);
|
|
|
|
|
if (m_ecm_ctx.eit == true) {
|
|
|
|
|
pack_esm_information_request(reply_buffer);
|
|
|
|
|
m_nas_log->console("Sending ESM information request\n");
|
|
|
|
|
m_nas_log->info_hex(reply_buffer->msg, reply_buffer->N_bytes, "Sending ESM information request\n");
|
|
|
|
|
*reply_flag = true;
|
|
|
|
|
} else {
|
|
|
|
|
//Get subscriber info from HSS
|
|
|
|
|
uint8_t default_bearer=5;
|
|
|
|
|
m_hss->gen_update_loc_answer(emm_ctx->imsi,&ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_s1ap_log->debug("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_s1ap_log->console("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_hss->gen_update_loc_answer(m_emm_ctx.imsi, &m_esm_ctx[default_bearer].qci);
|
|
|
|
|
m_nas_log->debug("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
|
|
|
|
|
m_nas_log->console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
|
|
|
|
|
//FIXME The packging of GTP-C messages is not ready.
|
|
|
|
|
//This means that GTP-U tunnels are created with function calls, as opposed to GTP-C.
|
|
|
|
|
m_mme_gtpc->send_create_session_request(emm_ctx->imsi);
|
|
|
|
|
m_gtpc->send_create_session_request(m_emm_ctx.imsi);
|
|
|
|
|
*reply_flag = false; //No reply needed
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -165,7 +161,7 @@ nas::handle_nas_security_mode_complete(srslte::byte_buffer_t *nas_msg, srslte::b
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
nas::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_ATTACH_COMPLETE_MSG_STRUCT attach_comp;
|
|
|
|
@ -173,81 +169,76 @@ nas::handle_nas_attach_complete(srslte::byte_buffer_t *nas_msg, ue_ctx_t *ue_ctx
|
|
|
|
|
srslte::byte_buffer_t *esm_msg = m_pool->allocate();
|
|
|
|
|
LIBLTE_MME_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT_MSG_STRUCT act_bearer;
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info_hex(nas_msg->msg, nas_msg->N_bytes, "NAS Attach complete");
|
|
|
|
|
m_nas_log->info_hex(nas_msg->msg, nas_msg->N_bytes, "NAS Attach complete");
|
|
|
|
|
|
|
|
|
|
//Get NAS authentication response
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_attach_complete_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &attach_comp);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = liblte_mme_unpack_activate_default_eps_bearer_context_accept_msg( (LIBLTE_BYTE_MSG_STRUCT *) &attach_comp.esm_msg, &act_bearer);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking Activate EPS Bearer Context Accept Msg. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking Activate EPS Bearer Context Accept Msg. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx;
|
|
|
|
|
ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->console("Unpacked Attached Complete Message. IMSI %" PRIu64 "\n", emm_ctx->imsi);
|
|
|
|
|
m_s1ap_log->console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id);
|
|
|
|
|
m_nas_log->console("Unpacked Attached Complete Message. IMSI %" PRIu64 "\n", m_emm_ctx.imsi);
|
|
|
|
|
m_nas_log->console("Unpacked Activate Default EPS Bearer message. EPS Bearer id %d\n",act_bearer.eps_bearer_id);
|
|
|
|
|
if (act_bearer.eps_bearer_id < 5 || act_bearer.eps_bearer_id > 15) {
|
|
|
|
|
m_s1ap_log->error("EPS Bearer ID out of range\n");
|
|
|
|
|
m_nas_log->error("EPS Bearer ID out of range\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(emm_ctx->state == EMM_STATE_DEREGISTERED)
|
|
|
|
|
{
|
|
|
|
|
if (m_emm_ctx.state == EMM_STATE_DEREGISTERED) {
|
|
|
|
|
//Attach requested from attach request
|
|
|
|
|
m_mme_gtpc->send_modify_bearer_request(emm_ctx->imsi, &ecm_ctx->erabs_ctx[act_bearer.eps_bearer_id]);
|
|
|
|
|
m_gtpc->send_modify_bearer_request(m_emm_ctx.imsi, &m_esm_ctx[act_bearer.eps_bearer_id]);
|
|
|
|
|
//Send reply to eNB
|
|
|
|
|
m_s1ap_log->console("Packing EMM Information\n");
|
|
|
|
|
*reply_flag = pack_emm_information(ue_ctx, reply_msg);
|
|
|
|
|
m_s1ap_log->console("Sending EMM Information, bytes %d\n",reply_msg->N_bytes);
|
|
|
|
|
m_s1ap_log->info("Sending EMM Information\n");
|
|
|
|
|
m_nas_log->console("Packing EMM Information\n");
|
|
|
|
|
*reply_flag = pack_emm_information(reply_msg);
|
|
|
|
|
m_nas_log->console("Sending EMM Information, bytes %d\n",reply_msg->N_bytes);
|
|
|
|
|
m_nas_log->info("Sending EMM Information\n");
|
|
|
|
|
}
|
|
|
|
|
emm_ctx->state = EMM_STATE_REGISTERED;
|
|
|
|
|
m_emm_ctx.state = EMM_STATE_REGISTERED;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
nas::handle_esm_information_response(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
LIBLTE_MME_ESM_INFORMATION_RESPONSE_MSG_STRUCT esm_info_resp;
|
|
|
|
|
|
|
|
|
|
//Get NAS authentication response
|
|
|
|
|
LIBLTE_ERROR_ENUM err = srslte_mme_unpack_esm_information_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &esm_info_resp);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info("ESM Info: EPS bearer id %d\n",esm_info_resp.eps_bearer_id);
|
|
|
|
|
m_nas_log->info("ESM Info: EPS bearer id %d\n",esm_info_resp.eps_bearer_id);
|
|
|
|
|
if(esm_info_resp.apn_present){
|
|
|
|
|
m_s1ap_log->info("ESM Info: APN %s\n",esm_info_resp.apn.apn);
|
|
|
|
|
m_s1ap_log->console("ESM Info: APN %s\n",esm_info_resp.apn.apn);
|
|
|
|
|
m_nas_log->info("ESM Info: APN %s\n",esm_info_resp.apn.apn);
|
|
|
|
|
m_nas_log->console("ESM Info: APN %s\n",esm_info_resp.apn.apn);
|
|
|
|
|
}
|
|
|
|
|
if(esm_info_resp.protocol_cnfg_opts_present){
|
|
|
|
|
m_s1ap_log->info("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts);
|
|
|
|
|
m_s1ap_log->console("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts);
|
|
|
|
|
m_nas_log->info("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts);
|
|
|
|
|
m_nas_log->console("ESM Info: %d Protocol Configuration Options\n",esm_info_resp.protocol_cnfg_opts.N_opts);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Get subscriber info from HSS
|
|
|
|
|
uint8_t default_bearer=5;
|
|
|
|
|
m_hss->gen_update_loc_answer(ue_ctx->emm_ctx.imsi,&ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_s1ap_log->debug("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_s1ap_log->console("Getting subscription information -- QCI %d\n", ue_ctx->ecm_ctx.erabs_ctx[default_bearer].qci);
|
|
|
|
|
m_hss->gen_update_loc_answer(m_emm_ctx.imsi, &m_esm_ctx[default_bearer].qci);
|
|
|
|
|
m_nas_log->debug("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
|
|
|
|
|
m_nas_log->console("Getting subscription information -- QCI %d\n", m_esm_ctx[default_bearer].qci);
|
|
|
|
|
|
|
|
|
|
//FIXME The packging of GTP-C messages is not ready.
|
|
|
|
|
//This means that GTP-U tunnels are created with function calls, as opposed to GTP-C.
|
|
|
|
|
m_mme_gtpc->send_create_session_request(ue_ctx->emm_ctx.imsi);
|
|
|
|
|
m_gtpc->send_create_session_request(m_emm_ctx.imsi);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
uint8_t autn[16];
|
|
|
|
|
uint8_t rand[16];
|
|
|
|
@ -256,7 +247,7 @@ nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx,
|
|
|
|
|
LIBLTE_MME_ID_RESPONSE_MSG_STRUCT id_resp;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_identity_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &id_resp);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS identity response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking NAS identity response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -265,35 +256,31 @@ nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx,
|
|
|
|
|
imsi += id_resp.mobile_id.imsi[i]*std::pow(10,14-i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx;
|
|
|
|
|
ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx;
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info("ID response -- IMSI: %015lu\n", imsi);
|
|
|
|
|
m_s1ap_log->console("ID Response -- IMSI: %015lu\n", imsi);
|
|
|
|
|
m_nas_log->info("ID response -- IMSI: %015lu\n", imsi);
|
|
|
|
|
m_nas_log->console("ID Response -- IMSI: %015lu\n", imsi);
|
|
|
|
|
|
|
|
|
|
//Set UE's context IMSI
|
|
|
|
|
emm_ctx->imsi=imsi;
|
|
|
|
|
ecm_ctx->imsi = imsi;
|
|
|
|
|
//Set UE's IMSI
|
|
|
|
|
m_emm_ctx.imsi=imsi;
|
|
|
|
|
|
|
|
|
|
//Get Authentication Vectors from HSS
|
|
|
|
|
if (!m_hss->gen_auth_info_answer(imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres)) {
|
|
|
|
|
m_s1ap_log->console("User not found. IMSI %015lu\n",imsi);
|
|
|
|
|
m_s1ap_log->info("User not found. IMSI %015lu\n",imsi);
|
|
|
|
|
if (!m_hss->gen_auth_info_answer(imsi, m_sec_ctx.k_asme, autn, rand, m_sec_ctx.xres)) {
|
|
|
|
|
m_nas_log->console("User not found. IMSI %015lu\n",imsi);
|
|
|
|
|
m_nas_log->info("User not found. IMSI %015lu\n",imsi);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//Identity reponse from unknown GUTI atach. Assigning new eKSI.
|
|
|
|
|
emm_ctx->security_ctxt.eksi=0;
|
|
|
|
|
m_sec_ctx.eksi=0;
|
|
|
|
|
|
|
|
|
|
//Store UE context im IMSI map
|
|
|
|
|
m_s1ap->add_ue_ctx_to_imsi_map(ue_ctx);
|
|
|
|
|
m_s1ap->add_nas_ctx_to_imsi_map(this);
|
|
|
|
|
|
|
|
|
|
//Pack NAS Authentication Request in Downlink NAS Transport msg
|
|
|
|
|
pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, emm_ctx->security_ctxt.eksi, autn, rand);
|
|
|
|
|
pack_authentication_request(reply_msg);
|
|
|
|
|
|
|
|
|
|
//Send reply to eNB
|
|
|
|
|
*reply_flag = true;
|
|
|
|
|
m_s1ap_log->info("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_s1ap_log->console("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_nas_log->info("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_nas_log->console("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
//TODO Start T3460 Timer!
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
@ -301,11 +288,11 @@ nas::handle_identity_response(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->console("Warning: Tracking Area Update Request messages not handled yet.\n");
|
|
|
|
|
m_s1ap_log->warning("Warning: Tracking Area Update Request messages not handled yet.\n");
|
|
|
|
|
m_nas_log->console("Warning: Tracking Area Update Request messages not handled yet.\n");
|
|
|
|
|
m_nas_log->warning("Warning: Tracking Area Update Request messages not handled yet.\n");
|
|
|
|
|
//Setup initiating message
|
|
|
|
|
LIBLTE_S1AP_S1AP_PDU_STRUCT tx_pdu;
|
|
|
|
|
bzero(&tx_pdu, sizeof(LIBLTE_S1AP_S1AP_PDU_STRUCT));
|
|
|
|
@ -320,33 +307,16 @@ nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ctx_
|
|
|
|
|
//Setup Dw NAS structure
|
|
|
|
|
LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport;
|
|
|
|
|
dw_nas->ext=false;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ctx->ecm_ctx.mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ctx->ecm_ctx.enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = m_ecm_ctx.mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = m_ecm_ctx.enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->HandoverRestrictionList_present=false;
|
|
|
|
|
dw_nas->SubscriberProfileIDforRFP_present=false;
|
|
|
|
|
//m_s1ap_log->console("Tracking area accept to MME-UE S1AP Id %d\n", ue_ctx->mme_ue_s1ap_id);
|
|
|
|
|
//m_nas_log->console("Tracking area accept to MME-UE S1AP Id %d\n", ue_ctx->mme_ue_s1ap_id);
|
|
|
|
|
LIBLTE_MME_TRACKING_AREA_UPDATE_ACCEPT_MSG_STRUCT tau_acc;
|
|
|
|
|
|
|
|
|
|
//Get decimal MCC and MNC
|
|
|
|
|
uint32_t mcc = 0;
|
|
|
|
|
mcc += 0x000F & m_s1ap->m_s1ap_args.mcc;
|
|
|
|
|
mcc += 10*( (0x00F0 & m_s1ap->m_s1ap_args.mcc) >> 4);
|
|
|
|
|
mcc += 100*( (0x0F00 & m_s1ap->m_s1ap_args.mcc) >> 8);
|
|
|
|
|
|
|
|
|
|
uint32_t mnc = 0;
|
|
|
|
|
if( 0xFF00 == (m_s1ap->m_s1ap_args.mnc & 0xFF00 ))
|
|
|
|
|
{
|
|
|
|
|
//Two digit MNC
|
|
|
|
|
mnc += 0x000F & m_s1ap->m_s1ap_args.mnc;
|
|
|
|
|
mnc += 10*((0x00F0 & m_s1ap->m_s1ap_args.mnc) >> 4);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//Three digit MNC
|
|
|
|
|
mnc += 0x000F & m_s1ap->m_s1ap_args.mnc;
|
|
|
|
|
mnc += 10*((0x00F0 & m_s1ap->m_s1ap_args.mnc) >> 4);
|
|
|
|
|
mnc += 100*((0x0F00 & m_s1ap->m_s1ap_args.mnc) >> 8);
|
|
|
|
|
}
|
|
|
|
|
uint32_t mcc = m_s1ap->get_mcc();
|
|
|
|
|
uint32_t mnc = m_s1ap->get_mnc();
|
|
|
|
|
|
|
|
|
|
//T3412 Timer
|
|
|
|
|
tau_acc.t3412_present = true;
|
|
|
|
@ -358,10 +328,10 @@ nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ctx_
|
|
|
|
|
tau_acc.guti.type_of_id = 6; //110 -> GUTI
|
|
|
|
|
tau_acc.guti.guti.mcc = mcc;
|
|
|
|
|
tau_acc.guti.guti.mnc = mnc;
|
|
|
|
|
tau_acc.guti.guti.mme_group_id = m_s1ap->m_s1ap_args.mme_group;
|
|
|
|
|
tau_acc.guti.guti.mme_code = m_s1ap->m_s1ap_args.mme_code;
|
|
|
|
|
tau_acc.guti.guti.mme_group_id = m_s1ap->get_mme_group();
|
|
|
|
|
tau_acc.guti.guti.mme_code = m_s1ap->get_mme_code();
|
|
|
|
|
tau_acc.guti.guti.m_tmsi = 0xF000;
|
|
|
|
|
m_s1ap_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n",
|
|
|
|
|
m_nas_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n",
|
|
|
|
|
tau_acc.guti.guti.mcc,
|
|
|
|
|
tau_acc.guti.guti.mnc,
|
|
|
|
|
tau_acc.guti.guti.mme_group_id,
|
|
|
|
@ -382,7 +352,7 @@ nas::handle_tracking_area_update_request(srslte::byte_buffer_t *nas_msg, ue_ctx_
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_ctx, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
nas::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, srslte::byte_buffer_t *reply_msg, bool *reply_flag)
|
|
|
|
|
{
|
|
|
|
|
uint8_t autn[16];
|
|
|
|
|
uint8_t rand[16];
|
|
|
|
@ -391,52 +361,48 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_
|
|
|
|
|
LIBLTE_MME_AUTHENTICATION_FAILURE_MSG_STRUCT auth_fail;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_failure_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &auth_fail);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication failure. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
m_nas_log->error("Error unpacking NAS authentication failure. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ue_emm_ctx_t *emm_ctx = &ue_ctx->emm_ctx;
|
|
|
|
|
ue_ecm_ctx_t *ecm_ctx = &ue_ctx->ecm_ctx;
|
|
|
|
|
|
|
|
|
|
switch(auth_fail.emm_cause){
|
|
|
|
|
switch (auth_fail.emm_cause) {
|
|
|
|
|
case 20:
|
|
|
|
|
m_s1ap_log->console("MAC code failure\n");
|
|
|
|
|
m_s1ap_log->info("MAC code failure\n");
|
|
|
|
|
m_nas_log->console("MAC code failure\n");
|
|
|
|
|
m_nas_log->info("MAC code failure\n");
|
|
|
|
|
break;
|
|
|
|
|
case 26:
|
|
|
|
|
m_s1ap_log->console("Non-EPS authentication unacceptable\n");
|
|
|
|
|
m_s1ap_log->info("Non-EPS authentication unacceptable\n");
|
|
|
|
|
m_nas_log->console("Non-EPS authentication unacceptable\n");
|
|
|
|
|
m_nas_log->info("Non-EPS authentication unacceptable\n");
|
|
|
|
|
break;
|
|
|
|
|
case 21:
|
|
|
|
|
m_s1ap_log->console("Authentication Failure -- Synchronization Failure\n");
|
|
|
|
|
m_s1ap_log->info("Authentication Failure -- Synchronization Failure\n");
|
|
|
|
|
m_nas_log->console("Authentication Failure -- Synchronization Failure\n");
|
|
|
|
|
m_nas_log->info("Authentication Failure -- Synchronization Failure\n");
|
|
|
|
|
if(auth_fail.auth_fail_param_present == false){
|
|
|
|
|
m_s1ap_log->error("Missing fail parameter\n");
|
|
|
|
|
m_nas_log->error("Missing fail parameter\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!m_hss->resync_sqn(emm_ctx->imsi, auth_fail.auth_fail_param))
|
|
|
|
|
{
|
|
|
|
|
m_s1ap_log->console("Resynchronization failed. IMSI %015lu\n", emm_ctx->imsi);
|
|
|
|
|
m_s1ap_log->info("Resynchronization failed. IMSI %015lu\n", emm_ctx->imsi);
|
|
|
|
|
if (!m_hss->resync_sqn(m_emm_ctx.imsi, auth_fail.auth_fail_param)) {
|
|
|
|
|
m_nas_log->console("Resynchronization failed. IMSI %015lu\n", m_emm_ctx.imsi);
|
|
|
|
|
m_nas_log->info("Resynchronization failed. IMSI %015lu\n", m_emm_ctx.imsi);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//Get Authentication Vectors from HSS
|
|
|
|
|
if(!m_hss->gen_auth_info_answer(emm_ctx->imsi, emm_ctx->security_ctxt.k_asme, autn, rand, emm_ctx->security_ctxt.xres))
|
|
|
|
|
{
|
|
|
|
|
m_s1ap_log->console("User not found. IMSI %015lu\n", emm_ctx->imsi);
|
|
|
|
|
m_s1ap_log->info("User not found. IMSI %015lu\n", emm_ctx->imsi);
|
|
|
|
|
if (!m_hss->gen_auth_info_answer(m_emm_ctx.imsi, m_sec_ctx.k_asme, autn, rand, m_sec_ctx.xres)) {
|
|
|
|
|
m_nas_log->console("User not found. IMSI %015lu\n", m_emm_ctx.imsi);
|
|
|
|
|
m_nas_log->info("User not found. IMSI %015lu\n", m_emm_ctx.imsi);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Making sure eKSI is different from previous eKSI.
|
|
|
|
|
emm_ctx->security_ctxt.eksi = (emm_ctx->security_ctxt.eksi+1)%6;
|
|
|
|
|
m_sec_ctx.eksi = (m_sec_ctx.eksi+1)%6;
|
|
|
|
|
|
|
|
|
|
//Pack NAS Authentication Request in Downlink NAS Transport msg
|
|
|
|
|
pack_authentication_request(reply_msg, ecm_ctx->enb_ue_s1ap_id, ecm_ctx->mme_ue_s1ap_id, emm_ctx->security_ctxt.eksi, autn, rand);
|
|
|
|
|
pack_authentication_request(reply_msg);
|
|
|
|
|
|
|
|
|
|
//Send reply to eNB
|
|
|
|
|
*reply_flag = true;
|
|
|
|
|
m_s1ap_log->info("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_s1ap_log->console("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_nas_log->info("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
m_nas_log->console("Downlink NAS: Sent Authentication Request\n");
|
|
|
|
|
//TODO Start T3460 Timer!
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
@ -446,7 +412,7 @@ nas::handle_authentication_failure(srslte::byte_buffer_t *nas_msg, ue_ctx_t* ue_
|
|
|
|
|
|
|
|
|
|
/*Packing/Unpacking helper functions*/
|
|
|
|
|
bool
|
|
|
|
|
nas::pack_authentication_request(srslte::byte_buffer_t *reply_msg, uint8_t *autn, uint8_t *rand)
|
|
|
|
|
nas::pack_authentication_request(srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
{
|
|
|
|
|
srslte::byte_buffer_t *nas_buffer = m_pool->allocate();
|
|
|
|
|
|
|
|
|
@ -464,22 +430,22 @@ nas::pack_authentication_request(srslte::byte_buffer_t *reply_msg, uint8_t *autn
|
|
|
|
|
//Setup Dw NAS structure
|
|
|
|
|
LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport;
|
|
|
|
|
dw_nas->ext=false;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = next_mme_ue_s1ap_id;//FIXME Change name
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = m_ecm_ctx.mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = m_ecm_ctx.enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->HandoverRestrictionList_present=false;
|
|
|
|
|
dw_nas->SubscriberProfileIDforRFP_present=false;
|
|
|
|
|
|
|
|
|
|
//Pack NAS PDU
|
|
|
|
|
LIBLTE_MME_AUTHENTICATION_REQUEST_MSG_STRUCT auth_req;
|
|
|
|
|
memcpy(auth_req.autn , autn, 16);
|
|
|
|
|
memcpy(auth_req.rand, rand, 16);
|
|
|
|
|
memcpy(auth_req.autn , m_sec_ctx.autn, 16);
|
|
|
|
|
memcpy(auth_req.rand, m_sec_ctx.rand, 16);
|
|
|
|
|
auth_req.nas_ksi.tsc_flag=LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE;
|
|
|
|
|
auth_req.nas_ksi.nas_ksi = eksi;
|
|
|
|
|
auth_req.nas_ksi.nas_ksi = m_sec_ctx.eksi;
|
|
|
|
|
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_request_msg(&auth_req, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Authentication Request\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Authentication Request\n");
|
|
|
|
|
m_nas_log->error("Error packing Authentication Request\n");
|
|
|
|
|
m_nas_log->console("Error packing Authentication Request\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -490,8 +456,8 @@ nas::pack_authentication_request(srslte::byte_buffer_t *reply_msg, uint8_t *autn
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Authentication Request\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Authentication Request\n");
|
|
|
|
|
m_nas_log->error("Error packing Authentication Request\n");
|
|
|
|
|
m_nas_log->console("Error packing Authentication Request\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -527,8 +493,8 @@ nas::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, uint32_t enb_u
|
|
|
|
|
LIBLTE_MME_AUTHENTICATION_REJECT_MSG_STRUCT auth_rej;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_authentication_reject_msg(&auth_rej, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Authentication Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Authentication Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Authentication Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Authentication Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -539,8 +505,8 @@ nas::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, uint32_t enb_u
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -549,35 +515,7 @@ nas::pack_authentication_reject(srslte::byte_buffer_t *reply_msg, uint32_t enb_u
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::unpack_authentication_response( LIBLTE_S1AP_MESSAGE_UPLINKNASTRANSPORT_STRUCT *ul_xport,
|
|
|
|
|
LIBLTE_MME_AUTHENTICATION_RESPONSE_MSG_STRUCT *auth_resp )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/*Get NAS Authentiation Response Message*/
|
|
|
|
|
uint8_t pd, msg_type;
|
|
|
|
|
srslte::byte_buffer_t *nas_msg = m_pool->allocate();
|
|
|
|
|
|
|
|
|
|
memcpy(nas_msg->msg, &ul_xport->NAS_PDU.buffer, ul_xport->NAS_PDU.n_octets);
|
|
|
|
|
nas_msg->N_bytes = ul_xport->NAS_PDU.n_octets;
|
|
|
|
|
liblte_mme_parse_msg_header((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, &pd, &msg_type);
|
|
|
|
|
|
|
|
|
|
if(msg_type!=LIBLTE_MME_MSG_TYPE_AUTHENTICATION_RESPONSE){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication response\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_unpack_authentication_response_msg((LIBLTE_BYTE_MSG_STRUCT *) nas_msg, auth_resp);
|
|
|
|
|
if(err != LIBLTE_SUCCESS){
|
|
|
|
|
m_s1ap_log->error("Error unpacking NAS authentication response. Error: %s\n", liblte_error_text[err]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pool->deallocate(nas_msg);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx)
|
|
|
|
|
nas::pack_security_mode_command(srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
{
|
|
|
|
|
srslte::byte_buffer_t *nas_buffer = m_pool->allocate();
|
|
|
|
|
|
|
|
|
@ -595,8 +533,8 @@ nas::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *
|
|
|
|
|
//Setup Dw NAS structure
|
|
|
|
|
LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport;
|
|
|
|
|
dw_nas->ext=false;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = m_ecm_ctx.mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = m_ecm_ctx.enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->HandoverRestrictionList_present=false;
|
|
|
|
|
dw_nas->SubscriberProfileIDforRFP_present=false;
|
|
|
|
|
|
|
|
|
@ -607,51 +545,54 @@ nas::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *
|
|
|
|
|
sm_cmd.selected_nas_sec_algs.type_of_eia = LIBLTE_MME_TYPE_OF_INTEGRITY_ALGORITHM_128_EIA1;
|
|
|
|
|
|
|
|
|
|
sm_cmd.nas_ksi.tsc_flag=LIBLTE_MME_TYPE_OF_SECURITY_CONTEXT_FLAG_NATIVE;
|
|
|
|
|
sm_cmd.nas_ksi.nas_ksi=ue_emm_ctx->security_ctxt.eksi;
|
|
|
|
|
sm_cmd.nas_ksi.nas_ksi=m_sec_ctx.eksi;
|
|
|
|
|
|
|
|
|
|
//Replay UE security cap
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.eea,ue_emm_ctx->security_ctxt.ue_network_cap.eea,8*sizeof(bool));
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.eia,ue_emm_ctx->security_ctxt.ue_network_cap.eia,8*sizeof(bool));
|
|
|
|
|
sm_cmd.ue_security_cap.uea_present = ue_emm_ctx->security_ctxt.ue_network_cap.uea_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.uea,ue_emm_ctx->security_ctxt.ue_network_cap.uea,8*sizeof(bool));
|
|
|
|
|
sm_cmd.ue_security_cap.uia_present = ue_emm_ctx->security_ctxt.ue_network_cap.uia_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.uia,ue_emm_ctx->security_ctxt.ue_network_cap.uia,8*sizeof(bool));
|
|
|
|
|
sm_cmd.ue_security_cap.gea_present = ue_emm_ctx->security_ctxt.ms_network_cap_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.gea,ue_emm_ctx->security_ctxt.ms_network_cap.gea,8*sizeof(bool));
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.eea,m_sec_ctx.ue_network_cap.eea,8*sizeof(bool));
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.eia,m_sec_ctx.ue_network_cap.eia,8*sizeof(bool));
|
|
|
|
|
|
|
|
|
|
sm_cmd.ue_security_cap.uea_present = m_sec_ctx.ue_network_cap.uea_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.uea,m_sec_ctx.ue_network_cap.uea,8*sizeof(bool));
|
|
|
|
|
|
|
|
|
|
sm_cmd.ue_security_cap.uia_present = m_sec_ctx.ue_network_cap.uia_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.uia,m_sec_ctx.ue_network_cap.uia,8*sizeof(bool));
|
|
|
|
|
|
|
|
|
|
sm_cmd.ue_security_cap.gea_present = m_sec_ctx.ms_network_cap_present;
|
|
|
|
|
memcpy(sm_cmd.ue_security_cap.gea,m_sec_ctx.ms_network_cap.gea,8*sizeof(bool));
|
|
|
|
|
|
|
|
|
|
sm_cmd.imeisv_req_present=false;
|
|
|
|
|
sm_cmd.nonce_ue_present=false;
|
|
|
|
|
sm_cmd.nonce_mme_present=false;
|
|
|
|
|
|
|
|
|
|
uint8_t sec_hdr_type=3;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg(&sm_cmd,sec_hdr_type, ue_emm_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_security_mode_command_msg(&sm_cmd,sec_hdr_type, m_sec_ctx.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if(err != LIBLTE_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
m_s1ap_log->console("Error packing Authentication Request\n");
|
|
|
|
|
m_nas_log->console("Error packing Authentication Request\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Generate EPS security context
|
|
|
|
|
uint8_t mac[4];
|
|
|
|
|
srslte::security_generate_k_nas( ue_emm_ctx->security_ctxt.k_asme,
|
|
|
|
|
srslte::security_generate_k_nas( m_sec_ctx.k_asme,
|
|
|
|
|
srslte::CIPHERING_ALGORITHM_ID_EEA0,
|
|
|
|
|
srslte::INTEGRITY_ALGORITHM_ID_128_EIA1,
|
|
|
|
|
ue_emm_ctx->security_ctxt.k_nas_enc,
|
|
|
|
|
ue_emm_ctx->security_ctxt.k_nas_int
|
|
|
|
|
m_sec_ctx.k_nas_enc,
|
|
|
|
|
m_sec_ctx.k_nas_int
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_nas_enc, 32, "Key NAS Encryption (k_nas_enc)\n");
|
|
|
|
|
m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_nas_int, 32, "Key NAS Integrity (k_nas_int)\n");
|
|
|
|
|
m_nas_log->info_hex(m_sec_ctx.k_nas_enc, 32, "Key NAS Encryption (k_nas_enc)\n");
|
|
|
|
|
m_nas_log->info_hex(m_sec_ctx.k_nas_int, 32, "Key NAS Integrity (k_nas_int)\n");
|
|
|
|
|
|
|
|
|
|
uint8_t key_enb[32];
|
|
|
|
|
srslte::security_generate_k_enb(ue_emm_ctx->security_ctxt.k_asme, ue_emm_ctx->security_ctxt.ul_nas_count, ue_emm_ctx->security_ctxt.k_enb);
|
|
|
|
|
m_s1ap_log->info("Generating KeNB with UL NAS COUNT: %d\n", ue_emm_ctx->security_ctxt.ul_nas_count);
|
|
|
|
|
m_s1ap_log->console("Generating KeNB with UL NAS COUNT: %d\n", ue_emm_ctx->security_ctxt.ul_nas_count);
|
|
|
|
|
m_s1ap_log->info_hex(ue_emm_ctx->security_ctxt.k_enb, 32, "Key eNodeB (k_enb)\n");
|
|
|
|
|
srslte::security_generate_k_enb(m_sec_ctx.k_asme, m_sec_ctx.ul_nas_count, m_sec_ctx.k_enb);
|
|
|
|
|
m_nas_log->info("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count);
|
|
|
|
|
m_nas_log->console("Generating KeNB with UL NAS COUNT: %d\n", m_sec_ctx.ul_nas_count);
|
|
|
|
|
m_nas_log->info_hex(m_sec_ctx.k_enb, 32, "Key eNodeB (k_enb)\n");
|
|
|
|
|
//Generate MAC for integrity protection
|
|
|
|
|
//FIXME Write wrapper to support EIA1, EIA2, etc.
|
|
|
|
|
srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16],
|
|
|
|
|
ue_emm_ctx->security_ctxt.dl_nas_count,
|
|
|
|
|
srslte::security_128_eia1 (&m_sec_ctx.k_nas_int[16],
|
|
|
|
|
m_sec_ctx.dl_nas_count,
|
|
|
|
|
0,
|
|
|
|
|
SECURITY_DIRECTION_DOWNLINK,
|
|
|
|
|
&nas_buffer->msg[5],
|
|
|
|
@ -666,18 +607,17 @@ nas::pack_security_mode_command(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *
|
|
|
|
|
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if(err != LIBLTE_SUCCESS)
|
|
|
|
|
{
|
|
|
|
|
m_s1ap_log->console("Error packing Authentication Request\n");
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_nas_log->console("Error packing Authentication Request\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
m_s1ap_log->debug_hex(reply_msg->msg, reply_msg->N_bytes, "Security Mode Command: ");
|
|
|
|
|
m_nas_log->debug_hex(reply_msg->msg, reply_msg->N_bytes, "Security Mode Command: ");
|
|
|
|
|
m_pool->deallocate(nas_buffer);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
nas::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t *ue_emm_ctx, ue_ecm_ctx_t *ue_ecm_ctx)
|
|
|
|
|
nas::pack_esm_information_request(srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
{
|
|
|
|
|
srslte::byte_buffer_t *nas_buffer = m_pool->allocate();
|
|
|
|
|
|
|
|
|
@ -695,28 +635,28 @@ nas::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t
|
|
|
|
|
//Setup Dw NAS structure
|
|
|
|
|
LIBLTE_S1AP_MESSAGE_DOWNLINKNASTRANSPORT_STRUCT *dw_nas = &init->choice.DownlinkNASTransport;
|
|
|
|
|
dw_nas->ext=false;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = ue_ecm_ctx->mme_ue_s1ap_id;//FIXME Change name
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = ue_ecm_ctx->enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->MME_UE_S1AP_ID.MME_UE_S1AP_ID = m_ecm_ctx.mme_ue_s1ap_id;
|
|
|
|
|
dw_nas->eNB_UE_S1AP_ID.ENB_UE_S1AP_ID = m_ecm_ctx.enb_ue_s1ap_id;
|
|
|
|
|
dw_nas->HandoverRestrictionList_present=false;
|
|
|
|
|
dw_nas->SubscriberProfileIDforRFP_present=false;
|
|
|
|
|
|
|
|
|
|
LIBLTE_MME_ESM_INFORMATION_REQUEST_MSG_STRUCT esm_info_req;
|
|
|
|
|
esm_info_req.eps_bearer_id = 0;
|
|
|
|
|
esm_info_req.proc_transaction_id = ue_emm_ctx->procedure_transaction_id;
|
|
|
|
|
esm_info_req.proc_transaction_id = m_emm_ctx.procedure_transaction_id;
|
|
|
|
|
|
|
|
|
|
uint8_t sec_hdr_type = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED;
|
|
|
|
|
|
|
|
|
|
ue_emm_ctx->security_ctxt.dl_nas_count++;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg(&esm_info_req, sec_hdr_type,ue_emm_ctx->security_ctxt.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
m_sec_ctx.dl_nas_count++;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = srslte_mme_pack_esm_information_request_msg(&esm_info_req, sec_hdr_type, m_sec_ctx.dl_nas_count,(LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing ESM information request\n");
|
|
|
|
|
m_s1ap_log->console("Error packing ESM information request\n");
|
|
|
|
|
m_nas_log->error("Error packing ESM information request\n");
|
|
|
|
|
m_nas_log->console("Error packing ESM information request\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t mac[4];
|
|
|
|
|
srslte::security_128_eia1 (&ue_emm_ctx->security_ctxt.k_nas_int[16],
|
|
|
|
|
ue_emm_ctx->security_ctxt.dl_nas_count,
|
|
|
|
|
srslte::security_128_eia1 (&m_sec_ctx.k_nas_int[16],
|
|
|
|
|
m_sec_ctx.dl_nas_count,
|
|
|
|
|
0,
|
|
|
|
|
SECURITY_DIRECTION_DOWNLINK,
|
|
|
|
|
&nas_buffer->msg[5],
|
|
|
|
@ -733,8 +673,8 @@ nas::pack_esm_information_request(srslte::byte_buffer_t *reply_msg, ue_emm_ctx_t
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if(err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -787,7 +727,7 @@ nas::pack_attach_accept(LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctx
|
|
|
|
|
attach_accept.guti.guti.mme_group_id = m_s1ap->m_s1ap_args.mme_group;
|
|
|
|
|
attach_accept.guti.guti.mme_code = m_s1ap->m_s1ap_args.mme_code;
|
|
|
|
|
attach_accept.guti.guti.m_tmsi = m_s1ap->allocate_m_tmsi(ue_emm_ctx->imsi);
|
|
|
|
|
m_s1ap_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n",
|
|
|
|
|
m_nas_log->debug("Allocated GUTI: MCC %d, MNC %d, MME Group Id %d, MME Code 0x%x, M-TMSI 0x%x\n",
|
|
|
|
|
attach_accept.guti.guti.mcc,
|
|
|
|
|
attach_accept.guti.guti.mnc,
|
|
|
|
|
attach_accept.guti.guti.mme_group_id,
|
|
|
|
@ -867,7 +807,7 @@ nas::pack_attach_accept(LIBLTE_S1AP_E_RABTOBESETUPITEMCTXTSUREQ_STRUCT *erab_ctx
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
memcpy(&nas_buffer->msg[1],mac,4);
|
|
|
|
|
m_s1ap_log->info("Packed Attach Complete\n");
|
|
|
|
|
m_nas_log->info("Packed Attach Complete\n");
|
|
|
|
|
|
|
|
|
|
//Add nas message to context setup request
|
|
|
|
|
erab_ctxt->nAS_PDU_present = true;
|
|
|
|
@ -905,8 +845,8 @@ nas::pack_identity_request(srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
id_req.id_type = LIBLTE_MME_EPS_MOBILE_ID_TYPE_IMSI;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_identity_request_msg(&id_req, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Identity Request\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Identity REquest\n");
|
|
|
|
|
m_nas_log->error("Error packing Identity Request\n");
|
|
|
|
|
m_nas_log->console("Error packing Identity REquest\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -917,8 +857,8 @@ nas::pack_identity_request(srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Dw NAS Transport: Authentication Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Downlink NAS Transport: Authentication Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -968,8 +908,8 @@ nas::pack_emm_information( ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
emm_ctx->security_ctxt.dl_nas_count++;
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_emm_information_msg(&emm_info, sec_hdr_type, emm_ctx->security_ctxt.dl_nas_count, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing EMM Information\n");
|
|
|
|
|
m_s1ap_log->console("Error packing EMM Information\n");
|
|
|
|
|
m_nas_log->error("Error packing EMM Information\n");
|
|
|
|
|
m_nas_log->console("Error packing EMM Information\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -991,12 +931,12 @@ nas::pack_emm_information( ue_ctx_t *ue_ctx, srslte::byte_buffer_t *reply_msg)
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Dw NAS Transport: EMM Info\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Downlink NAS Transport: EMM Info\n");
|
|
|
|
|
m_nas_log->error("Error packing Dw NAS Transport: EMM Info\n");
|
|
|
|
|
m_nas_log->console("Error packing Downlink NAS Transport: EMM Info\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_s1ap_log->info("Packed UE EMM information\n");
|
|
|
|
|
m_nas_log->info("Packed UE EMM information\n");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1033,8 +973,8 @@ nas::pack_service_reject(srslte::byte_buffer_t *reply_msg, uint8_t emm_cause, ui
|
|
|
|
|
|
|
|
|
|
LIBLTE_ERROR_ENUM err = liblte_mme_pack_service_reject_msg(&service_rej, LIBLTE_MME_SECURITY_HDR_TYPE_PLAIN_NAS, 0, (LIBLTE_BYTE_MSG_STRUCT *) nas_buffer);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Service Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Service Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Service Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Service Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1045,8 +985,8 @@ nas::pack_service_reject(srslte::byte_buffer_t *reply_msg, uint8_t emm_cause, ui
|
|
|
|
|
//Pack Downlink NAS Transport Message
|
|
|
|
|
err = liblte_s1ap_pack_s1ap_pdu(&tx_pdu, (LIBLTE_BYTE_MSG_STRUCT *) reply_msg);
|
|
|
|
|
if (err != LIBLTE_SUCCESS) {
|
|
|
|
|
m_s1ap_log->error("Error packing Dw NAS Transport: Service Reject\n");
|
|
|
|
|
m_s1ap_log->console("Error packing Downlink NAS Transport: Service Reject\n");
|
|
|
|
|
m_nas_log->error("Error packing Dw NAS Transport: Service Reject\n");
|
|
|
|
|
m_nas_log->console("Error packing Downlink NAS Transport: Service Reject\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -1076,7 +1016,7 @@ nas::short_integrity_check(srslte::byte_buffer_t *pdu)
|
|
|
|
|
// Check if expected mac equals the sent mac
|
|
|
|
|
for(i=0; i<2; i++){
|
|
|
|
|
if(exp_mac[i+2] != mac[i]){
|
|
|
|
|
m_s1ap_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
|
m_nas_log->warning("Short integrity check failure. Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
|
"Received: count=%d, [%02x %02x]\n",
|
|
|
|
|
m_sec_ctx->ul_nas_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3],
|
|
|
|
|
pdu->msg[1] & 0x1F, mac[0], mac[1]);
|
|
|
|
@ -1107,14 +1047,14 @@ nas::integrity_check(srslte::byte_buffer_t *pdu)
|
|
|
|
|
// Check if expected mac equals the sent mac
|
|
|
|
|
for(i=0; i<4; i++){
|
|
|
|
|
if(exp_mac[i] != mac[i]){
|
|
|
|
|
m_s1ap_log->warning("Integrity check failure. UL Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
|
m_nas_log->warning("Integrity check failure. UL Local: count=%d, [%02x %02x %02x %02x], "
|
|
|
|
|
"Received: UL count=%d, [%02x %02x %02x %02x]\n",
|
|
|
|
|
emm_ctx->security_ctxt.ul_nas_count, exp_mac[0], exp_mac[1], exp_mac[2], exp_mac[3],
|
|
|
|
|
pdu->msg[5], mac[0], mac[1], mac[2], mac[3]);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
m_s1ap_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
|
|
|
|
|
m_nas_log->info("Integrity check ok. Local: count=%d, Received: count=%d\n",
|
|
|
|
|
emm_ctx->security_ctxt.ul_nas_count, pdu->msg[5]);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|