Commit 6f5c0332 authored by Lionel Gauthier's avatar Lionel Gauthier

For Sync only, still problem with NAS COUNT (TODO) and MAC-I (check on real PFT SIM)

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5311 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 55d05b6f
...@@ -26,6 +26,9 @@ typedef struct mme_app_connection_establishment_cnf_s { ...@@ -26,6 +26,9 @@ typedef struct mme_app_connection_establishment_cnf_s {
pre_emp_capability_t bearer_qos_pre_emp_capability; pre_emp_capability_t bearer_qos_pre_emp_capability;
ambr_t ambr; ambr_t ambr;
/* Key eNB */
uint8_t keNB[32];
nas_conn_est_cnf_t nas_conn_est_cnf; nas_conn_est_cnf_t nas_conn_est_cnf;
} mme_app_connection_establishment_cnf_t; } mme_app_connection_establishment_cnf_t;
......
...@@ -170,7 +170,7 @@ typedef struct nas_pdn_connectivity_rsp_s { ...@@ -170,7 +170,7 @@ typedef struct nas_pdn_connectivity_rsp_s {
uint32_t mme_ue_s1ap_id; uint32_t mme_ue_s1ap_id;
/* Key eNB */ /* Key eNB */
uint8_t keNB[32]; //uint8_t keNB[32];
ambr_t ambr; ambr_t ambr;
ambr_t apn_ambr; ambr_t apn_ambr;
......
...@@ -289,6 +289,7 @@ mme_app_handle_conn_est_cnf( ...@@ -289,6 +289,7 @@ mme_app_handle_conn_est_cnf(
mme_app_connection_establishment_cnf_t *establishment_cnf_p = NULL; mme_app_connection_establishment_cnf_t *establishment_cnf_p = NULL;
bearer_context_t *current_bearer_p = NULL; bearer_context_t *current_bearer_p = NULL;
ebi_t bearer_id = 0; ebi_t bearer_id = 0;
uint8_t *keNB = NULL;
MME_APP_DEBUG("Received NAS_CONNECTION_ESTABLISHMENT_CNF from NAS\n"); MME_APP_DEBUG("Received NAS_CONNECTION_ESTABLISHMENT_CNF from NAS\n");
...@@ -332,6 +333,11 @@ mme_app_handle_conn_est_cnf( ...@@ -332,6 +333,11 @@ mme_app_handle_conn_est_cnf(
establishment_cnf_p->bearer_qos_pre_emp_capability = current_bearer_p->pre_emp_capability; establishment_cnf_p->bearer_qos_pre_emp_capability = current_bearer_p->pre_emp_capability;
establishment_cnf_p->ambr = ue_context_p->used_ambr; establishment_cnf_p->ambr = ue_context_p->used_ambr;
MME_APP_DEBUG("Derive keNB with UL NAS COUNT %x\n", nas_conn_est_cnf_pP->ul_nas_count);
derive_keNB(ue_context_p->vector_in_use->kasme, nas_conn_est_cnf_pP->ul_nas_count, &keNB); //156
memcpy(establishment_cnf_p->keNB, keNB, 32);
free(keNB);
itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p); itti_send_msg_to_task(TASK_S1AP, INSTANCE_DEFAULT, message_p);
} }
...@@ -471,17 +477,18 @@ mme_app_handle_create_sess_resp( ...@@ -471,17 +477,18 @@ mme_app_handle_create_sess_resp(
mme_app_dump_ue_contexts(&mme_app_desc.mme_ue_contexts); mme_app_dump_ue_contexts(&mme_app_desc.mme_ue_contexts);
{ {
uint8_t *keNB = NULL; //uint8_t *keNB = NULL;
message_p = itti_alloc_new_message(TASK_MME_APP, NAS_PDN_CONNECTIVITY_RSP); message_p = itti_alloc_new_message(TASK_MME_APP, NAS_PDN_CONNECTIVITY_RSP);
memset((void*)&message_p->ittiMsg.nas_pdn_connectivity_rsp, memset((void*)&message_p->ittiMsg.nas_pdn_connectivity_rsp,
0, 0,
sizeof(nas_pdn_connectivity_rsp_t)); sizeof(nas_pdn_connectivity_rsp_t));
derive_keNB(ue_context_p->vector_in_use->kasme, 156, &keNB); // moved to NAS_CONNECTION_ESTABLISHMENT_CONF, keNB not handled in NAS MME
memcpy(NAS_PDN_CONNECTIVITY_RSP(message_p).keNB, keNB, 32); //derive_keNB(ue_context_p->vector_in_use->kasme, 156, &keNB);
//memcpy(NAS_PDN_CONNECTIVITY_RSP(message_p).keNB, keNB, 32);
free(keNB); //free(keNB);
NAS_PDN_CONNECTIVITY_RSP(message_p).pti = ue_context_p->pending_pdn_connectivity_req_pti; // NAS internal ref NAS_PDN_CONNECTIVITY_RSP(message_p).pti = ue_context_p->pending_pdn_connectivity_req_pti; // NAS internal ref
NAS_PDN_CONNECTIVITY_RSP(message_p).ue_id = ue_context_p->pending_pdn_connectivity_req_ue_id; // NAS internal ref NAS_PDN_CONNECTIVITY_RSP(message_p).ue_id = ue_context_p->pending_pdn_connectivity_req_ue_id; // NAS internal ref
......
...@@ -23,6 +23,9 @@ Description Defines the layer 3 messages supported by the NAS sublayer ...@@ -23,6 +23,9 @@ Description Defines the layer 3 messages supported by the NAS sublayer
#include "commonDef.h" #include "commonDef.h"
#include "emm_msg.h" #include "emm_msg.h"
#if defined(EPC_BUILD)
#include "emmData.h"
#endif
#include "esm_msg.h" #include "esm_msg.h"
/****************************************************************************/ /****************************************************************************/
...@@ -78,14 +81,29 @@ typedef union { ...@@ -78,14 +81,29 @@ typedef union {
/****************** E X P O R T E D F U N C T I O N S ******************/ /****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/ /****************************************************************************/
int nas_message_encrypt(const char *inbuf, char *outbuf, int nas_message_encrypt(
const nas_message_security_header_t *header, int length); const char *inbuf,
char *outbuf,
int nas_message_decrypt(const char *inbuf, char *outbuf, const nas_message_security_header_t *header,
nas_message_security_header_t *header, int length); int length,
void *security);
int nas_message_decode(const char * const buffer, nas_message_t *msg, int length);
int nas_message_decrypt(const char *inbuf,
int nas_message_encode(char *buffer, const nas_message_t * const msg, int length); char *outbuf,
nas_message_security_header_t *header,
int length,
void *security);
int nas_message_decode(
const char * const buffer,
nas_message_t *msg,
int length,
void *security);
int nas_message_encode(
char *buffer,
const nas_message_t * const msg,
int length,
void *security);
#endif /* __NAS_MESSAGE_H__*/ #endif /* __NAS_MESSAGE_H__*/
...@@ -45,6 +45,8 @@ Description Defines the attach related EMM procedure executed by the ...@@ -45,6 +45,8 @@ Description Defines the attach related EMM procedure executed by the
#include "esm_sap.h" #include "esm_sap.h"
#include "emm_cause.h" #include "emm_cause.h"
#include "NasSecurityAlgorithms.h"
#ifdef NAS_MME #ifdef NAS_MME
#include "mme_api.h" #include "mme_api.h"
# if defined(EPC_BUILD) # if defined(EPC_BUILD)
...@@ -1133,6 +1135,17 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, ...@@ -1133,6 +1135,17 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
#if defined(EPC_BUILD) #if defined(EPC_BUILD)
emm_data_context_add(&_emm_data, *(emm_ctx)); emm_data_context_add(&_emm_data, *(emm_ctx));
#endif #endif
#warning "TRICK TO SET TAC, BUT LOOK AT SPEC"
if (tai){
LOG_TRACE(WARNING,
"EMM-PROC - Set tac %u in context %u ",
tai->tac);
(*emm_ctx)->tac = tai->tac;
} else {
LOG_TRACE(WARNING,
"EMM-PROC - Could not set tac in context, cause tai is NULL ");
}
} }
/* Update the EMM context with the current attach procedure parameters */ /* Update the EMM context with the current attach procedure parameters */
...@@ -2040,6 +2053,8 @@ static int _emm_attach_security(void *args) ...@@ -2040,6 +2053,8 @@ static int _emm_attach_security(void *args)
if (emm_ctx->security) { if (emm_ctx->security) {
memset(emm_ctx->security, 0, sizeof(emm_security_context_t)); memset(emm_ctx->security, 0, sizeof(emm_security_context_t));
emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE; emm_ctx->security->type = EMM_KSI_NOT_AVAILABLE;
emm_ctx->security->selected_algorithms.encryption = NAS_SECURITY_ALGORITHMS_EEA0;
emm_ctx->security->selected_algorithms.integrity = NAS_SECURITY_ALGORITHMS_EIA0;
} else { } else {
LOG_TRACE(WARNING, "EMM-PROC - Failed to create security context"); LOG_TRACE(WARNING, "EMM-PROC - Failed to create security context");
emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE; emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE;
...@@ -2309,62 +2324,63 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx, ...@@ -2309,62 +2324,63 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx,
GUTI_t *guti, imsi_t *imsi, imei_t *imei, GUTI_t *guti, imsi_t *imsi, imei_t *imei,
int eea, int eia) int eea, int eia)
{ {
LOG_FUNC_IN;
/* Emergency bearer services indicator */ /* Emergency bearer services indicator */
if ( (type == EMM_ATTACH_TYPE_EMERGENCY) != ctx->is_emergency) { if ( (type == EMM_ATTACH_TYPE_EMERGENCY) != ctx->is_emergency) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
/* Security key set identifier */ /* Security key set identifier */
if (ksi != ctx->ksi) { if (ksi != ctx->ksi) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
/* Supported EPS encryption algorithms */ /* Supported EPS encryption algorithms */
if (eea != ctx->eea) { if (eea != ctx->eea) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
/* Supported EPS integrity algorithms */ /* Supported EPS integrity algorithms */
if (eia != ctx->eia) { if (eia != ctx->eia) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
/* The GUTI if provided by the UE */ /* The GUTI if provided by the UE */
if ( (guti) && (ctx->guti == NULL) ) { if ( (guti) && (ctx->guti == NULL) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (guti == NULL) && (ctx->guti) ) { if ( (guti == NULL) && (ctx->guti) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (guti) && (ctx->guti) ) { if ( (guti) && (ctx->guti) ) {
if (guti->m_tmsi != ctx->guti->m_tmsi) { if (guti->m_tmsi != ctx->guti->m_tmsi) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( memcmp(&guti->gummei, &ctx->guti->gummei, sizeof(gummei_t)) != 0 ) { if ( memcmp(&guti->gummei, &ctx->guti->gummei, sizeof(gummei_t)) != 0 ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
} }
/* The IMSI if provided by the UE */ /* The IMSI if provided by the UE */
if ( (imsi) && (ctx->imsi == NULL) ) { if ( (imsi) && (ctx->imsi == NULL) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (imsi == NULL) && (ctx->imsi) ) { if ( (imsi == NULL) && (ctx->imsi) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (imsi) && (ctx->imsi) ) { if ( (imsi) && (ctx->imsi) ) {
if ( memcmp(imsi, ctx->imsi, sizeof(imsi_t)) != 0 ) { if ( memcmp(imsi, ctx->imsi, sizeof(imsi_t)) != 0 ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
} }
/* The IMEI if provided by the UE */ /* The IMEI if provided by the UE */
if ( (imei) && (ctx->imei == NULL) ) { if ( (imei) && (ctx->imei == NULL) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (imei == NULL) && (ctx->imei) ) { if ( (imei == NULL) && (ctx->imei) ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if ( (imei) && (ctx->imei) ) { if ( (imei) && (ctx->imei) ) {
if ( memcmp(imei, ctx->imei, sizeof(imei_t)) != 0 ) { if ( memcmp(imei, ctx->imei, sizeof(imei_t)) != 0 ) {
return (TRUE); LOG_FUNC_RETURN (TRUE);
} }
} }
return (FALSE); LOG_FUNC_RETURN (FALSE);
} }
/**************************************************************************** /****************************************************************************
...@@ -2396,6 +2412,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2396,6 +2412,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
GUTI_t *guti, imsi_t *imsi, imei_t *imei, GUTI_t *guti, imsi_t *imsi, imei_t *imei,
int eea, int eia, const OctetString *esm_msg) int eea, int eia, const OctetString *esm_msg)
{ {
LOG_FUNC_IN;
/* UE identifier */ /* UE identifier */
ctx->ueid = ueid; ctx->ueid = ueid;
/* Emergency bearer services indicator */ /* Emergency bearer services indicator */
...@@ -2414,7 +2431,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2414,7 +2431,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
if (ctx->guti != NULL) { if (ctx->guti != NULL) {
memcpy(ctx->guti, guti, sizeof(GUTI_t)); memcpy(ctx->guti, guti, sizeof(GUTI_t));
} else { } else {
return (RETURNerror); LOG_FUNC_RETURN (RETURNerror);
} }
} else { } else {
if (ctx->guti == NULL) { if (ctx->guti == NULL) {
...@@ -2422,6 +2439,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2422,6 +2439,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
} }
if (ctx->guti != NULL) { if (ctx->guti != NULL) {
/* TODO: FIXME */ /* TODO: FIXME */
LOG_TRACE(WARNING, "EMM-PROC - Assign hardcoded PLMN 208.92 and tac 0001 to emm_data_context");
ctx->guti->gummei.plmn.MCCdigit1 = 2; ctx->guti->gummei.plmn.MCCdigit1 = 2;
ctx->guti->gummei.plmn.MCCdigit2 = 0; ctx->guti->gummei.plmn.MCCdigit2 = 0;
ctx->guti->gummei.plmn.MCCdigit3 = 8; ctx->guti->gummei.plmn.MCCdigit3 = 8;
...@@ -2433,8 +2451,10 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2433,8 +2451,10 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
ctx->guti->gummei.MMEgid = 0; ctx->guti->gummei.MMEgid = 0;
ctx->guti->m_tmsi = (uint32_t) ctx; ctx->guti->m_tmsi = (uint32_t) ctx;
ctx->tac = 1;
} else { } else {
return (RETURNerror); LOG_FUNC_RETURN (RETURNerror);
} }
} }
/* The IMSI if provided by the UE */ /* The IMSI if provided by the UE */
...@@ -2445,7 +2465,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2445,7 +2465,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
if (ctx->imsi != NULL) { if (ctx->imsi != NULL) {
memcpy(ctx->imsi, imsi, sizeof(imsi_t)); memcpy(ctx->imsi, imsi, sizeof(imsi_t));
} else { } else {
return (RETURNerror); LOG_FUNC_RETURN (RETURNerror);
} }
} }
/* The IMEI if provided by the UE */ /* The IMEI if provided by the UE */
...@@ -2456,7 +2476,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2456,7 +2476,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
if (ctx->imei != NULL) { if (ctx->imei != NULL) {
memcpy(ctx->imei, imei, sizeof(imei_t)); memcpy(ctx->imei, imei, sizeof(imei_t));
} else { } else {
return (RETURNerror); LOG_FUNC_RETURN (RETURNerror);
} }
} }
/* The ESM message contained within the attach request */ /* The ESM message contained within the attach request */
...@@ -2468,14 +2488,14 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2468,14 +2488,14 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
strncpy((char *)ctx->esm_msg.value, strncpy((char *)ctx->esm_msg.value,
(char *)esm_msg->value, esm_msg->length); (char *)esm_msg->value, esm_msg->length);
} else { } else {
return (RETURNerror); LOG_FUNC_RETURN (RETURNerror);
} }
} }
ctx->esm_msg.length = esm_msg->length; ctx->esm_msg.length = esm_msg->length;
/* Attachment indicator */ /* Attachment indicator */
ctx->is_attached = FALSE; ctx->is_attached = FALSE;
return (RETURNok); LOG_FUNC_RETURN (RETURNok);
} }
#endif // NAS_MME #endif // NAS_MME
...@@ -670,6 +670,8 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause, ...@@ -670,6 +670,8 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause,
/* RES does not match the XRES parameter */ /* RES does not match the XRES parameter */
LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE"); LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE");
emm_cause = EMM_CAUSE_ILLEGAL_UE; emm_cause = EMM_CAUSE_ILLEGAL_UE;
} else {
LOG_TRACE(DEBUG, "EMM-PROC - Success to authentify the UE RESP XRES == XRES UE CONTEXT");
} }
} }
......
...@@ -30,6 +30,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum ...@@ -30,6 +30,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum
#include "emm_sap.h" #include "emm_sap.h"
#include "esm_sap.h" #include "esm_sap.h"
#include "nas_log.h"
#include <string.h> // memset #include <string.h> // memset
...@@ -457,6 +458,14 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args, ...@@ -457,6 +458,14 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args,
* into use, UE and MME shall cipher and integrity protect all * into use, UE and MME shall cipher and integrity protect all
* NAS signalling messages with the selected NAS ciphering and * NAS signalling messages with the selected NAS ciphering and
* NAS integrity algorithms */ * NAS integrity algorithms */
LOG_TRACE(WARNING,
"EPS security context exists is new %u KSI %u SQN %u count %u knas_int %s",
is_new,
context->eksi,
context->ul_count.seq_num,
*(UInt32_t *)(&context->ul_count),
context->knas_int.value
);
data->is_new = is_new; data->is_new = is_new;
data->ksi = context->eksi; data->ksi = context->eksi;
data->sqn = context->ul_count.seq_num; data->sqn = context->ul_count.seq_num;
...@@ -473,9 +482,14 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args, ...@@ -473,9 +482,14 @@ void emm_as_set_security_data(emm_as_security_data_t *data, const void *args,
/* 3GPP TS 24.301, section 5.4.3.2 /* 3GPP TS 24.301, section 5.4.3.2
* The MME shall send the SECURITY MODE COMMAND message integrity * The MME shall send the SECURITY MODE COMMAND message integrity
* protected and unciphered */ * protected and unciphered */
LOG_TRACE(WARNING,
"EPS security context exists knas_enc %s",
context->knas_enc.value
);
data->k_enc = &context->knas_enc; data->k_enc = &context->knas_enc;
} }
} else { } else {
LOG_TRACE(WARNING, "EMM_AS_NO_KEY_AVAILABLE");
/* No valid EPS security context exists */ /* No valid EPS security context exists */
data->ksi = EMM_AS_NO_KEY_AVAILABLE; data->ksi = EMM_AS_NO_KEY_AVAILABLE;
} }
......
...@@ -46,6 +46,7 @@ Description Defines the security mode control EMM procedure executed by the ...@@ -46,6 +46,7 @@ Description Defines the security mode control EMM procedure executed by the
#if defined(ENABLE_ITTI) #if defined(ENABLE_ITTI)
# include "assertions.h" # include "assertions.h"
#endif #endif
#include "secu_defs.h"
/****************************************************************************/ /****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/
...@@ -98,7 +99,11 @@ static void *_security_t3460_handler(void *); ...@@ -98,7 +99,11 @@ static void *_security_t3460_handler(void *);
* retransmission timer counter is exceed * retransmission timer counter is exceed
*/ */
static int _security_abort(void *); static int _security_abort(void *);
static int _security_select_algorithms(
const int ue_eiaP,
const int ue_eeaP,
int * const mme_eiaP,
int * const mme_eeaP);
/* /*
* Internal data used for security mode control procedure * Internal data used for security mode control procedure
*/ */
...@@ -109,6 +114,8 @@ typedef struct { ...@@ -109,6 +114,8 @@ typedef struct {
int ksi; /* NAS key set identifier */ int ksi; /* NAS key set identifier */
int eea; /* Replayed EPS encryption algorithms */ int eea; /* Replayed EPS encryption algorithms */
int eia; /* Replayed EPS integrity algorithms */ int eia; /* Replayed EPS integrity algorithms */
int selected_eea; /* Replayed EPS encryption algorithms */
int selected_eia; /* Replayed EPS integrity algorithms */
int notify_failure; /* Indicates whether the security mode control int notify_failure; /* Indicates whether the security mode control
* procedure failure shall be notified to the * procedure failure shall be notified to the
* ongoing EMM procedure */ * ongoing EMM procedure */
...@@ -332,6 +339,8 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, ...@@ -332,6 +339,8 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
#ifdef NAS_MME #ifdef NAS_MME
/**************************************************************************** /****************************************************************************
** ** ** **
** Name: emm_proc_security_mode_control() ** ** Name: emm_proc_security_mode_control() **
...@@ -372,14 +381,16 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, ...@@ -372,14 +381,16 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
{ {
int rc = RETURNerror; int rc = RETURNerror;
int security_context_is_new = FALSE; int security_context_is_new = FALSE;
int mme_eea = NAS_SECURITY_ALGORITHMS_EEA0;
int mme_eia = NAS_SECURITY_ALGORITHMS_EIA0;
/* Get the UE context */ /* Get the UE context */
emm_data_context_t *emm_ctx = NULL; emm_data_context_t *emm_ctx = NULL;
LOG_FUNC_IN; LOG_FUNC_IN;
LOG_TRACE(INFO, "EMM-PROC - Initiate security mode control procedure " LOG_TRACE(INFO, "EMM-PROC - Initiate security mode control procedure "
"KSI = %d", ksi); "KSI = %d EEA = %d EIA = %d",
ksi, eea, eia);
#if defined(EPC_BUILD) #if defined(EPC_BUILD)
if (ueid > 0) { if (ueid > 0) {
...@@ -402,6 +413,52 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, ...@@ -402,6 +413,52 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
emm_ctx->security->dl_count.seq_num = 0; emm_ctx->security->dl_count.seq_num = 0;
/* TODO !!! Compute Kasme, and NAS cyphering and integrity keys */ /* TODO !!! Compute Kasme, and NAS cyphering and integrity keys */
// LG: Kasme should have been received from authentication
// information request (S6A)
// Kasme is located in emm_ctx->vector.kasme
rc = _security_select_algorithms(
eia,
eea,
&mme_eia,
&mme_eea);
emm_ctx->security->selected_algorithms.encryption = mme_eea;
emm_ctx->security->selected_algorithms.integrity = mme_eia;
if (rc == RETURNerror) {
LOG_TRACE(WARNING,
"EMM-PROC - Failed to select security algorithms");
LOG_FUNC_RETURN (RETURNerror);
}
if ( ! emm_ctx->security->knas_int.value) {
emm_ctx->security->knas_int.value = malloc(AUTH_KNAS_INT_SIZE);
} else {
AssertFatal(
emm_ctx->security->knas_int.length >= AUTH_KNAS_INT_SIZE,
" TODO realloc emm_ctx->security->knas_int OctetString");
}
emm_ctx->security->knas_int.length = AUTH_KNAS_INT_SIZE;
derive_key_nas(
NAS_INT_ALG,
emm_ctx->security->selected_algorithms.integrity,
emm_ctx->vector.kasme,
&emm_ctx->security->knas_int.value);
if ( ! emm_ctx->security->knas_enc.value) {
emm_ctx->security->knas_enc.value = malloc(AUTH_KNAS_ENC_SIZE);
} else {
AssertFatal(
emm_ctx->security->knas_enc.length >= AUTH_KNAS_ENC_SIZE,
" TODO realloc emm_ctx->security->knas_enc OctetString");
}
emm_ctx->security->knas_enc.length = AUTH_KNAS_ENC_SIZE;
derive_key_nas(
NAS_ENC_ALG,
emm_ctx->security->selected_algorithms.encryption,
emm_ctx->vector.kasme,
&emm_ctx->security->knas_enc.value);
/* Set new security context indicator */ /* Set new security context indicator */
security_context_is_new = TRUE; security_context_is_new = TRUE;
...@@ -434,6 +491,10 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, ...@@ -434,6 +491,10 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
data->eea = eea; data->eea = eea;
/* Set the EPS integrity algorithms to be replayed to the UE */ /* Set the EPS integrity algorithms to be replayed to the UE */
data->eia = eia; data->eia = eia;
/* Set the EPS encryption algorithms to be replayed to the UE */
data->selected_eea = emm_ctx->security->selected_algorithms.encryption;
/* Set the EPS integrity algorithms to be replayed to the UE */
data->selected_eia = emm_ctx->security->selected_algorithms.integrity;
/* Set the failure notification indicator */ /* Set the failure notification indicator */
data->notify_failure = FALSE; data->notify_failure = FALSE;
/* Send security mode command message to the UE */ /* Send security mode command message to the UE */
...@@ -891,6 +952,8 @@ int _security_request(security_data_t *data, int is_new) ...@@ -891,6 +952,8 @@ int _security_request(security_data_t *data, int is_new)
emm_sap.u.emm_as.u.security.ksi = data->ksi; emm_sap.u.emm_as.u.security.ksi = data->ksi;
emm_sap.u.emm_as.u.security.eea = data->eea; emm_sap.u.emm_as.u.security.eea = data->eea;
emm_sap.u.emm_as.u.security.eia = data->eia; emm_sap.u.emm_as.u.security.eia = data->eia;
emm_sap.u.emm_as.u.security.selected_eea = data->selected_eea;
emm_sap.u.emm_as.u.security.selected_eia = data->selected_eia;
#if defined(EPC_BUILD) #if defined(EPC_BUILD)
if (data->ueid > 0) { if (data->ueid > 0) {
...@@ -976,5 +1039,64 @@ static int _security_abort(void *args) ...@@ -976,5 +1039,64 @@ static int _security_abort(void *args)
LOG_FUNC_RETURN (rc); LOG_FUNC_RETURN (rc);
} }
/****************************************************************************
** **
** Name: _security_select_algorithms() **
** **
** Description: Select int and enc algorithms based on UE capabilities and**
** MME capabilities and MME preferences **
** **
** Inputs: ue_eia: integrity algorithms supported by UE **
** ue_eea: ciphering algorithms supported by UE **
** **
** Outputs: mme_eia: integrity algorithms supported by MME **
** mme_eea: ciphering algorithms supported by MME **
** **
** Return: RETURNok, RETURNerror **
** Others: None **
** **
***************************************************************************/
static int _security_select_algorithms(
const int ue_eiaP,
const int ue_eeaP,
int * const mme_eiaP,
int * const mme_eeaP)
{
LOG_FUNC_IN;
int rc = RETURNerror;
/* TODO work with loaded preferences from config file */
if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA2)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA0");
*mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA0;
} else if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA1)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA1");
*mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA1;
} else if (ue_eiaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EIA0)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EIA0");
*mme_eiaP = NAS_SECURITY_ALGORITHMS_EIA0;
} else {
LOG_FUNC_RETURN (rc);
}
if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA0)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA0");
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA0;
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA2)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA2");
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA2;
} else if (ue_eeaP & (0x80 >> NAS_SECURITY_ALGORITHMS_EEA1)) {
LOG_TRACE(DEBUG,"Selected NAS_SECURITY_ALGORITHMS_EEA1");
*mme_eeaP = NAS_SECURITY_ALGORITHMS_EEA1;
} else {
LOG_FUNC_RETURN (rc);
}
LOG_FUNC_RETURN (RETURNok);
}
#endif // NAS_MME #endif // NAS_MME
...@@ -113,6 +113,10 @@ typedef struct { ...@@ -113,6 +113,10 @@ typedef struct {
UInt8_t encryption:4; /* algorithm used for ciphering */ UInt8_t encryption:4; /* algorithm used for ciphering */
UInt8_t integrity:4; /* algorithm used for integrity protection */ UInt8_t integrity:4; /* algorithm used for integrity protection */
} capability; /* UE network capability */ } capability; /* UE network capability */
struct {
UInt8_t encryption:4; /* algorithm used for ciphering */
UInt8_t integrity:4; /* algorithm used for integrity protection */
} selected_algorithms; /* MME selected algorithms */
} emm_security_context_t; } emm_security_context_t;
/* /*
......
...@@ -98,6 +98,10 @@ typedef struct { ...@@ -98,6 +98,10 @@ typedef struct {
UInt8_t eea; /* Replayed EPS encryption algorithms */ UInt8_t eea; /* Replayed EPS encryption algorithms */
UInt8_t eia; /* Replayed EPS integrity algorithms */ UInt8_t eia; /* Replayed EPS integrity algorithms */
// Added by LG
UInt8_t selected_eea; /* Selected EPS encryption algorithms */
UInt8_t selected_eia; /* Selected EPS integrity algorithms */
#define EMM_AS_MSG_TYPE_IDENT 0x01 /* Identification message */ #define EMM_AS_MSG_TYPE_IDENT 0x01 /* Identification message */
#define EMM_AS_MSG_TYPE_AUTH 0x02 /* Authentication message */ #define EMM_AS_MSG_TYPE_AUTH 0x02 /* Authentication message */
#define EMM_AS_MSG_TYPE_SMC 0x03 /* Security Mode Command */ #define EMM_AS_MSG_TYPE_SMC 0x03 /* Security Mode Command */
......
...@@ -101,8 +101,11 @@ static int _emm_cn_authentication_res(const emm_cn_auth_res_t *msg) ...@@ -101,8 +101,11 @@ static int _emm_cn_authentication_res(const emm_cn_auth_res_t *msg)
* and NAS security setup to activate integrity protection and NAS * and NAS security setup to activate integrity protection and NAS
* ciphering are mandatory. * ciphering are mandatory.
*/ */
rc = emm_proc_authentication(emm_ctx, emm_ctx->ueid, 0, // TODO: eksi != 0 rc = emm_proc_authentication(emm_ctx,
&loc_rand, &autn, emm_ctx->ueid,
0, // TODO: eksi != 0
&loc_rand,
&autn,
emm_attach_security, emm_attach_security,
NULL, NULL,
NULL); NULL);
......
...@@ -983,7 +983,9 @@ int emm_recv_authentication_failure(unsigned int ueid, ...@@ -983,7 +983,9 @@ int emm_recv_authentication_failure(unsigned int ueid,
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
int emm_recv_security_mode_complete(unsigned int ueid, int
emm_recv_security_mode_complete(
unsigned int ueid,
security_mode_complete_msg *msg, security_mode_complete_msg *msg,
int *emm_cause) int *emm_cause)
{ {
......
...@@ -1205,9 +1205,9 @@ int emm_send_security_mode_command(const emm_as_security_t *msg, ...@@ -1205,9 +1205,9 @@ int emm_send_security_mode_command(const emm_as_security_t *msg,
/* Selected NAS security algorithms */ /* Selected NAS security algorithms */
size += NAS_SECURITY_ALGORITHMS_MAXIMUM_LENGTH; size += NAS_SECURITY_ALGORITHMS_MAXIMUM_LENGTH;
emm_msg->selectednassecurityalgorithms.typeofcipheringalgorithm = emm_msg->selectednassecurityalgorithms.typeofcipheringalgorithm =
NAS_SECURITY_ALGORITHMS_EEA0; msg->selected_eea;
emm_msg->selectednassecurityalgorithms.typeofintegrityalgorithm = emm_msg->selectednassecurityalgorithms.typeofintegrityalgorithm =
NAS_SECURITY_ALGORITHMS_EIA0; msg->selected_eia;
/* NAS key set identifier */ /* NAS key set identifier */
size += NAS_KEY_SET_IDENTIFIER_MAXIMUM_LENGTH; size += NAS_KEY_SET_IDENTIFIER_MAXIMUM_LENGTH;
......
...@@ -48,8 +48,8 @@ Description Contains global security definitions ...@@ -48,8 +48,8 @@ Description Contains global security definitions
#define AUTH_RES_SIZE 16 /* Authentication response: 128 bits */ #define AUTH_RES_SIZE 16 /* Authentication response: 128 bits */
#define AUTH_SNID_SIZE 3 /* Serving network's identity: 24 bits */ #define AUTH_SNID_SIZE 3 /* Serving network's identity: 24 bits */
#define AUTH_KASME_SIZE 32 /* KASME security key: 256 bits */ #define AUTH_KASME_SIZE 32 /* KASME security key: 256 bits */
#define AUTH_KNAS_INT_SIZE AUTH_KASME_SIZE /* NAS integrity key */ #define AUTH_KNAS_INT_SIZE 16 /* NAS integrity key */
#define AUTH_KNAS_ENC_SIZE AUTH_KASME_SIZE /* NAS cyphering key */ #define AUTH_KNAS_ENC_SIZE 16 /* NAS cyphering key */
#define AUTH_KENB_SIZE AUTH_KASME_SIZE /* eNodeB security key */ #define AUTH_KENB_SIZE AUTH_KASME_SIZE /* eNodeB security key */
/* "Separation bit" of AMF field */ /* "Separation bit" of AMF field */
......
...@@ -8,6 +8,7 @@ AM_CFLAGS = \ ...@@ -8,6 +8,7 @@ AM_CFLAGS = \
-DEPC_BUILD \ -DEPC_BUILD \
-DENABLE_ITTI \ -DENABLE_ITTI \
-I$(top_srcdir)/COMMON \ -I$(top_srcdir)/COMMON \
-I$(top_srcdir)/SECU \
-I$(top_srcdir)/INTERTASK_INTERFACE \ -I$(top_srcdir)/INTERTASK_INTERFACE \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/user \ -I$(top_srcdir)/NAS/EURECOM-NAS/src/api/user \
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/mme \ -I$(top_srcdir)/NAS/EURECOM-NAS/src/api/mme \
......
...@@ -653,12 +653,18 @@ void s1ap_handle_conn_est_cnf(const mme_app_connection_establishment_cnf_t * con ...@@ -653,12 +653,18 @@ void s1ap_handle_conn_est_cnf(const mme_app_connection_establishment_cnf_t * con
initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.bits_unused initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.bits_unused
= 0; = 0;
// initialContextSetupRequest_p->securityKey.buf = initial_p->keNB; /* 256 bits length */ if (conn_est_cnf_pP->keNB) {
uint8_t keNB[32]; initialContextSetupRequest_p->securityKey.buf = malloc(32);
memset(keNB, 0, sizeof(keNB)); memcpy(initialContextSetupRequest_p->securityKey.buf,
conn_est_cnf_pP->keNB,
32);
initialContextSetupRequest_p->securityKey.buf = keNB;
initialContextSetupRequest_p->securityKey.size = 32; initialContextSetupRequest_p->securityKey.size = 32;
} else {
S1AP_DEBUG("No keNB\n");
initialContextSetupRequest_p->securityKey.buf = NULL;
initialContextSetupRequest_p->securityKey.size = 0;
}
initialContextSetupRequest_p->securityKey.bits_unused = 0; initialContextSetupRequest_p->securityKey.bits_unused = 0;
if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) { if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) {
......
...@@ -9,10 +9,15 @@ ...@@ -9,10 +9,15 @@
#include <openssl/cmac.h> #include <openssl/cmac.h>
#include <openssl/evp.h> #include <openssl/evp.h>
// test
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include "assertions.h" #include "assertions.h"
#include "conversions.h" #include "conversions.h"
// #define SECU_DEBUG #define SECU_DEBUG
/*! /*!
* @brief Create integrity cmac t for a given message. * @brief Create integrity cmac t for a given message.
...@@ -21,19 +26,19 @@ ...@@ -21,19 +26,19 @@
*/ */
int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
{ {
uint8_t *m; uint8_t *m = NULL;
uint32_t local_count; uint32_t local_count;
size_t size = 4; size_t size = 4;
uint8_t data[16]; uint8_t data[16];
CMAC_CTX *cmac_ctx = NULL;
CMAC_CTX *cmac_ctx; const EVP_CIPHER *cipher = EVP_aes_128_cbc();
uint32_t zero_bit = 0; uint32_t zero_bit = 0;
uint32_t m_length; uint32_t m_length;
int ret;
DevAssert(stream_cipher != NULL); DevAssert(stream_cipher != NULL);
DevAssert(stream_cipher->key != NULL); DevAssert(stream_cipher->key != NULL);
DevAssert(stream_cipher->key_length > 0);
DevAssert(out != NULL); DevAssert(out != NULL);
memset(data, 0, 16); memset(data, 0, 16);
...@@ -59,24 +64,36 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4]) ...@@ -59,24 +64,36 @@ int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
printf("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit); printf("Byte length: %u, Zero bits: %u\nm: ", m_length + 8, zero_bit);
for (i = 0; i < m_length + 8; i++) for (i = 0; i < m_length + 8; i++)
printf("%02x", m[i]); printf("%02x", m[i]);
printf("\nKey:");
for (i = 0; i < stream_cipher->key_length; i++)
printf("%02x", stream_cipher->key[i]);
printf("\nMessage:");
for (i = 0; i < m_length; i++)
printf("%02x", stream_cipher->message[i]);
printf("\n"); printf("\n");
} }
#endif #endif
cmac_ctx = CMAC_CTX_new(); cmac_ctx = CMAC_CTX_new();
ret = CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL);
CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, EVP_aes_128_cbc(), NULL); #if defined(SECU_DEBUG)
CMAC_Update(cmac_ctx, m, m_length + 8); printf("CMAC_Init returned %d\n", ret);
#endif
ret = CMAC_Update(cmac_ctx, m, m_length + 8);
#if defined(SECU_DEBUG)
printf("CMAC_Update returned %d\n", ret);
#endif
CMAC_Final(cmac_ctx, data, &size); CMAC_Final(cmac_ctx, data, &size);
#if defined(SECU_DEBUG)
printf("CMAC_Final returned %d, size = %u\n", ret, size);
#endif
CMAC_CTX_free(cmac_ctx); CMAC_CTX_free(cmac_ctx);
#if defined(SECU_DEBUG) #if defined(SECU_DEBUG)
{ {
int i; int i;
printf("out: "); printf("out: ");
for (i = 0; i < 16; i++) for (i = 0; i < size; i++)
printf("%02x", data[i]); printf("%02x", data[i]);
printf("\n"); printf("\n");
} }
......
...@@ -7,6 +7,13 @@ ...@@ -7,6 +7,13 @@
#define EIA1_128_ALG_ID 0x01 #define EIA1_128_ALG_ID 0x01
#define EIA2_128_ALG_ID 0x02 #define EIA2_128_ALG_ID 0x02
#define EEA0_ALG_ID 0x00
#define EEA1_128_ALG_ID 0x01
#define EEA2_128_ALG_ID 0x02
#define SECU_DIRECTION_UPLINK 0
#define SECU_DIRECTION_DOWNLINK 1
inline inline
void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key, void kdf(const uint8_t *s, const uint32_t s_length, const uint8_t *key,
const uint32_t key_length, uint8_t **out, uint32_t out_length); const uint32_t key_length, uint8_t **out, uint32_t out_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment