Commit 7f5fb1c9 authored by Lionel Gauthier's avatar Lionel Gauthier

Replayed ue security capabilities

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5675 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 8e7d0de5
...@@ -706,7 +706,7 @@ static int _nas_message_protected_decode( ...@@ -706,7 +706,7 @@ static int _nas_message_protected_decode(
int bytes = TLV_DECODE_BUFFER_TOO_SHORT; int bytes = TLV_DECODE_BUFFER_TOO_SHORT;
char* plain_msg = (char*)malloc(length); char* plain_msg = (char*)calloc(1,length);
if (plain_msg) if (plain_msg)
{ {
/* Decrypt the security protected NAS message */ /* Decrypt the security protected NAS message */
...@@ -862,7 +862,7 @@ static int _nas_message_protected_encode( ...@@ -862,7 +862,7 @@ static int _nas_message_protected_encode(
emm_security_context_t *emm_security_context = (emm_security_context_t*)security; emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
int bytes = TLV_ENCODE_BUFFER_TOO_SHORT; int bytes = TLV_ENCODE_BUFFER_TOO_SHORT;
char* plain_msg = (char*)malloc(length); char* plain_msg = (char*)calloc(1,length);
if (plain_msg) { if (plain_msg) {
/* Encode the security protected NAS message as plain NAS message */ /* Encode the security protected NAS message as plain NAS message */
int size = _nas_message_plain_encode(plain_msg, &msg->header, int size = _nas_message_plain_encode(plain_msg, &msg->header,
......
...@@ -152,11 +152,14 @@ static int _emm_attach_abort(void *); ...@@ -152,11 +152,14 @@ static int _emm_attach_abort(void *);
static int _emm_attach_have_changed(const emm_data_context_t *ctx, static int _emm_attach_have_changed(const emm_data_context_t *ctx,
emm_proc_attach_type_t type, int ksi, emm_proc_attach_type_t type, int ksi,
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, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present);
static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
emm_proc_attach_type_t type, int ksi, emm_proc_attach_type_t type, int ksi,
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, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present,
const OctetString *esm_msg);
/* /*
* Internal data used for attach procedure * Internal data used for attach procedure
...@@ -286,10 +289,10 @@ int emm_proc_attach(emm_proc_attach_type_t type) ...@@ -286,10 +289,10 @@ int emm_proc_attach(emm_proc_attach_type_t type)
if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) { if (_emm_data.security->type != EMM_KSI_NOT_AVAILABLE) {
emm_as->ksi = _emm_data.security->eksi; emm_as->ksi = _emm_data.security->eksi;
} }
LOG_TRACE(INFO, "EMM-PROC - encryption 0x%X", _emm_data.security->capability.encryption); LOG_TRACE(INFO, "EMM-PROC - eps_encryption 0x%X", _emm_data.security->capability.eps_encryption);
LOG_TRACE(INFO, "EMM-PROC - integrity 0x%X", _emm_data.security->capability.integrity); LOG_TRACE(INFO, "EMM-PROC - eps_integrity 0x%X", _emm_data.security->capability.eps_integrity);
emm_as->encryption = _emm_data.security->capability.encryption; emm_as->encryption = _emm_data.security->capability.eps_encryption;
emm_as->integrity = _emm_data.security->capability.integrity; emm_as->integrity = _emm_data.security->capability.eps_integrity;
} }
/* /*
* Notify ESM that initiation of a PDN connectivity procedure * Notify ESM that initiation of a PDN connectivity procedure
...@@ -1051,7 +1054,9 @@ int emm_proc_attach_set_detach(void) ...@@ -1051,7 +1054,9 @@ int emm_proc_attach_set_detach(void)
int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
int native_ksi, int ksi, int native_guti, int native_ksi, int ksi, int native_guti,
GUTI_t *guti, imsi_t *imsi, imei_t *imei, GUTI_t *guti, imsi_t *imsi, imei_t *imei,
tai_t *tai, int eea, int eia, tai_t *tai,
int eea, int eia, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present,
const OctetString *esm_msg) const OctetString *esm_msg)
{ {
LOG_FUNC_IN; LOG_FUNC_IN;
...@@ -1061,6 +1066,8 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, ...@@ -1061,6 +1066,8 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
LOG_TRACE(INFO, "EMM-PROC - EPS attach type = %s (%d) requested (ueid=0x%08x)", LOG_TRACE(INFO, "EMM-PROC - EPS attach type = %s (%d) requested (ueid=0x%08x)",
_emm_attach_type_str[type], type, ueid); _emm_attach_type_str[type], type, ueid);
LOG_TRACE(INFO, "EMM-PROC - umts_present = %u umts_present = %u",
umts_present, gprs_present);
/* Initialize the temporary UE context */ /* Initialize the temporary UE context */
memset(&ue_ctx, 0 , sizeof(emm_data_context_t)); memset(&ue_ctx, 0 , sizeof(emm_data_context_t));
...@@ -1105,7 +1112,7 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, ...@@ -1105,7 +1112,7 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
if (*emm_ctx != NULL) { if (*emm_ctx != NULL) {
/* An EMM context already exists for the UE in the network */ /* An EMM context already exists for the UE in the network */
if (_emm_attach_have_changed(*emm_ctx, type, ksi, guti, imsi, imei, if (_emm_attach_have_changed(*emm_ctx, type, ksi, guti, imsi, imei,
eea, eia)) { eea, eia, ucs2, uea, uia, gea, umts_present, gprs_present)) {
/* /*
* 3GPP TS 24.301, section 5.5.1.2.7, abnormal case e * 3GPP TS 24.301, section 5.5.1.2.7, abnormal case e
* The attach parameters have changed from the one received within * The attach parameters have changed from the one received within
...@@ -1129,7 +1136,8 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, ...@@ -1129,7 +1136,8 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
LOG_TRACE(WARNING, "EMM-PROC - Initiate new attach procedure"); LOG_TRACE(WARNING, "EMM-PROC - Initiate new attach procedure");
rc = emm_proc_attach_request(ueid, type, native_ksi, ksi, rc = emm_proc_attach_request(ueid, type, native_ksi, ksi,
native_guti, guti, imsi, imei, native_guti, guti, imsi, imei,
tai, eea, eia, esm_msg); tai, eea, eia, ucs2, uea, uia, gea,
umts_present, gprs_present, esm_msg);
} }
LOG_FUNC_RETURN(rc); LOG_FUNC_RETURN(rc);
} else { } else {
...@@ -1178,7 +1186,7 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, ...@@ -1178,7 +1186,7 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
/* Update the EMM context with the current attach procedure parameters */ /* Update the EMM context with the current attach procedure parameters */
rc = _emm_attach_update(*emm_ctx, ueid, type, ksi, guti, imsi, imei, rc = _emm_attach_update(*emm_ctx, ueid, type, ksi, guti, imsi, imei,
eea, eia, esm_msg); eea, eia, ucs2, uea, uia, gea, umts_present, gprs_present, esm_msg);
if (rc != RETURNok) { if (rc != RETURNok) {
LOG_TRACE(WARNING, "EMM-PROC - Failed to update EMM context"); LOG_TRACE(WARNING, "EMM-PROC - Failed to update EMM context");
/* Do not accept the UE to attach to the network */ /* Do not accept the UE to attach to the network */
...@@ -2104,9 +2112,11 @@ static int _emm_attach_security(void *args) ...@@ -2104,9 +2112,11 @@ static int _emm_attach_security(void *args)
/* Initialize the security mode control procedure */ /* Initialize the security mode control procedure */
rc = emm_proc_security_mode_control(emm_ctx->ueid, 0, // TODO: eksi != 0 rc = emm_proc_security_mode_control(emm_ctx->ueid, 0, // TODO: eksi != 0
emm_ctx->eea, emm_ctx->eia, emm_ctx->eea, emm_ctx->eia,emm_ctx->ucs2,
_emm_attach, _emm_attach_release, emm_ctx->uea, emm_ctx->uia, emm_ctx->gea,
_emm_attach_release); emm_ctx->umts_present, emm_ctx->gprs_present,
_emm_attach, _emm_attach_release,
_emm_attach_release);
if (rc != RETURNok) { if (rc != RETURNok) {
/* Failed to initiate the security mode control procedure */ /* Failed to initiate the security mode control procedure */
LOG_TRACE(WARNING, "EMM-PROC - " LOG_TRACE(WARNING, "EMM-PROC - "
...@@ -2373,7 +2383,8 @@ static int _emm_attach_accept(emm_data_context_t *emm_ctx, attach_data_t *data) ...@@ -2373,7 +2383,8 @@ static int _emm_attach_accept(emm_data_context_t *emm_ctx, attach_data_t *data)
static int _emm_attach_have_changed(const emm_data_context_t *ctx, static int _emm_attach_have_changed(const emm_data_context_t *ctx,
emm_proc_attach_type_t type, int ksi, emm_proc_attach_type_t type, int ksi,
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, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present)
{ {
LOG_FUNC_IN; LOG_FUNC_IN;
/* Emergency bearer services indicator */ /* Emergency bearer services indicator */
...@@ -2392,6 +2403,31 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx, ...@@ -2392,6 +2403,31 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx,
if (eia != ctx->eia) { if (eia != ctx->eia) {
LOG_FUNC_RETURN (TRUE); LOG_FUNC_RETURN (TRUE);
} }
if (umts_present != ctx->umts_present){
LOG_FUNC_RETURN (TRUE);
}
if (ctx->umts_present){
if (ucs2 != ctx->ucs2) {
LOG_FUNC_RETURN (TRUE);
}
/* Supported UMTS encryption algorithms */
if (uea != ctx->uea) {
LOG_FUNC_RETURN (TRUE);
}
/* Supported UMTS integrity algorithms */
if (uia != ctx->uia) {
LOG_FUNC_RETURN (TRUE);
}
}
if (gprs_present != ctx->gprs_present){
LOG_FUNC_RETURN (TRUE);
}
if (ctx->gprs_present){
if (gea != ctx->gea) {
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) ) {
LOG_FUNC_RETURN (TRUE); LOG_FUNC_RETURN (TRUE);
...@@ -2461,7 +2497,9 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx, ...@@ -2461,7 +2497,9 @@ static int _emm_attach_have_changed(const emm_data_context_t *ctx,
static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
emm_proc_attach_type_t type, int ksi, emm_proc_attach_type_t type, int ksi,
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, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present,
const OctetString *esm_msg)
{ {
LOG_FUNC_IN; LOG_FUNC_IN;
/* UE identifier */ /* UE identifier */
...@@ -2469,11 +2507,20 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid, ...@@ -2469,11 +2507,20 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
/* Emergency bearer services indicator */ /* Emergency bearer services indicator */
ctx->is_emergency = (type == EMM_ATTACH_TYPE_EMERGENCY); ctx->is_emergency = (type == EMM_ATTACH_TYPE_EMERGENCY);
/* Security key set identifier */ /* Security key set identifier */
ctx->ksi = ksi; ctx->ksi = ksi;
/* Supported EPS encryption algorithms */ /* Supported EPS encryption algorithms */
ctx->eea = eea; ctx->eea = eea;
/* Supported EPS integrity algorithms */ /* Supported EPS integrity algorithms */
ctx->eia = eia; ctx->eia = eia;
ctx->ucs2 = ucs2;
ctx->uea = uea;
ctx->uia = uia;
ctx->gea = gea;
LOG_TRACE(WARNING, "EMM-PROC - umts_present %u", umts_present);
LOG_TRACE(WARNING, "EMM-PROC - gprs_present %u", gprs_present);
ctx->umts_present = umts_present;
ctx->gprs_present = gprs_present;
/* The GUTI if provided by the UE */ /* The GUTI if provided by the UE */
if (guti) { if (guti) {
if (ctx->guti == NULL) { if (ctx->guti == NULL) {
......
...@@ -133,14 +133,20 @@ static int _security_select_algorithms( ...@@ -133,14 +133,20 @@ static int _security_select_algorithms(
* Internal data used for security mode control procedure * Internal data used for security mode control procedure
*/ */
typedef struct { typedef struct {
unsigned int ueid; /* UE identifier */ unsigned int ueid; /* UE identifier */
#define SECURITY_COUNTER_MAX 5 #define SECURITY_COUNTER_MAX 5
unsigned int retransmission_count; /* Retransmission counter */ unsigned int retransmission_count; /* Retransmission counter */
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; /* Selected EPS encryption algorithms */ int ucs2; /* Replayed Alphabet */
int selected_eia; /* Selected EPS integrity algorithms */ int uea; /* Replayed UMTS encryption algorithms */
int uia; /* Replayed UMTS integrity algorithms */
int gea; /* Replayed G encryption algorithms */
int umts_present:1;
int gprs_present:1;
int selected_eea; /* Selected EPS encryption algorithms */
int selected_eia; /* Selected 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 */
...@@ -206,8 +212,8 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, ...@@ -206,8 +212,8 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
/* /*
* Check the replayed UE security capabilities * Check the replayed UE security capabilities
*/ */
UInt8_t eea = (0x80 >> _emm_data.security->capability.encryption); UInt8_t eea = (0x80 >> _emm_data.security->capability.eps_encryption);
UInt8_t eia = (0x80 >> _emm_data.security->capability.integrity); UInt8_t eia = (0x80 >> _emm_data.security->capability.eps_integrity);
if ( (reea != eea) || (reia != eia) ) { if ( (reea != eea) || (reia != eia) ) {
LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities " LOG_TRACE(WARNING, "EMM-PROC - Replayed UE security capabilities "
"rejected"); "rejected");
...@@ -412,10 +418,11 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, ...@@ -412,10 +418,11 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
** Others: None ** ** Others: None **
** ** ** **
***************************************************************************/ ***************************************************************************/
int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, int emm_proc_security_mode_control(unsigned int ueid, int ksi,
emm_common_success_callback_t success, int eea, int eia,int ucs2, int uea, int uia, int gea, int umts_present, int gprs_present,
emm_common_reject_callback_t reject, emm_common_success_callback_t success,
emm_common_failure_callback_t failure) emm_common_reject_callback_t reject,
emm_common_failure_callback_t failure)
{ {
int rc = RETURNerror; int rc = RETURNerror;
int security_context_is_new = FALSE; int security_context_is_new = FALSE;
...@@ -536,9 +543,18 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, ...@@ -536,9 +543,18 @@ 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->ucs2 = ucs2;
/* Set the UMTS encryption algorithms to be replayed to the UE */
data->uea = uea;
/* Set the UMTS integrity algorithms to be replayed to the UE */
data->uia = uia;
/* Set the GPRS integrity algorithms to be replayed to the UE */
data->gea = gea;
data->umts_present = umts_present;
data->gprs_present = gprs_present;
/* Set the EPS encryption algorithms selected to the UE */
data->selected_eea = emm_ctx->security->selected_algorithms.encryption; data->selected_eea = emm_ctx->security->selected_algorithms.encryption;
/* Set the EPS integrity algorithms to be replayed to the UE */ /* Set the EPS integrity algorithms selected to the UE */
data->selected_eia = emm_ctx->security->selected_algorithms.integrity; 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;
...@@ -1017,6 +1033,12 @@ int _security_request(security_data_t *data, int is_new) ...@@ -1017,6 +1033,12 @@ 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.ucs2 = data->ucs2;
emm_sap.u.emm_as.u.security.uea = data->uea;
emm_sap.u.emm_as.u.security.uia = data->uia;
emm_sap.u.emm_as.u.security.gea = data->gea;
emm_sap.u.emm_as.u.security.umts_present = data->umts_present;
emm_sap.u.emm_as.u.security.gprs_present = data->gprs_present;
emm_sap.u.emm_as.u.security.selected_eea = data->selected_eea; emm_sap.u.emm_as.u.security.selected_eea = data->selected_eea;
emm_sap.u.emm_as.u.security.selected_eia = data->selected_eia; emm_sap.u.emm_as.u.security.selected_eia = data->selected_eia;
......
...@@ -135,8 +135,13 @@ typedef struct { ...@@ -135,8 +135,13 @@ typedef struct {
UInt32_t seq_num:8; UInt32_t seq_num:8;
} dl_count, ul_count; /* Downlink and uplink count parameters */ } dl_count, ul_count; /* Downlink and uplink count parameters */
struct { struct {
UInt8_t encryption:4; /* algorithm used for ciphering */ UInt8_t eps_encryption; /* algorithm used for ciphering */
UInt8_t integrity:4; /* algorithm used for integrity protection */ UInt8_t eps_integrity; /* algorithm used for integrity protection */
UInt8_t umts_encryption; /* algorithm used for ciphering */
UInt8_t umts_integrity; /* algorithm used for integrity protection */
UInt8_t gprs_encryption; /* algorithm used for ciphering */
UInt8_t umts_present:1;
UInt8_t gprs_present:1;
} capability; /* UE network capability */ } capability; /* UE network capability */
struct { struct {
UInt8_t encryption:4; /* algorithm used for ciphering */ UInt8_t encryption:4; /* algorithm used for ciphering */
...@@ -373,6 +378,13 @@ typedef struct emm_data_context_s { ...@@ -373,6 +378,13 @@ typedef struct emm_data_context_s {
int ksi; /* Security key set identifier provided by the UE */ int ksi; /* Security key set identifier provided by the UE */
int eea; /* EPS encryption algorithms supported by the UE */ int eea; /* EPS encryption algorithms supported by the UE */
int eia; /* EPS integrity algorithms supported by the UE */ int eia; /* EPS integrity algorithms supported by the UE */
int ucs2; /* UCS2 Alphabet*/
int uea; /* UMTS encryption algorithms supported by the UE */
int uia; /* UMTS integrity algorithms supported by the UE */
int gea; /* GPRS encryption algorithms supported by the UE */
int umts_present; /* For encoding ue network capabilities (variable size)*/
int gprs_present; /* For encoding ue network capabilities (variable size)*/
auth_vector_t vector;/* EPS authentication vector */ auth_vector_t vector;/* EPS authentication vector */
emm_security_context_t *security; /* Current EPS NAS security context */ emm_security_context_t *security; /* Current EPS NAS security context */
OctetString esm_msg; /* ESM message contained within the initial request*/ OctetString esm_msg; /* ESM message contained within the initial request*/
......
...@@ -301,10 +301,10 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei) ...@@ -301,10 +301,10 @@ void emm_main_initialize(emm_indication_callback_t cb, const char *imei)
_usim_data.securityctx.ulNAScount.length); _usim_data.securityctx.ulNAScount.length);
} }
/* Ciphering algorithm */ /* Ciphering algorithm */
_emm_data.security->capability.encryption = _emm_data.security->capability.eps_encryption =
((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf); ((_usim_data.securityctx.algorithmID.value[0] >> 4) & 0xf);
/* Identity protection algorithm */ /* Identity protection algorithm */
_emm_data.security->capability.integrity = _emm_data.security->capability.eps_integrity =
(_usim_data.securityctx.algorithmID.value[0] & 0xf); (_usim_data.securityctx.algorithmID.value[0] & 0xf);
/* NAS integrity and cyphering keys are not available */ /* NAS integrity and cyphering keys are not available */
} else { } else {
......
...@@ -159,7 +159,8 @@ int emm_proc_attach_set_detach(void); ...@@ -159,7 +159,8 @@ int emm_proc_attach_set_detach(void);
#ifdef NAS_MME #ifdef NAS_MME
int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type, int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
int native_ksi, int ksi, int native_guti, GUTI_t *guti, imsi_t *imsi, int native_ksi, int ksi, int native_guti, GUTI_t *guti, imsi_t *imsi,
imei_t *imei, tai_t *tai, int eea, int eia, const OctetString *esm_msg); imei_t *imei, tai_t *tai, int eea, int eia, int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present, const OctetString *esm_msg);
int emm_proc_attach_reject(unsigned int ueid, int emm_cause); int emm_proc_attach_reject(unsigned int ueid, int emm_cause);
int emm_proc_attach_complete(unsigned int ueid, const OctetString *esm_msg); int emm_proc_attach_complete(unsigned int ueid, const OctetString *esm_msg);
int emm_proc_tracking_area_update_reject(unsigned int ueid, int emm_cause); int emm_proc_tracking_area_update_reject(unsigned int ueid, int emm_cause);
...@@ -240,7 +241,9 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia, ...@@ -240,7 +241,9 @@ int emm_proc_security_mode_command(int native_ksi, int ksi, int seea, int seia,
#endif #endif
#ifdef NAS_MME #ifdef NAS_MME
int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia, int emm_proc_security_mode_control(unsigned int ueid, int ksi,
int eea, int eia,int ucs2, int uea, int uia, int gea,
int umts_present, int gprs_present,
emm_common_success_callback_t success, emm_common_success_callback_t success,
emm_common_reject_callback_t reject, emm_common_reject_callback_t reject,
emm_common_failure_callback_t failure); emm_common_failure_callback_t failure);
......
...@@ -43,7 +43,8 @@ int decode_attach_request(attach_request_msg *attach_request, uint8_t *buffer, u ...@@ -43,7 +43,8 @@ int decode_attach_request(attach_request_msg *attach_request, uint8_t *buffer, u
int decoded_result = 0; int decoded_result = 0;
LOG_FUNC_IN; LOG_FUNC_IN;
LOG_TRACE(INFO, "EMM - attach_request len = %d",
len);
// Check if we got a NULL pointer and if buffer length is >= minimum length expected for the message. // Check if we got a NULL pointer and if buffer length is >= minimum length expected for the message.
CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, ATTACH_REQUEST_MINIMUM_LENGTH, len); CHECK_PDU_POINTER_AND_LENGTH_DECODER(buffer, ATTACH_REQUEST_MINIMUM_LENGTH, len);
......
...@@ -2037,8 +2037,6 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg, ...@@ -2037,8 +2037,6 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg,
as_msg->selected_encryption_algorithm = htons(0x8000 >> emm_security_context->selected_algorithms.encryption); as_msg->selected_encryption_algorithm = htons(0x8000 >> emm_security_context->selected_algorithms.encryption);
as_msg->selected_integrity_algorithm = htons(0x8000 >> emm_security_context->selected_algorithms.integrity); as_msg->selected_integrity_algorithm = htons(0x8000 >> emm_security_context->selected_algorithms.integrity);
//as_msg->selected_encryption_algorithm = htons(0x8000 >> emm_security_context->capability.encryption);
//as_msg->selected_integrity_algorithm = htons(0x8000 >> emm_security_context->capability.integrity);
LOG_TRACE(DEBUG, LOG_TRACE(DEBUG,
"Set nas_msg.selected_encryption_algorithm -> NBO: 0x%04X (%u)", "Set nas_msg.selected_encryption_algorithm -> NBO: 0x%04X (%u)",
......
...@@ -123,6 +123,12 @@ typedef struct { ...@@ -123,6 +123,12 @@ 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 */
UInt8_t uea; /* Replayed UMTS encryption algorithms */
uint8_t ucs2;
UInt8_t uia; /* Replayed UMTS integrity algorithms */
UInt8_t gea; /* Replayed GPRS encryption algorithms */
UInt8_t umts_present;
UInt8_t gprs_present;
// Added by LG // Added by LG
UInt8_t selected_eea; /* Selected EPS encryption algorithms */ UInt8_t selected_eea; /* Selected EPS encryption algorithms */
......
...@@ -624,7 +624,20 @@ int emm_recv_attach_request(unsigned int ueid, const attach_request_msg *msg, ...@@ -624,7 +624,20 @@ int emm_recv_attach_request(unsigned int ueid, const attach_request_msg *msg,
msg->naskeysetidentifier.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED, msg->naskeysetidentifier.tsc != NAS_KEY_SET_IDENTIFIER_MAPPED,
msg->naskeysetidentifier.naskeysetidentifier, msg->naskeysetidentifier.naskeysetidentifier,
msg->oldgutitype != GUTI_MAPPED, p_guti, p_imsi, p_imei, p_tai, msg->oldgutitype != GUTI_MAPPED, p_guti, p_imsi, p_imei, p_tai,
msg->uenetworkcapability.eea, msg->uenetworkcapability.eia, msg->uenetworkcapability.eea,
msg->uenetworkcapability.eia,
msg->uenetworkcapability.ucs2,
msg->uenetworkcapability.uea,
msg->uenetworkcapability.uia,
0x00 |
//((msg->uenetworkcapability.spare & 0x7) << 5) | // spare coded as zero
((msg->uenetworkcapability.csfb & 0x1) << 4) |
((msg->uenetworkcapability.lpp & 0x1) << 3) |
((msg->uenetworkcapability.lcs & 0x1) << 2) |
((msg->uenetworkcapability.srvcc & 0x1) << 1) |
(msg->uenetworkcapability.nf & 0x1),
msg->uenetworkcapability.umts_present,
msg->uenetworkcapability.gprs_present,
&msg->esmmessagecontainer.esmmessagecontainercontents); &msg->esmmessagecontainer.esmmessagecontainercontents);
LOG_FUNC_RETURN (rc); LOG_FUNC_RETURN (rc);
......
...@@ -1244,10 +1244,12 @@ int emm_send_security_mode_command(const emm_as_security_t *msg, ...@@ -1244,10 +1244,12 @@ int emm_send_security_mode_command(const emm_as_security_t *msg,
size += UE_SECURITY_CAPABILITY_MAXIMUM_LENGTH; size += UE_SECURITY_CAPABILITY_MAXIMUM_LENGTH;
emm_msg->replayeduesecuritycapabilities.eea = msg->eea; emm_msg->replayeduesecuritycapabilities.eea = msg->eea;
emm_msg->replayeduesecuritycapabilities.eia = msg->eia; emm_msg->replayeduesecuritycapabilities.eia = msg->eia;
emm_msg->replayeduesecuritycapabilities.non_eps_security_present = 0; emm_msg->replayeduesecuritycapabilities.umts_present = msg->umts_present;
emm_msg->replayeduesecuritycapabilities.uea = 0x00; emm_msg->replayeduesecuritycapabilities.gprs_present = msg->gprs_present;
emm_msg->replayeduesecuritycapabilities.uia = 0x00;
emm_msg->replayeduesecuritycapabilities.gea = 0x00; emm_msg->replayeduesecuritycapabilities.uea = msg->uea;
emm_msg->replayeduesecuritycapabilities.uia = msg->uia;
emm_msg->replayeduesecuritycapabilities.gea = msg->gea;
LOG_FUNC_RETURN (size); LOG_FUNC_RETURN (size);
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "TLVEncoder.h" #include "TLVEncoder.h"
...@@ -46,6 +47,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8 ...@@ -46,6 +47,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8
} }
DECODE_U8(buffer + decoded, ielen, decoded); DECODE_U8(buffer + decoded, ielen, decoded);
memset(uenetworkcapability, 0, sizeof(UeNetworkCapability));
LOG_TRACE(INFO, "decode_ue_network_capability len = %d",ielen); LOG_TRACE(INFO, "decode_ue_network_capability len = %d",ielen);
CHECK_LENGTH_DECODER(len - decoded, ielen); CHECK_LENGTH_DECODER(len - decoded, ielen);
uenetworkcapability->eea = *(buffer + decoded); uenetworkcapability->eea = *(buffer + decoded);
...@@ -62,6 +65,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8 ...@@ -62,6 +65,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8
uenetworkcapability->ucs2 = (*(buffer + decoded) >> 7) & 0x1; uenetworkcapability->ucs2 = (*(buffer + decoded) >> 7) & 0x1;
uenetworkcapability->uia = *(buffer + decoded) & 0x7f; uenetworkcapability->uia = *(buffer + decoded) & 0x7f;
decoded++; decoded++;
uenetworkcapability->umts_present =1;
LOG_TRACE(INFO, "uenetworkcapability decoded UMTS\n");
if (ielen > 4) { if (ielen > 4) {
uenetworkcapability->spare = (*(buffer + decoded) >> 5) & 0x7; uenetworkcapability->spare = (*(buffer + decoded) >> 5) & 0x7;
...@@ -71,6 +76,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8 ...@@ -71,6 +76,8 @@ int decode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8
uenetworkcapability->srvcc = (*(buffer + decoded) >> 1) & 0x1; uenetworkcapability->srvcc = (*(buffer + decoded) >> 1) & 0x1;
uenetworkcapability->nf = *(buffer + decoded) & 0x1; uenetworkcapability->nf = *(buffer + decoded) & 0x1;
decoded++; decoded++;
uenetworkcapability->gprs_present =1;
LOG_TRACE(INFO, "uenetworkcapability decoded GPRS\n");
} }
} }
} }
...@@ -106,20 +113,28 @@ int encode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8 ...@@ -106,20 +113,28 @@ int encode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8
encoded++; encoded++;
*(buffer + encoded) = uenetworkcapability->eia; *(buffer + encoded) = uenetworkcapability->eia;
encoded++; encoded++;
*(buffer + encoded) = uenetworkcapability->uea; LOG_TRACE(INFO, "uenetworkcapability encoded EPS %u\n", encoded);
encoded++;
*(buffer + encoded) = 0x00 | ((uenetworkcapability->ucs2 & 0x1) << 7) |
(uenetworkcapability->uia & 0x7f);
encoded++;
*(buffer + encoded) = 0x00 | if (uenetworkcapability->umts_present) {
//((uenetworkcapability->spare & 0x7) << 5) | // spare coded as zero *(buffer + encoded) = uenetworkcapability->uea;
((uenetworkcapability->csfb & 0x1) << 4) | encoded++;
((uenetworkcapability->lpp & 0x1) << 3) | *(buffer + encoded) = 0x00 | ((uenetworkcapability->ucs2 & 0x1) << 7) |
((uenetworkcapability->lcs & 0x1) << 2) | (uenetworkcapability->uia & 0x7f);
((uenetworkcapability->srvcc & 0x1) << 1) | encoded++;
(uenetworkcapability->nf & 0x1); LOG_TRACE(INFO, "uenetworkcapability encoded UMTS %u\n", encoded);
encoded++; }
if (uenetworkcapability->gprs_present) {
*(buffer + encoded) = 0x00 |
//((uenetworkcapability->spare & 0x7) << 5) | // spare coded as zero
((uenetworkcapability->csfb & 0x1) << 4) |
((uenetworkcapability->lpp & 0x1) << 3) |
((uenetworkcapability->lcs & 0x1) << 2) |
((uenetworkcapability->srvcc & 0x1) << 1) |
(uenetworkcapability->nf & 0x1);
encoded++;
LOG_TRACE(INFO, "uenetworkcapability encoded GPRS %u\n", encoded);
}
*lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0); *lenPtr = encoded - 1 - ((iei > 0) ? 1 : 0);
return encoded; return encoded;
...@@ -142,6 +157,8 @@ void dump_ue_network_capability_xml(UeNetworkCapability *uenetworkcapability, ui ...@@ -142,6 +157,8 @@ void dump_ue_network_capability_xml(UeNetworkCapability *uenetworkcapability, ui
printf(" <LCS>%u</LCS>\n", uenetworkcapability->lcs); printf(" <LCS>%u</LCS>\n", uenetworkcapability->lcs);
printf(" <SR VCC>%u</SR VCC>\n", uenetworkcapability->srvcc); printf(" <SR VCC>%u</SR VCC>\n", uenetworkcapability->srvcc);
printf(" <NF>%u<NF/>\n", uenetworkcapability->nf); printf(" <NF>%u<NF/>\n", uenetworkcapability->nf);
printf(" <UMTS>%u<UMTS/>\n", uenetworkcapability->umts_present);
printf(" <GPRS>%u<GPRS/>\n", uenetworkcapability->gprs_present);
printf("</Ue Network Capability>\n"); printf("</Ue Network Capability>\n");
} }
...@@ -99,6 +99,9 @@ typedef struct UeNetworkCapability_tag { ...@@ -99,6 +99,9 @@ typedef struct UeNetworkCapability_tag {
/* NF notification procedure capability */ /* NF notification procedure capability */
#define UE_NETWORK_CAPABILITY_NF 1 #define UE_NETWORK_CAPABILITY_NF 1
uint8_t nf:1; uint8_t nf:1;
uint8_t umts_present;
uint8_t gprs_present;
} UeNetworkCapability; } UeNetworkCapability;
int encode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8_t iei, uint8_t *buffer, uint32_t len); int encode_ue_network_capability(UeNetworkCapability *uenetworkcapability, uint8_t iei, uint8_t *buffer, uint32_t len);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "TLVEncoder.h" #include "TLVEncoder.h"
...@@ -44,6 +45,7 @@ int decode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui ...@@ -44,6 +45,7 @@ int decode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui
CHECK_IEI_DECODER(iei, *buffer); CHECK_IEI_DECODER(iei, *buffer);
decoded++; decoded++;
} }
memset(uesecuritycapability, 0, sizeof(UeSecurityCapability));
ielen = *(buffer + decoded); ielen = *(buffer + decoded);
decoded++; decoded++;
CHECK_LENGTH_DECODER(len - decoded, ielen); CHECK_LENGTH_DECODER(len - decoded, ielen);
...@@ -51,14 +53,17 @@ int decode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui ...@@ -51,14 +53,17 @@ int decode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui
decoded++; decoded++;
uesecuritycapability->eia = *(buffer + decoded); uesecuritycapability->eia = *(buffer + decoded);
decoded++; decoded++;
if (len == decoded + 3) { if (len >= decoded + 3) {
uesecuritycapability->non_eps_security_present = 1; uesecuritycapability->umts_present = 1;
uesecuritycapability->uea = *(buffer + decoded); uesecuritycapability->uea = *(buffer + decoded);
decoded++; decoded++;
uesecuritycapability->uia = *(buffer + decoded) & 0x7f; uesecuritycapability->uia = *(buffer + decoded) & 0x7f;
decoded++; decoded++;
uesecuritycapability->gea = *(buffer + decoded) & 0x7f; if (len == decoded + 4) {
decoded++; uesecuritycapability->gprs_present = 1;
uesecuritycapability->gea = *(buffer + decoded) & 0x7f;
decoded++;
}
} }
#if defined (NAS_DEBUG) #if defined (NAS_DEBUG)
dump_ue_security_capability_xml(uesecuritycapability, iei); dump_ue_security_capability_xml(uesecuritycapability, iei);
...@@ -85,12 +90,14 @@ int encode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui ...@@ -85,12 +90,14 @@ int encode_ue_security_capability(UeSecurityCapability *uesecuritycapability, ui
encoded++; encoded++;
*(buffer + encoded) = uesecuritycapability->eia; *(buffer + encoded) = uesecuritycapability->eia;
encoded++; encoded++;
if (uesecuritycapability->non_eps_security_present == 1) { if (uesecuritycapability->umts_present) {
*(buffer + encoded) = uesecuritycapability->uea; *(buffer + encoded) = uesecuritycapability->uea;
encoded++; encoded++;
*(buffer + encoded) = 0x00 | *(buffer + encoded) = 0x00 |
(uesecuritycapability->uia & 0x7f); (uesecuritycapability->uia & 0x7f);
encoded++; encoded++;
}
if (uesecuritycapability->gprs_present) {
*(buffer + encoded) = 0x00 | *(buffer + encoded) = 0x00 |
(uesecuritycapability->gea & 0x7f); (uesecuritycapability->gea & 0x7f);
encoded++; encoded++;
...@@ -107,9 +114,11 @@ void dump_ue_security_capability_xml(UeSecurityCapability *uesecuritycapability, ...@@ -107,9 +114,11 @@ void dump_ue_security_capability_xml(UeSecurityCapability *uesecuritycapability,
printf(" <IEI>0x%X</IEI>\n", iei); printf(" <IEI>0x%X</IEI>\n", iei);
printf(" <EEA>%u</EEA>\n", uesecuritycapability->eea); printf(" <EEA>%u</EEA>\n", uesecuritycapability->eea);
printf(" <EIA>%u</EIA>\n", uesecuritycapability->eia); printf(" <EIA>%u</EIA>\n", uesecuritycapability->eia);
if (uesecuritycapability->non_eps_security_present == 1) { if (uesecuritycapability->umts_present == 1) {
printf(" <UEA>%u</UEA>\n", uesecuritycapability->uea); printf(" <UEA>%u</UEA>\n", uesecuritycapability->uea);
printf(" <UIA>%u</UIA>\n", uesecuritycapability->uia); printf(" <UIA>%u</UIA>\n", uesecuritycapability->uia);
}
if (uesecuritycapability->gprs_present == 1) {
printf(" <GEA>%u</GEA>\n", uesecuritycapability->gea); printf(" <GEA>%u</GEA>\n", uesecuritycapability->gea);
} }
printf("</Ue Security Capability>\n"); printf("</Ue Security Capability>\n");
......
...@@ -59,7 +59,8 @@ typedef struct UeSecurityCapability_tag { ...@@ -59,7 +59,8 @@ typedef struct UeSecurityCapability_tag {
#define UE_SECURITY_CAPABILITY_EIA6 0b00000010 #define UE_SECURITY_CAPABILITY_EIA6 0b00000010
#define UE_SECURITY_CAPABILITY_EIA7 0b00000001 #define UE_SECURITY_CAPABILITY_EIA7 0b00000001
uint8_t eia; uint8_t eia;
unsigned non_eps_security_present:1; uint8_t umts_present;
uint8_t gprs_present;
/* UMTS encryption algorithms supported (octet 5) */ /* UMTS encryption algorithms supported (octet 5) */
#define UE_SECURITY_CAPABILITY_UEA0 0b10000000 #define UE_SECURITY_CAPABILITY_UEA0 0b10000000
#define UE_SECURITY_CAPABILITY_UEA1 0b01000000 #define UE_SECURITY_CAPABILITY_UEA1 0b01000000
......
...@@ -281,7 +281,6 @@ int sgi_init(const pgw_config_t *pgw_config_p) ...@@ -281,7 +281,6 @@ int sgi_init(const pgw_config_t *pgw_config_p)
return -1; return -1;
} }
#endif #endif
#if 0
#ifdef ENABLE_USE_RAW_SOCKET_FOR_SGI #ifdef ENABLE_USE_RAW_SOCKET_FOR_SGI
for (i=0; i < SGI_MAX_EPS_BEARERS_PER_USER; i++) { for (i=0; i < SGI_MAX_EPS_BEARERS_PER_USER; i++) {
sgi_read_thread_args_t *args_p = malloc(sizeof(sgi_read_thread_args_t)); sgi_read_thread_args_t *args_p = malloc(sizeof(sgi_read_thread_args_t));
...@@ -292,7 +291,6 @@ int sgi_init(const pgw_config_t *pgw_config_p) ...@@ -292,7 +291,6 @@ int sgi_init(const pgw_config_t *pgw_config_p)
return -1; return -1;
} }
} }
#endif
#endif #endif
} }
......
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