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
This commit is contained in:
@@ -26,6 +26,9 @@ typedef struct mme_app_connection_establishment_cnf_s {
|
||||
pre_emp_capability_t bearer_qos_pre_emp_capability;
|
||||
ambr_t ambr;
|
||||
|
||||
/* Key eNB */
|
||||
uint8_t keNB[32];
|
||||
|
||||
nas_conn_est_cnf_t nas_conn_est_cnf;
|
||||
} mme_app_connection_establishment_cnf_t;
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ typedef struct nas_pdn_connectivity_rsp_s {
|
||||
uint32_t mme_ue_s1ap_id;
|
||||
|
||||
/* Key eNB */
|
||||
uint8_t keNB[32];
|
||||
//uint8_t keNB[32];
|
||||
|
||||
ambr_t ambr;
|
||||
ambr_t apn_ambr;
|
||||
|
||||
@@ -289,6 +289,7 @@ mme_app_handle_conn_est_cnf(
|
||||
mme_app_connection_establishment_cnf_t *establishment_cnf_p = NULL;
|
||||
bearer_context_t *current_bearer_p = NULL;
|
||||
ebi_t bearer_id = 0;
|
||||
uint8_t *keNB = NULL;
|
||||
|
||||
MME_APP_DEBUG("Received NAS_CONNECTION_ESTABLISHMENT_CNF from NAS\n");
|
||||
|
||||
@@ -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->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);
|
||||
}
|
||||
|
||||
@@ -471,17 +477,18 @@ mme_app_handle_create_sess_resp(
|
||||
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);
|
||||
memset((void*)&message_p->ittiMsg.nas_pdn_connectivity_rsp,
|
||||
0,
|
||||
sizeof(nas_pdn_connectivity_rsp_t));
|
||||
|
||||
derive_keNB(ue_context_p->vector_in_use->kasme, 156, &keNB);
|
||||
memcpy(NAS_PDN_CONNECTIVITY_RSP(message_p).keNB, keNB, 32);
|
||||
// moved to NAS_CONNECTION_ESTABLISHMENT_CONF, keNB not handled in NAS MME
|
||||
//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).ue_id = ue_context_p->pending_pdn_connectivity_req_ue_id; // NAS internal ref
|
||||
|
||||
@@ -17,7 +17,7 @@ SRCDIR = $(PROJDIR)/src
|
||||
INCDIR = $(SRCDIR)/include
|
||||
UTILDIR = $(SRCDIR)/util
|
||||
APIDIR = $(SRCDIR)/api
|
||||
USERAPIDIR = $(APIDIR)/user
|
||||
USERAPIDIR = $(APIDIR)/user
|
||||
NETAPIDIR = $(APIDIR)/network
|
||||
USIMAPIDIR = $(APIDIR)/usim
|
||||
MMEAPIDIR = $(APIDIR)/mme
|
||||
|
||||
@@ -31,6 +31,7 @@ Description Defines the layer 3 messages supported by the NAS sublayer
|
||||
#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
|
||||
# include "nas_itti_messaging.h"
|
||||
#endif
|
||||
#include "secu_defs.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
@@ -40,34 +41,55 @@ Description Defines the layer 3 messages supported by the NAS sublayer
|
||||
/******************* L O C A L D E F I N I T I O N S *******************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
/* Functions used to decode layer 3 NAS messages */
|
||||
static int _nas_message_header_decode(const char* buffer,
|
||||
nas_message_security_header_t* header, int length);
|
||||
nas_message_security_header_t* header, int length);
|
||||
static int _nas_message_plain_decode(const char* buffer,
|
||||
const nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length);
|
||||
const nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length);
|
||||
static int _nas_message_protected_decode(const char* buffer,
|
||||
nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length);
|
||||
nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length);
|
||||
|
||||
/* Functions used to encode layer 3 NAS messages */
|
||||
static int _nas_message_header_encode(char* buffer,
|
||||
const nas_message_security_header_t* header, int length);
|
||||
const nas_message_security_header_t* header, int length);
|
||||
static int _nas_message_plain_encode(char* buffer,
|
||||
const nas_message_security_header_t* header,
|
||||
const nas_message_plain_t* msg, int length);
|
||||
static int _nas_message_protected_encode(char* buffer,
|
||||
const nas_message_security_protected_t* msg, int length);
|
||||
const nas_message_security_header_t* header,
|
||||
const nas_message_plain_t* msg, int length);
|
||||
|
||||
static int _nas_message_protected_encode(
|
||||
char *buffer,
|
||||
const nas_message_security_protected_t *msg,
|
||||
int length,
|
||||
void *security);
|
||||
|
||||
/* Functions used to decrypt and encrypt layer 3 NAS messages */
|
||||
static int _nas_message_decrypt(char* dest, const char* src, UInt8_t type,
|
||||
UInt32_t code, UInt8_t seq, int length);
|
||||
static int _nas_message_encrypt(char* dest, const char* src, UInt8_t type,
|
||||
UInt32_t code, UInt8_t seq, int length);
|
||||
static int _nas_message_decrypt(
|
||||
char* dest,
|
||||
const char* src,
|
||||
UInt8_t type,
|
||||
UInt32_t code,
|
||||
UInt8_t seq,
|
||||
int length);
|
||||
|
||||
static int
|
||||
_nas_message_encrypt(
|
||||
char *dest,
|
||||
const char *src,
|
||||
UInt8_t type,
|
||||
UInt32_t code,
|
||||
UInt8_t seq,
|
||||
int length,
|
||||
const emm_security_context_t * const emm_security_context);
|
||||
|
||||
/* Functions used for integrity protection of layer 3 NAS messages */
|
||||
static UInt32_t _nas_message_get_mac(const char* buffer, UInt32_t count,
|
||||
int length);
|
||||
static UInt32_t _nas_message_get_mac(
|
||||
const char * const buffer,
|
||||
int const length,
|
||||
int const direction,
|
||||
const emm_security_context_t * const emm_security_context);
|
||||
|
||||
/****************************************************************************/
|
||||
/****************** E X P O R T E D F U N C T I O N S ******************/
|
||||
@@ -93,48 +115,60 @@ static UInt32_t _nas_message_get_mac(const char* buffer, UInt32_t count,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int nas_message_encrypt(const char* inbuf, char* outbuf,
|
||||
const nas_message_security_header_t* header, int length)
|
||||
int
|
||||
nas_message_encrypt(
|
||||
const char *inbuf,
|
||||
char *outbuf,
|
||||
const nas_message_security_header_t *header,
|
||||
int length,
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
int bytes = length;
|
||||
|
||||
/* Encode the header */
|
||||
int size = _nas_message_header_encode(outbuf, header, length);
|
||||
|
||||
if (size < 0) {
|
||||
LOG_FUNC_RETURN (TLV_ENCODE_BUFFER_TOO_SHORT);
|
||||
LOG_FUNC_RETURN (TLV_ENCODE_BUFFER_TOO_SHORT);
|
||||
}
|
||||
else if (size > 1) {
|
||||
/* Encrypt the plain NAS message */
|
||||
bytes = _nas_message_encrypt(outbuf + size, inbuf,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number,
|
||||
length - size);
|
||||
/* Integrity protected the NAS message */
|
||||
if (bytes > 0) {
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(outbuf + offset,
|
||||
0, // TODO !!! ul counter
|
||||
length - offset);
|
||||
/* Set the message authentication code of the NAS message */
|
||||
*(UInt32_t*)(outbuf + sizeof(UInt8_t)) = mac;
|
||||
}
|
||||
/* Encrypt the plain NAS message */
|
||||
bytes = _nas_message_encrypt(outbuf + size, inbuf,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number,
|
||||
length - size,
|
||||
emm_security_context);
|
||||
/* Integrity protected the NAS message */
|
||||
if (bytes > 0) {
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(
|
||||
outbuf + offset,
|
||||
length - offset,
|
||||
#ifdef NAS_MME
|
||||
SECU_DIRECTION_DOWNLINK,
|
||||
#else
|
||||
SECU_DIRECTION_UPLINK,
|
||||
#endif
|
||||
emm_security_context);
|
||||
/* Set the message authentication code of the NAS message */
|
||||
*(UInt32_t*)(outbuf + sizeof(UInt8_t)) = mac;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* The input buffer does not need to be encrypted */
|
||||
memcpy(outbuf, inbuf, length);
|
||||
/* The input buffer does not need to be encrypted */
|
||||
memcpy(outbuf, inbuf, length);
|
||||
}
|
||||
|
||||
if (bytes < 0) {
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
}
|
||||
if (size > 1) {
|
||||
LOG_FUNC_RETURN (size + bytes);
|
||||
LOG_FUNC_RETURN (size + bytes);
|
||||
}
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
}
|
||||
@@ -159,43 +193,54 @@ int nas_message_encrypt(const char* inbuf, char* outbuf,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int nas_message_decrypt(const char* inbuf, char* outbuf,
|
||||
nas_message_security_header_t* header, int length)
|
||||
int nas_message_decrypt(
|
||||
const char *inbuf,
|
||||
char *outbuf,
|
||||
nas_message_security_header_t *header,
|
||||
int length,
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int bytes = length;
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
int bytes = length;
|
||||
|
||||
/* Decode the header */
|
||||
int size = _nas_message_header_decode(inbuf, header, length);
|
||||
|
||||
if (size < 0) {
|
||||
LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
|
||||
LOG_FUNC_RETURN (TLV_DECODE_BUFFER_TOO_SHORT);
|
||||
}
|
||||
else if (size > 1) {
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(inbuf + offset,
|
||||
0, // TODO !!! dl counter
|
||||
length - offset);
|
||||
/* Check NAS message integrity */
|
||||
if (mac != header->message_authentication_code) {
|
||||
LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
|
||||
}
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(
|
||||
inbuf + offset,
|
||||
length - offset,
|
||||
#ifdef NAS_MME
|
||||
SECU_DIRECTION_UPLINK,
|
||||
#else
|
||||
SECU_DIRECTION_DOWNLINK,
|
||||
#endif
|
||||
emm_security_context);
|
||||
/* Check NAS message integrity */
|
||||
if (mac != header->message_authentication_code) {
|
||||
LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
|
||||
}
|
||||
|
||||
/* Decrypt the security protected NAS message */
|
||||
header->protocol_discriminator =
|
||||
_nas_message_decrypt(outbuf, inbuf + size,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number,
|
||||
length - size);
|
||||
bytes = length - size;
|
||||
/* Decrypt the security protected NAS message */
|
||||
header->protocol_discriminator =
|
||||
_nas_message_decrypt(outbuf, inbuf + size,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number,
|
||||
length - size);
|
||||
bytes = length - size;
|
||||
}
|
||||
else {
|
||||
/* The input buffer contains a plain NAS message */
|
||||
memcpy(outbuf, inbuf, length);
|
||||
/* The input buffer contains a plain NAS message */
|
||||
memcpy(outbuf, inbuf, length);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
@@ -219,10 +264,14 @@ int nas_message_decrypt(const char* inbuf, char* outbuf,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int nas_message_decode(const char* const buffer, nas_message_t* msg, int length)
|
||||
int nas_message_decode(
|
||||
const char* const buffer,
|
||||
nas_message_t *msg,
|
||||
int length,
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
int bytes;
|
||||
#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
|
||||
int down_link;
|
||||
@@ -244,9 +293,17 @@ int nas_message_decode(const char* const buffer, nas_message_t* msg, int length)
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(buffer + offset,
|
||||
0, // TODO !!! dl counter
|
||||
length - offset);
|
||||
UInt32_t mac = _nas_message_get_mac(
|
||||
buffer + offset,
|
||||
length - offset,
|
||||
#ifdef NAS_MME
|
||||
SECU_DIRECTION_UPLINK,
|
||||
#else
|
||||
SECU_DIRECTION_DOWNLINK,
|
||||
#endif
|
||||
emm_security_context
|
||||
);
|
||||
|
||||
/* Check NAS message integrity */
|
||||
if (mac != msg->header.message_authentication_code) {
|
||||
LOG_FUNC_RETURN (TLV_DECODE_MAC_MISMATCH);
|
||||
@@ -292,10 +349,15 @@ int nas_message_decode(const char* const buffer, nas_message_t* msg, int length)
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int nas_message_encode(char* buffer, const nas_message_t* const msg, int length)
|
||||
int nas_message_encode(
|
||||
char *buffer,
|
||||
const nas_message_t *const msg,
|
||||
int length,
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
int bytes;
|
||||
#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
|
||||
int down_link;
|
||||
@@ -315,18 +377,47 @@ int nas_message_encode(char* buffer, const nas_message_t* const msg, int length)
|
||||
}
|
||||
else if (size > 1) {
|
||||
/* Encode security protected NAS message */
|
||||
bytes = _nas_message_protected_encode(buffer + size, &msg->security_protected,
|
||||
length - size);
|
||||
bytes = _nas_message_protected_encode(
|
||||
buffer + size,
|
||||
&msg->security_protected,
|
||||
length - size,
|
||||
emm_security_context);
|
||||
/* Integrity protect the NAS message */
|
||||
if (bytes > 0) {
|
||||
/* Compute offset of the sequence number field */
|
||||
int offset = size - sizeof(UInt8_t);
|
||||
/* Compute the NAS message authentication code */
|
||||
UInt32_t mac = _nas_message_get_mac(buffer + offset,
|
||||
0, // TODO !!! ul counter
|
||||
length - offset);
|
||||
UInt32_t mac = _nas_message_get_mac(
|
||||
buffer + offset,
|
||||
length - offset,
|
||||
#ifdef NAS_MME
|
||||
SECU_DIRECTION_DOWNLINK,
|
||||
#else
|
||||
SECU_DIRECTION_UPLINK,
|
||||
#endif
|
||||
emm_security_context);
|
||||
/* Set the message authentication code of the NAS message */
|
||||
*(UInt32_t*)(buffer + sizeof(UInt8_t)) = mac;
|
||||
|
||||
if (emm_security_context) {
|
||||
#ifdef NAS_MME
|
||||
emm_security_context->dl_count.seq_num += 1;
|
||||
if ( ! emm_security_context->dl_count.seq_num) {
|
||||
emm_security_context->dl_count.overflow += 1;
|
||||
if ( ! emm_security_context->dl_count.overflow) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
#else
|
||||
emm_security_context->ul_count.seq_num += 1;
|
||||
if ( ! emm_security_context->ul_count.seq_num) {
|
||||
emm_security_context->ul_count.overflow += 1;
|
||||
if ( ! emm_security_context->ul_count.overflow) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if ((defined(EPC_BUILD) && defined(NAS_MME)) || (defined(ENABLE_NAS_UE_LOGGING) && defined(UE_BUILD) && defined(NAS_UE)))
|
||||
/* Log message header */
|
||||
@@ -377,9 +468,11 @@ int nas_message_encode(char* buffer, const nas_message_t* const msg, int length)
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_header_decode(const char* buffer,
|
||||
nas_message_security_header_t* header,
|
||||
int length)
|
||||
static int
|
||||
_nas_message_header_decode(
|
||||
const char *buffer,
|
||||
nas_message_security_header_t *header,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -393,11 +486,11 @@ static int _nas_message_header_decode(const char* buffer,
|
||||
if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED)
|
||||
{
|
||||
if (length < NAS_MESSAGE_SECURITY_HEADER_SIZE) {
|
||||
/* The buffer is not big enough to contain security header */
|
||||
LOG_TRACE(WARNING, "NET-API - The size of the header (%u) "
|
||||
"exceeds the buffer length (%u)",
|
||||
NAS_MESSAGE_SECURITY_HEADER_SIZE, length);
|
||||
LOG_FUNC_RETURN (-1);
|
||||
/* The buffer is not big enough to contain security header */
|
||||
LOG_TRACE(WARNING, "NET-API - The size of the header (%u) "
|
||||
"exceeds the buffer length (%u)",
|
||||
NAS_MESSAGE_SECURITY_HEADER_SIZE, length);
|
||||
LOG_FUNC_RETURN (-1);
|
||||
}
|
||||
/* Decode the message authentication code */
|
||||
DECODE_U32(buffer+size, header->message_authentication_code, size);
|
||||
@@ -428,26 +521,29 @@ static int _nas_message_header_decode(const char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_plain_decode(const char* buffer,
|
||||
const nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length)
|
||||
static int
|
||||
_nas_message_plain_decode(
|
||||
const char *buffer,
|
||||
const nas_message_security_header_t *header,
|
||||
nas_message_plain_t *msg,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int bytes = TLV_DECODE_PROTOCOL_NOT_SUPPORTED;
|
||||
|
||||
if (header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
|
||||
/* Decode EPS Mobility Management L3 message */
|
||||
bytes = emm_msg_decode(&msg->emm, (uint8_t *)buffer, length);
|
||||
/* Decode EPS Mobility Management L3 message */
|
||||
bytes = emm_msg_decode(&msg->emm, (uint8_t *)buffer, length);
|
||||
}
|
||||
else if (header->protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
|
||||
/* Decode EPS Session Management L3 message */
|
||||
bytes = esm_msg_decode(&msg->esm, (uint8_t *)buffer, length);
|
||||
/* Decode EPS Session Management L3 message */
|
||||
bytes = esm_msg_decode(&msg->esm, (uint8_t *)buffer, length);
|
||||
}
|
||||
else {
|
||||
/* Discard L3 messages with not supported protocol discriminator */
|
||||
LOG_TRACE(WARNING,"NET-API - Protocol discriminator 0x%x is "
|
||||
"not supported", header->protocol_discriminator);
|
||||
/* Discard L3 messages with not supported protocol discriminator */
|
||||
LOG_TRACE(WARNING,"NET-API - Protocol discriminator 0x%x is "
|
||||
"not supported", header->protocol_discriminator);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
@@ -473,9 +569,11 @@ static int _nas_message_plain_decode(const char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_protected_decode(const char* buffer,
|
||||
nas_message_security_header_t* header,
|
||||
nas_message_plain_t* msg, int length)
|
||||
static int _nas_message_protected_decode(
|
||||
const char *buffer,
|
||||
nas_message_security_header_t *header,
|
||||
nas_message_plain_t *msg,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -484,15 +582,15 @@ static int _nas_message_protected_decode(const char* buffer,
|
||||
char* plain_msg = (char*)malloc(length);
|
||||
if (plain_msg)
|
||||
{
|
||||
/* Decrypt the security protected NAS message */
|
||||
header->protocol_discriminator =
|
||||
_nas_message_decrypt(plain_msg, buffer,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number, length);
|
||||
/* Decode the decrypted message as plain NAS message */
|
||||
bytes = _nas_message_plain_decode(plain_msg, header, msg, length);
|
||||
free(plain_msg);
|
||||
/* Decrypt the security protected NAS message */
|
||||
header->protocol_discriminator =
|
||||
_nas_message_decrypt(plain_msg, buffer,
|
||||
header->security_header_type,
|
||||
header->message_authentication_code,
|
||||
header->sequence_number, length);
|
||||
/* Decode the decrypted message as plain NAS message */
|
||||
bytes = _nas_message_plain_decode(plain_msg, header, msg, length);
|
||||
free(plain_msg);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
@@ -523,8 +621,10 @@ static int _nas_message_protected_decode(const char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_header_encode(char* buffer,
|
||||
const nas_message_security_header_t* header, int length)
|
||||
static int _nas_message_header_encode(
|
||||
char *buffer,
|
||||
const nas_message_security_header_t *header,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -576,26 +676,28 @@ static int _nas_message_header_encode(char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_plain_encode(char* buffer,
|
||||
const nas_message_security_header_t* header,
|
||||
const nas_message_plain_t* msg, int length)
|
||||
static int _nas_message_plain_encode(
|
||||
char *buffer,
|
||||
const nas_message_security_header_t *header,
|
||||
const nas_message_plain_t *msg,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int bytes = TLV_ENCODE_PROTOCOL_NOT_SUPPORTED;
|
||||
|
||||
if (header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
|
||||
/* Encode EPS Mobility Management L3 message */
|
||||
bytes = emm_msg_encode((EMM_msg*)(&msg->emm), (uint8_t*)buffer, length);
|
||||
/* Encode EPS Mobility Management L3 message */
|
||||
bytes = emm_msg_encode((EMM_msg*)(&msg->emm), (uint8_t*)buffer, length);
|
||||
}
|
||||
else if (header->protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
|
||||
/* Encode EPS Session Management L3 message */
|
||||
bytes = esm_msg_encode((ESM_msg*)(&msg->esm), (uint8_t*)buffer, length);
|
||||
/* Encode EPS Session Management L3 message */
|
||||
bytes = esm_msg_encode((ESM_msg*)(&msg->esm), (uint8_t*)buffer, length);
|
||||
}
|
||||
else {
|
||||
/* Discard L3 messages with not supported protocol discriminator */
|
||||
LOG_TRACE(WARNING,"NET-API - Protocol discriminator 0x%x is "
|
||||
"not supported", header->protocol_discriminator);
|
||||
/* Discard L3 messages with not supported protocol discriminator */
|
||||
LOG_TRACE(WARNING,"NET-API - Protocol discriminator 0x%x is "
|
||||
"not supported", header->protocol_discriminator);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
@@ -619,29 +721,36 @@ static int _nas_message_plain_encode(char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_protected_encode(char* buffer,
|
||||
const nas_message_security_protected_t* msg, int length)
|
||||
static int _nas_message_protected_encode(
|
||||
char *buffer,
|
||||
const nas_message_security_protected_t *msg,
|
||||
int length,
|
||||
void *security)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
emm_security_context_t *emm_security_context = (emm_security_context_t*)security;
|
||||
int bytes = TLV_ENCODE_BUFFER_TOO_SHORT;
|
||||
|
||||
char* plain_msg = (char*)malloc(length);
|
||||
if (plain_msg) {
|
||||
/* Encode the security protected NAS message as plain NAS message */
|
||||
int size = _nas_message_plain_encode(plain_msg, &msg->header,
|
||||
&msg->plain, length);
|
||||
if (size > 0) {
|
||||
//static uint8_t seq = 0;
|
||||
/* Encrypt the encoded plain NAS message */
|
||||
bytes = _nas_message_encrypt(buffer, plain_msg,
|
||||
msg->header.security_header_type,
|
||||
msg->header.message_authentication_code,
|
||||
msg->header.sequence_number, size);
|
||||
//seq, size);
|
||||
//seq ++;
|
||||
}
|
||||
free(plain_msg);
|
||||
/* Encode the security protected NAS message as plain NAS message */
|
||||
int size = _nas_message_plain_encode(plain_msg, &msg->header,
|
||||
&msg->plain, length);
|
||||
if (size > 0) {
|
||||
//static uint8_t seq = 0;
|
||||
/* Encrypt the encoded plain NAS message */
|
||||
bytes = _nas_message_encrypt(buffer,
|
||||
plain_msg,
|
||||
msg->header.security_header_type,
|
||||
msg->header.message_authentication_code,
|
||||
msg->header.sequence_number,
|
||||
size,
|
||||
emm_security_context);
|
||||
//seq, size);
|
||||
//seq ++;
|
||||
}
|
||||
free(plain_msg);
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN (bytes);
|
||||
@@ -672,8 +781,13 @@ static int _nas_message_protected_encode(char* buffer,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_decrypt(char* dest, const char* src, UInt8_t type,
|
||||
UInt32_t code, UInt8_t seq, int length)
|
||||
static int _nas_message_decrypt(
|
||||
char *dest,
|
||||
const char *src,
|
||||
UInt8_t type,
|
||||
UInt32_t code,
|
||||
UInt8_t seq,
|
||||
int length)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -710,8 +824,14 @@ static int _nas_message_decrypt(char* dest, const char* src, UInt8_t type,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _nas_message_encrypt(char* dest, const char* src, UInt8_t type,
|
||||
UInt32_t code, UInt8_t seq, int length)
|
||||
static int _nas_message_encrypt(
|
||||
char *dest,
|
||||
const char *src,
|
||||
UInt8_t type,
|
||||
UInt32_t code,
|
||||
UInt8_t seq,
|
||||
int length,
|
||||
const emm_security_context_t * const emm_security_context)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -748,17 +868,80 @@ static int _nas_message_encrypt(char* dest, const char* src, UInt8_t type,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static UInt32_t _nas_message_get_mac(const char* buffer, UInt32_t count,
|
||||
int length)
|
||||
static UInt32_t _nas_message_get_mac(
|
||||
const char * const buffer,
|
||||
int const length,
|
||||
int const direction,
|
||||
const emm_security_context_t * const emm_security_context)
|
||||
{
|
||||
|
||||
LOG_FUNC_IN;
|
||||
/* TODO: run integrity protection algorithm */
|
||||
/* TODO: Return the message authentication code */
|
||||
|
||||
if (!emm_security_context) {
|
||||
LOG_TRACE(DEBUG,
|
||||
"No security context set for integrity protection algorithm");
|
||||
#if defined(EPC_BUILD) || defined(UE_BUILD)
|
||||
LOG_FUNC_RETURN (0);
|
||||
LOG_FUNC_RETURN (0);
|
||||
#else
|
||||
LOG_FUNC_RETURN (0xabababab);
|
||||
LOG_FUNC_RETURN (0xabababab);
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (emm_security_context->selected_algorithms.integrity) {
|
||||
|
||||
case NAS_SECURITY_ALGORITHMS_EIA1:
|
||||
AssertFatal(0 ,
|
||||
"EIA1_128_ALG_ID not implemented");
|
||||
break;
|
||||
|
||||
case NAS_SECURITY_ALGORITHMS_EIA2: {
|
||||
UInt8_t mac[4];
|
||||
nas_stream_cipher_t stream_cipher;
|
||||
UInt32_t count;
|
||||
UInt32_t *mac32;
|
||||
|
||||
if (direction == SECU_DIRECTION_UPLINK) {
|
||||
count = 0x00000000 ||
|
||||
((emm_security_context->ul_count.overflow && 0x0000FFFF) << 8) ||
|
||||
(emm_security_context->ul_count.seq_num & 0x000000FF);
|
||||
} else {
|
||||
count = 0x00000000 ||
|
||||
((emm_security_context->dl_count.overflow && 0x0000FFFF) << 8) ||
|
||||
(emm_security_context->dl_count.seq_num & 0x000000FF);
|
||||
}
|
||||
stream_cipher.key = emm_security_context->knas_int.value;
|
||||
stream_cipher.key_length = AUTH_KNAS_INT_SIZE;
|
||||
stream_cipher.count = count;
|
||||
stream_cipher.bearer = 0x00; //33.401 section 8.1.1
|
||||
stream_cipher.direction = direction;
|
||||
stream_cipher.message = buffer;
|
||||
/* length in bits */
|
||||
stream_cipher.blength = length << 3;
|
||||
|
||||
nas_stream_encrypt_eia2(
|
||||
&stream_cipher,
|
||||
mac);
|
||||
LOG_TRACE(DEBUG,
|
||||
"NAS_SECURITY_ALGORITHMS_EIA2 returned MAC %x.%x.%x.%x for length %d direction %d, count %d",
|
||||
mac[0], mac[1], mac[2],mac[3], length, direction, count);
|
||||
mac32 = (UInt32_t*)&mac;
|
||||
LOG_FUNC_RETURN (*mac32);
|
||||
}break;
|
||||
|
||||
case NAS_SECURITY_ALGORITHMS_EIA0:
|
||||
#if defined(EPC_BUILD) || defined(UE_BUILD)
|
||||
LOG_FUNC_RETURN (0);
|
||||
#else
|
||||
LOG_FUNC_RETURN (0xabababab);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0 ,
|
||||
"Unknown integrity protection algorithm %d",
|
||||
emm_security_context->selected_algorithms.integrity);
|
||||
}
|
||||
LOG_FUNC_RETURN (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ Description Defines the layer 3 messages supported by the NAS sublayer
|
||||
|
||||
#include "commonDef.h"
|
||||
#include "emm_msg.h"
|
||||
#if defined(EPC_BUILD)
|
||||
#include "emmData.h"
|
||||
#endif
|
||||
#include "esm_msg.h"
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -78,14 +81,29 @@ typedef union {
|
||||
/****************** 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,
|
||||
const nas_message_security_header_t *header, int length);
|
||||
int nas_message_encrypt(
|
||||
const char *inbuf,
|
||||
char *outbuf,
|
||||
const nas_message_security_header_t *header,
|
||||
int length,
|
||||
void *security);
|
||||
|
||||
int nas_message_decrypt(const char *inbuf, char *outbuf,
|
||||
nas_message_security_header_t *header, int length);
|
||||
int nas_message_decrypt(const char *inbuf,
|
||||
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);
|
||||
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);
|
||||
int nas_message_encode(
|
||||
char *buffer,
|
||||
const nas_message_t * const msg,
|
||||
int length,
|
||||
void *security);
|
||||
|
||||
#endif /* __NAS_MESSAGE_H__*/
|
||||
|
||||
@@ -45,6 +45,8 @@ Description Defines the attach related EMM procedure executed by the
|
||||
#include "esm_sap.h"
|
||||
#include "emm_cause.h"
|
||||
|
||||
#include "NasSecurityAlgorithms.h"
|
||||
|
||||
#ifdef NAS_MME
|
||||
#include "mme_api.h"
|
||||
# if defined(EPC_BUILD)
|
||||
@@ -1133,6 +1135,17 @@ int emm_proc_attach_request(unsigned int ueid, emm_proc_attach_type_t type,
|
||||
#if defined(EPC_BUILD)
|
||||
emm_data_context_add(&_emm_data, *(emm_ctx));
|
||||
#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 */
|
||||
@@ -2040,6 +2053,8 @@ static int _emm_attach_security(void *args)
|
||||
if (emm_ctx->security) {
|
||||
memset(emm_ctx->security, 0, sizeof(emm_security_context_t));
|
||||
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 {
|
||||
LOG_TRACE(WARNING, "EMM-PROC - Failed to create security context");
|
||||
emm_ctx->emm_cause = EMM_CAUSE_ILLEGAL_UE;
|
||||
@@ -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,
|
||||
int eea, int eia)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
/* Emergency bearer services indicator */
|
||||
if ( (type == EMM_ATTACH_TYPE_EMERGENCY) != ctx->is_emergency) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
/* Security key set identifier */
|
||||
if (ksi != ctx->ksi) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
/* Supported EPS encryption algorithms */
|
||||
if (eea != ctx->eea) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
/* Supported EPS integrity algorithms */
|
||||
if (eia != ctx->eia) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
/* The GUTI if provided by the UE */
|
||||
if ( (guti) && (ctx->guti == NULL) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (guti == NULL) && (ctx->guti) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (guti) && (ctx->guti) ) {
|
||||
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 ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
}
|
||||
/* The IMSI if provided by the UE */
|
||||
if ( (imsi) && (ctx->imsi == NULL) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (imsi == NULL) && (ctx->imsi) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (imsi) && (ctx->imsi) ) {
|
||||
if ( memcmp(imsi, ctx->imsi, sizeof(imsi_t)) != 0 ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
}
|
||||
/* The IMEI if provided by the UE */
|
||||
if ( (imei) && (ctx->imei == NULL) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (imei == NULL) && (ctx->imei) ) {
|
||||
return (TRUE);
|
||||
LOG_FUNC_RETURN (TRUE);
|
||||
}
|
||||
if ( (imei) && (ctx->imei) ) {
|
||||
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,
|
||||
GUTI_t *guti, imsi_t *imsi, imei_t *imei,
|
||||
int eea, int eia, const OctetString *esm_msg)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
/* UE identifier */
|
||||
ctx->ueid = ueid;
|
||||
/* Emergency bearer services indicator */
|
||||
@@ -2414,7 +2431,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
|
||||
if (ctx->guti != NULL) {
|
||||
memcpy(ctx->guti, guti, sizeof(GUTI_t));
|
||||
} else {
|
||||
return (RETURNerror);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
} else {
|
||||
if (ctx->guti == NULL) {
|
||||
@@ -2422,6 +2439,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
|
||||
}
|
||||
if (ctx->guti != NULL) {
|
||||
/* 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.MCCdigit2 = 0;
|
||||
ctx->guti->gummei.plmn.MCCdigit3 = 8;
|
||||
@@ -2433,8 +2451,10 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
|
||||
ctx->guti->gummei.MMEgid = 0;
|
||||
|
||||
ctx->guti->m_tmsi = (uint32_t) ctx;
|
||||
|
||||
ctx->tac = 1;
|
||||
} else {
|
||||
return (RETURNerror);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
}
|
||||
/* The IMSI if provided by the UE */
|
||||
@@ -2445,7 +2465,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
|
||||
if (ctx->imsi != NULL) {
|
||||
memcpy(ctx->imsi, imsi, sizeof(imsi_t));
|
||||
} else {
|
||||
return (RETURNerror);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
}
|
||||
/* The IMEI if provided by the UE */
|
||||
@@ -2456,7 +2476,7 @@ static int _emm_attach_update(emm_data_context_t *ctx, unsigned int ueid,
|
||||
if (ctx->imei != NULL) {
|
||||
memcpy(ctx->imei, imei, sizeof(imei_t));
|
||||
} else {
|
||||
return (RETURNerror);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
}
|
||||
/* 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,
|
||||
strncpy((char *)ctx->esm_msg.value,
|
||||
(char *)esm_msg->value, esm_msg->length);
|
||||
} else {
|
||||
return (RETURNerror);
|
||||
LOG_FUNC_RETURN (RETURNerror);
|
||||
}
|
||||
}
|
||||
ctx->esm_msg.length = esm_msg->length;
|
||||
/* Attachment indicator */
|
||||
ctx->is_attached = FALSE;
|
||||
|
||||
return (RETURNok);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
}
|
||||
|
||||
#endif // NAS_MME
|
||||
|
||||
@@ -670,6 +670,8 @@ int emm_proc_authentication_complete(unsigned int ueid, int emm_cause,
|
||||
/* RES does not match the XRES parameter */
|
||||
LOG_TRACE(WARNING, "EMM-PROC - Failed to authentify the UE");
|
||||
emm_cause = EMM_CAUSE_ILLEGAL_UE;
|
||||
} else {
|
||||
LOG_TRACE(DEBUG, "EMM-PROC - Success to authentify the UE RESP XRES == XRES UE CONTEXT");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1151,10 +1153,10 @@ static int _authentication_kasme(const OctetString *autn,
|
||||
/* Compute the KDF input parameter
|
||||
* S = FC(0x10) || SNid || 0x00 0x03 || SQN ⊕ AK || 0x00 0x06
|
||||
*/
|
||||
UInt8_t input[kasme->length];
|
||||
UInt8_t input[kasme->length];
|
||||
UInt16_t length;
|
||||
int offset = 0;
|
||||
int size_of_length = sizeof(length);
|
||||
int offset = 0;
|
||||
int size_of_length = sizeof(length);
|
||||
input[offset] = 0x10;
|
||||
offset += 1;
|
||||
length = AUTH_SNID_SIZE;
|
||||
|
||||
@@ -30,6 +30,7 @@ Description Defines EMM procedures executed by the Non-Access Stratum
|
||||
|
||||
#include "emm_sap.h"
|
||||
#include "esm_sap.h"
|
||||
#include "nas_log.h"
|
||||
|
||||
#include <string.h> // memset
|
||||
|
||||
@@ -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
|
||||
* NAS signalling messages with the selected NAS ciphering and
|
||||
* 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->ksi = context->eksi;
|
||||
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,
|
||||
/* 3GPP TS 24.301, section 5.4.3.2
|
||||
* The MME shall send the SECURITY MODE COMMAND message integrity
|
||||
* protected and unciphered */
|
||||
LOG_TRACE(WARNING,
|
||||
"EPS security context exists knas_enc %s",
|
||||
context->knas_enc.value
|
||||
);
|
||||
data->k_enc = &context->knas_enc;
|
||||
}
|
||||
} else {
|
||||
LOG_TRACE(WARNING, "EMM_AS_NO_KEY_AVAILABLE");
|
||||
/* No valid EPS security context exists */
|
||||
data->ksi = EMM_AS_NO_KEY_AVAILABLE;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ Description Defines the security mode control EMM procedure executed by the
|
||||
#if defined(ENABLE_ITTI)
|
||||
# include "assertions.h"
|
||||
#endif
|
||||
#include "secu_defs.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
||||
@@ -98,20 +99,26 @@ static void *_security_t3460_handler(void *);
|
||||
* retransmission timer counter is exceed
|
||||
*/
|
||||
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
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int ueid; /* UE identifier */
|
||||
unsigned int ueid; /* UE identifier */
|
||||
#define SECURITY_COUNTER_MAX 5
|
||||
unsigned int retransmission_count; /* Retransmission counter */
|
||||
int ksi; /* NAS key set identifier */
|
||||
int eea; /* Replayed EPS encryption algorithms */
|
||||
int eia; /* Replayed EPS integrity algorithms */
|
||||
int ksi; /* NAS key set identifier */
|
||||
int eea; /* Replayed EPS encryption 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
|
||||
* procedure failure shall be notified to the
|
||||
* ongoing EMM procedure */
|
||||
* procedure failure shall be notified to the
|
||||
* ongoing EMM procedure */
|
||||
} security_data_t;
|
||||
|
||||
static int _security_request(security_data_t *data, int is_new);
|
||||
@@ -332,6 +339,8 @@ int emm_proc_security_mode_command(int native_ksi, int ksi,
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
#ifdef NAS_MME
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** 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,
|
||||
{
|
||||
int rc = RETURNerror;
|
||||
int security_context_is_new = FALSE;
|
||||
|
||||
int mme_eea = NAS_SECURITY_ALGORITHMS_EEA0;
|
||||
int mme_eia = NAS_SECURITY_ALGORITHMS_EIA0;
|
||||
/* Get the UE context */
|
||||
emm_data_context_t *emm_ctx = NULL;
|
||||
|
||||
LOG_FUNC_IN;
|
||||
|
||||
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 (ueid > 0) {
|
||||
@@ -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;
|
||||
|
||||
/* 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 */
|
||||
security_context_is_new = TRUE;
|
||||
@@ -434,6 +491,10 @@ int emm_proc_security_mode_control(unsigned int ueid, int ksi, int eea, int eia,
|
||||
data->eea = eea;
|
||||
/* Set the EPS integrity algorithms to be replayed to the UE */
|
||||
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 */
|
||||
data->notify_failure = FALSE;
|
||||
/* Send security mode command message to the UE */
|
||||
@@ -885,12 +946,14 @@ int _security_request(security_data_t *data, int is_new)
|
||||
* to the UE
|
||||
*/
|
||||
emm_sap.primitive = EMMAS_SECURITY_REQ;
|
||||
emm_sap.u.emm_as.u.security.guti = NULL;
|
||||
emm_sap.u.emm_as.u.security.ueid = data->ueid;
|
||||
emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC;
|
||||
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.eia = data->eia;
|
||||
emm_sap.u.emm_as.u.security.guti = NULL;
|
||||
emm_sap.u.emm_as.u.security.ueid = data->ueid;
|
||||
emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_SMC;
|
||||
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.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 (data->ueid > 0) {
|
||||
@@ -976,5 +1039,64 @@ static int _security_abort(void *args)
|
||||
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
|
||||
|
||||
|
||||
@@ -113,6 +113,10 @@ typedef struct {
|
||||
UInt8_t encryption:4; /* algorithm used for ciphering */
|
||||
UInt8_t integrity:4; /* algorithm used for integrity protection */
|
||||
} 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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -67,7 +67,7 @@ Description Defines error cause code returned upon receiving unknown,
|
||||
#define EMM_CAUSE_MAC_FAILURE 20
|
||||
#define EMM_CAUSE_SYNCH_FAILURE 21
|
||||
#define EMM_CAUSE_CONGESTION 22
|
||||
#define EMM_CAUSE_UE_SECURITY_MISMATCH 23
|
||||
#define EMM_CAUSE_UE_SECURITY_MISMATCH 23
|
||||
#define EMM_CAUSE_SECURITY_MODE_REJECTED 24
|
||||
#define EMM_CAUSE_NON_EPS_AUTH_UNACCEPTABLE 26
|
||||
#define EMM_CAUSE_CS_SERVICE_NOT_AVAILABLE 39
|
||||
|
||||
@@ -105,9 +105,20 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause);
|
||||
*/
|
||||
static EMM_msg *_emm_as_set_header(nas_message_t *msg,
|
||||
const emm_as_security_data_t *security);
|
||||
static int _emm_as_encode(as_nas_info_t *info, nas_message_t *msg, int length);
|
||||
static int _emm_as_encrypt(as_nas_info_t *info,
|
||||
const nas_message_security_header_t *header, const char *buffer, int length);
|
||||
static int
|
||||
_emm_as_encode(
|
||||
as_nas_info_t *info,
|
||||
nas_message_t *msg,
|
||||
int length,
|
||||
emm_security_context_t *emm_security_context);
|
||||
|
||||
static int _emm_as_encrypt(
|
||||
as_nas_info_t *info,
|
||||
const nas_message_security_header_t *header,
|
||||
const char *buffer,
|
||||
int length,
|
||||
emm_security_context_t *emm_security_context);
|
||||
|
||||
static int _emm_as_send(const emm_as_t *msg);
|
||||
|
||||
#ifdef NAS_UE
|
||||
@@ -310,8 +321,22 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len,
|
||||
nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0 , sizeof(nas_message_t));
|
||||
|
||||
emm_data_context_t *emm_ctx = NULL;
|
||||
emm_security_context_t *security = NULL; /* Current EPS NAS security context */
|
||||
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, ueid);
|
||||
if (emm_ctx) {
|
||||
security = emm_ctx->security;
|
||||
}
|
||||
#else
|
||||
if (ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[ueid];
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Decode the received message */
|
||||
decoder_rc = nas_message_decode(msg, &nas_msg, len);
|
||||
decoder_rc = nas_message_decode(msg, &nas_msg, len, security);
|
||||
|
||||
if (decoder_rc < 0) {
|
||||
LOG_TRACE(WARNING, "EMMAS-SAP - Failed to decode NAS message "
|
||||
@@ -369,33 +394,38 @@ static int _emm_as_recv(unsigned int ueid, const char *msg, int len,
|
||||
#endif
|
||||
#ifdef NAS_MME
|
||||
case ATTACH_REQUEST:
|
||||
rc = emm_recv_attach_request(ueid,
|
||||
&emm_msg->attach_request,
|
||||
emm_cause);
|
||||
rc = emm_recv_attach_request(
|
||||
ueid,
|
||||
&emm_msg->attach_request,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case IDENTITY_RESPONSE:
|
||||
rc = emm_recv_identity_response(ueid,
|
||||
&emm_msg->identity_response,
|
||||
emm_cause);
|
||||
rc = emm_recv_identity_response(
|
||||
ueid,
|
||||
&emm_msg->identity_response,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_RESPONSE:
|
||||
rc = emm_recv_authentication_response(ueid,
|
||||
&emm_msg->authentication_response,
|
||||
emm_cause);
|
||||
rc = emm_recv_authentication_response(
|
||||
ueid,
|
||||
&emm_msg->authentication_response,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_FAILURE:
|
||||
rc = emm_recv_authentication_failure(ueid,
|
||||
&emm_msg->authentication_failure,
|
||||
emm_cause);
|
||||
rc = emm_recv_authentication_failure(
|
||||
ueid,
|
||||
&emm_msg->authentication_failure,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case SECURITY_MODE_COMPLETE:
|
||||
rc = emm_recv_security_mode_complete(ueid,
|
||||
&emm_msg->security_mode_complete,
|
||||
emm_cause);
|
||||
rc = emm_recv_security_mode_complete(
|
||||
ueid,
|
||||
&emm_msg->security_mode_complete,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case SECURITY_MODE_REJECT:
|
||||
@@ -464,10 +494,32 @@ static int _emm_as_data_ind(const emm_as_data_t *msg, int *emm_cause)
|
||||
char *plain_msg = (char *)malloc(msg->NASmsg.length);
|
||||
if (plain_msg) {
|
||||
nas_message_security_header_t header;
|
||||
emm_data_context_t *emm_ctx = NULL;
|
||||
emm_security_context_t *security = NULL; /* Current EPS NAS security context */
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
/* Decrypt the received security protected message */
|
||||
#if defined(EPC_BUILD)
|
||||
if (msg->ueid > 0) {
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
if (emm_ctx) {
|
||||
security = emm_ctx->security;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
if (emm_ctx) {
|
||||
security = emm_ctx->security;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
int bytes = nas_message_decrypt((char *)(msg->NASmsg.value),
|
||||
plain_msg, &header,
|
||||
msg->NASmsg.length);
|
||||
plain_msg,
|
||||
&header,
|
||||
msg->NASmsg.length,
|
||||
security
|
||||
);
|
||||
if (bytes < 0) {
|
||||
/* Failed to decrypt the message */
|
||||
*emm_cause = EMM_CAUSE_PROTOCOL_ERROR;
|
||||
@@ -694,6 +746,8 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, int *emm_cause)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
int decoder_rc;
|
||||
int rc = RETURNerror;
|
||||
|
||||
@@ -702,9 +756,23 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, int *emm_cause)
|
||||
nas_message_t nas_msg;
|
||||
memset(&nas_msg, 0 , sizeof(nas_message_t));
|
||||
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
|
||||
/* Decode initial NAS message */
|
||||
decoder_rc = nas_message_decode((char *)(msg->NASmsg.value), &nas_msg,
|
||||
msg->NASmsg.length);
|
||||
decoder_rc = nas_message_decode(
|
||||
(char *)(msg->NASmsg.value),
|
||||
&nas_msg,
|
||||
msg->NASmsg.length,
|
||||
emm_security_context);
|
||||
|
||||
if (decoder_rc < TLV_DECODE_FATAL_ERROR) {
|
||||
*emm_cause = EMM_CAUSE_PROTOCOL_ERROR;
|
||||
@@ -719,8 +787,10 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, int *emm_cause)
|
||||
EMM_msg *emm_msg = &nas_msg.plain.emm;
|
||||
switch (emm_msg->header.message_type) {
|
||||
case ATTACH_REQUEST:
|
||||
rc = emm_recv_attach_request(msg->ueid, &emm_msg->attach_request,
|
||||
emm_cause);
|
||||
rc = emm_recv_attach_request(
|
||||
msg->ueid,
|
||||
&emm_msg->attach_request,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case DETACH_REQUEST:
|
||||
@@ -728,9 +798,10 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg, int *emm_cause)
|
||||
break;
|
||||
|
||||
case TRACKING_AREA_UPDATE_REQUEST:
|
||||
rc = emm_recv_tracking_area_update_request(msg->ueid,
|
||||
&emm_msg->tracking_area_update_request,
|
||||
emm_cause);
|
||||
rc = emm_recv_tracking_area_update_request(
|
||||
msg->ueid,
|
||||
&emm_msg->tracking_area_update_request,
|
||||
emm_cause);
|
||||
break;
|
||||
|
||||
case SERVICE_REQUEST:
|
||||
@@ -919,13 +990,19 @@ static EMM_msg *_emm_as_set_header(nas_message_t *msg,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _emm_as_encode(as_nas_info_t *info, nas_message_t *msg, int length)
|
||||
static int
|
||||
_emm_as_encode(
|
||||
as_nas_info_t *info,
|
||||
nas_message_t *msg,
|
||||
int length,
|
||||
emm_security_context_t *emm_security_context)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
int bytes = 0;
|
||||
|
||||
if (msg->header.security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) {
|
||||
if (msg->header.security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED)
|
||||
{
|
||||
emm_msg_header_t *header = &msg->security_protected.plain.emm.header;
|
||||
/* Expand size of protected NAS message */
|
||||
length += NAS_MESSAGE_SECURITY_HEADER_SIZE;
|
||||
@@ -937,7 +1014,12 @@ static int _emm_as_encode(as_nas_info_t *info, nas_message_t *msg, int length)
|
||||
info->data = (Byte_t *)malloc(length * sizeof(Byte_t));
|
||||
if (info->data != NULL) {
|
||||
/* Encode the NAS message */
|
||||
bytes = nas_message_encode((char *)(info->data), msg, length);
|
||||
bytes = nas_message_encode(
|
||||
(char *)(info->data),
|
||||
msg,
|
||||
length,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
info->length = bytes;
|
||||
} else {
|
||||
@@ -966,9 +1048,13 @@ static int _emm_as_encode(as_nas_info_t *info, nas_message_t *msg, int length)
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
static int _emm_as_encrypt(as_nas_info_t *info,
|
||||
const nas_message_security_header_t *header,
|
||||
const char *msg, int length)
|
||||
static int
|
||||
_emm_as_encrypt(
|
||||
as_nas_info_t *info,
|
||||
const nas_message_security_header_t *header,
|
||||
const char *msg,
|
||||
int length,
|
||||
emm_security_context_t *emm_security_context)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
@@ -982,7 +1068,13 @@ static int _emm_as_encrypt(as_nas_info_t *info,
|
||||
info->data = (Byte_t *)malloc(length * sizeof(Byte_t));
|
||||
if (info->data != NULL) {
|
||||
/* Encrypt the NAS information message */
|
||||
bytes = nas_message_encrypt(msg, (char *)(info->data), header, length);
|
||||
bytes = nas_message_encrypt(
|
||||
msg,
|
||||
(char *)(info->data),
|
||||
header,
|
||||
length,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
info->length = bytes;
|
||||
} else {
|
||||
@@ -1020,51 +1112,60 @@ static int _emm_as_send(const emm_as_t *msg)
|
||||
|
||||
switch (msg->primitive) {
|
||||
case _EMMAS_DATA_REQ:
|
||||
as_msg.msgID = _emm_as_data_req(&msg->u.data,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
as_msg.msgID = _emm_as_data_req(
|
||||
&msg->u.data,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
break;
|
||||
|
||||
case _EMMAS_STATUS_IND:
|
||||
as_msg.msgID = _emm_as_status_ind(&msg->u.status,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
as_msg.msgID = _emm_as_status_ind(
|
||||
&msg->u.status,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
break;
|
||||
|
||||
case _EMMAS_RELEASE_REQ:
|
||||
as_msg.msgID = _emm_as_release_req(&msg->u.release,
|
||||
&as_msg.msg.nas_release_req);
|
||||
as_msg.msgID = _emm_as_release_req(
|
||||
&msg->u.release,
|
||||
&as_msg.msg.nas_release_req);
|
||||
break;
|
||||
|
||||
#ifdef NAS_UE
|
||||
case _EMMAS_SECURITY_RES:
|
||||
as_msg.msgID = _emm_as_security_res(&msg->u.security,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
as_msg.msgID = _emm_as_security_res(
|
||||
&msg->u.security,
|
||||
&as_msg.msg.ul_info_transfer_req);
|
||||
break;
|
||||
|
||||
case _EMMAS_ESTABLISH_REQ:
|
||||
as_msg.msgID = _emm_as_establish_req(&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_req);
|
||||
as_msg.msgID = _emm_as_establish_req(
|
||||
&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_req);
|
||||
break;
|
||||
|
||||
#endif
|
||||
#ifdef NAS_MME
|
||||
case _EMMAS_SECURITY_REQ:
|
||||
as_msg.msgID = _emm_as_security_req(&msg->u.security,
|
||||
&as_msg.msg.dl_info_transfer_req);
|
||||
as_msg.msgID = _emm_as_security_req(
|
||||
&msg->u.security,
|
||||
&as_msg.msg.dl_info_transfer_req);
|
||||
break;
|
||||
|
||||
case _EMMAS_SECURITY_REJ:
|
||||
as_msg.msgID = _emm_as_security_rej(&msg->u.security,
|
||||
&as_msg.msg.dl_info_transfer_req);
|
||||
as_msg.msgID = _emm_as_security_rej(
|
||||
&msg->u.security,
|
||||
&as_msg.msg.dl_info_transfer_req);
|
||||
break;
|
||||
|
||||
case _EMMAS_ESTABLISH_CNF:
|
||||
as_msg.msgID = _emm_as_establish_cnf(&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_rsp);
|
||||
as_msg.msgID = _emm_as_establish_cnf(
|
||||
&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_rsp);
|
||||
break;
|
||||
|
||||
case _EMMAS_ESTABLISH_REJ:
|
||||
as_msg.msgID = _emm_as_establish_rej(&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_rsp);
|
||||
as_msg.msgID = _emm_as_establish_rej(
|
||||
&msg->u.establish,
|
||||
&as_msg.msg.nas_establish_rsp);
|
||||
break;
|
||||
|
||||
case _EMMAS_PAGE_IND:
|
||||
@@ -1098,25 +1199,28 @@ static int _emm_as_send(const emm_as_t *msg)
|
||||
|
||||
switch (as_msg.msgID) {
|
||||
case AS_DL_INFO_TRANSFER_REQ: {
|
||||
nas_itti_dl_data_req(as_msg.msg.dl_info_transfer_req.UEid,
|
||||
as_msg.msg.dl_info_transfer_req.nasMsg.data,
|
||||
as_msg.msg.dl_info_transfer_req.nasMsg.length);
|
||||
nas_itti_dl_data_req(
|
||||
as_msg.msg.dl_info_transfer_req.UEid,
|
||||
as_msg.msg.dl_info_transfer_req.nasMsg.data,
|
||||
as_msg.msg.dl_info_transfer_req.nasMsg.length);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} break;
|
||||
|
||||
case AS_NAS_ESTABLISH_RSP:
|
||||
case AS_NAS_ESTABLISH_CNF: {
|
||||
if (as_msg.msg.nas_establish_rsp.errCode != AS_SUCCESS) {
|
||||
nas_itti_dl_data_req(as_msg.msg.nas_establish_rsp.UEid,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.data,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.length);
|
||||
nas_itti_dl_data_req(
|
||||
as_msg.msg.nas_establish_rsp.UEid,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.data,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.length);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} else {
|
||||
/* Handle success case */
|
||||
nas_itti_establish_cnf(as_msg.msg.nas_establish_rsp.UEid,
|
||||
as_msg.msg.nas_establish_rsp.errCode,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.data,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.length);
|
||||
nas_itti_establish_cnf(
|
||||
as_msg.msg.nas_establish_rsp.UEid,
|
||||
as_msg.msg.nas_establish_rsp.errCode,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.data,
|
||||
as_msg.msg.nas_establish_rsp.nasMsg.length);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
}
|
||||
} break;
|
||||
@@ -1134,32 +1238,36 @@ static int _emm_as_send(const emm_as_t *msg)
|
||||
|
||||
switch (as_msg.msgID) {
|
||||
case AS_CELL_INFO_REQ: {
|
||||
nas_itti_cell_info_req(as_msg.msg.cell_info_req.plmnID,
|
||||
as_msg.msg.cell_info_req.rat);
|
||||
nas_itti_cell_info_req(
|
||||
as_msg.msg.cell_info_req.plmnID,
|
||||
as_msg.msg.cell_info_req.rat);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} break;
|
||||
|
||||
case AS_NAS_ESTABLISH_REQ: {
|
||||
nas_itti_nas_establish_req(as_msg.msg.nas_establish_req.cause,
|
||||
as_msg.msg.nas_establish_req.type,
|
||||
as_msg.msg.nas_establish_req.s_tmsi,
|
||||
as_msg.msg.nas_establish_req.plmnID,
|
||||
as_msg.msg.nas_establish_req.initialNasMsg.data,
|
||||
as_msg.msg.nas_establish_req.initialNasMsg.length);
|
||||
nas_itti_nas_establish_req(
|
||||
as_msg.msg.nas_establish_req.cause,
|
||||
as_msg.msg.nas_establish_req.type,
|
||||
as_msg.msg.nas_establish_req.s_tmsi,
|
||||
as_msg.msg.nas_establish_req.plmnID,
|
||||
as_msg.msg.nas_establish_req.initialNasMsg.data,
|
||||
as_msg.msg.nas_establish_req.initialNasMsg.length);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} break;
|
||||
|
||||
case AS_UL_INFO_TRANSFER_REQ: {
|
||||
nas_itti_ul_data_req(as_msg.msg.ul_info_transfer_req.UEid,
|
||||
as_msg.msg.ul_info_transfer_req.nasMsg.data,
|
||||
as_msg.msg.ul_info_transfer_req.nasMsg.length);
|
||||
nas_itti_ul_data_req(
|
||||
as_msg.msg.ul_info_transfer_req.UEid,
|
||||
as_msg.msg.ul_info_transfer_req.nasMsg.data,
|
||||
as_msg.msg.ul_info_transfer_req.nasMsg.length);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} break;
|
||||
|
||||
case AS_RAB_ESTABLISH_RSP: {
|
||||
nas_itti_rab_establish_rsp(as_msg.msg.rab_establish_rsp.s_tmsi,
|
||||
as_msg.msg.rab_establish_rsp.rabID,
|
||||
as_msg.msg.rab_establish_rsp.errCode);
|
||||
nas_itti_rab_establish_rsp(
|
||||
as_msg.msg.rab_establish_rsp.s_tmsi,
|
||||
as_msg.msg.rab_establish_rsp.rabID,
|
||||
as_msg.msg.rab_establish_rsp.errCode);
|
||||
LOG_FUNC_RETURN (RETURNok);
|
||||
} break;
|
||||
|
||||
@@ -1245,13 +1353,32 @@ static int _emm_as_data_req(const emm_as_data_t *msg,
|
||||
|
||||
if (size > 0) {
|
||||
int bytes;
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
|
||||
if (!is_encoded) {
|
||||
/* Encode the NAS information message */
|
||||
bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
bytes = _emm_as_encode(&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
} else {
|
||||
/* Encrypt the NAS information message */
|
||||
bytes = _emm_as_encrypt(&as_msg->nasMsg, &nas_msg.header,
|
||||
(char *)(msg->NASmsg.value), size);
|
||||
bytes = _emm_as_encrypt(&as_msg->nasMsg,
|
||||
&nas_msg.header,
|
||||
(char *)(msg->NASmsg.value),
|
||||
size,
|
||||
emm_security_context);
|
||||
}
|
||||
if (bytes > 0) {
|
||||
#ifdef NAS_UE
|
||||
@@ -1311,8 +1438,25 @@ static int _emm_as_status_ind(const emm_as_status_t *msg,
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
/* Encode the NAS information message */
|
||||
int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
int bytes = _emm_as_encode(
|
||||
&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
#ifdef NAS_UE
|
||||
LOG_FUNC_RETURN (AS_UL_INFO_TRANSFER_REQ);
|
||||
@@ -1407,26 +1551,32 @@ static int _emm_as_security_res(const emm_as_security_t *msg,
|
||||
/* Setup the NAS security message */
|
||||
if (emm_msg != NULL) switch (msg->msgType) {
|
||||
case EMM_AS_MSG_TYPE_IDENT:
|
||||
size = emm_send_identity_response(msg, &emm_msg->identity_response);
|
||||
size = emm_send_identity_response(
|
||||
msg,
|
||||
&emm_msg->identity_response);
|
||||
break;
|
||||
|
||||
case EMM_AS_MSG_TYPE_AUTH:
|
||||
if (msg->emm_cause != EMM_CAUSE_SUCCESS) {
|
||||
size = emm_send_authentication_failure(msg,
|
||||
&emm_msg->authentication_failure);
|
||||
size = emm_send_authentication_failure(
|
||||
msg,
|
||||
&emm_msg->authentication_failure);
|
||||
} else {
|
||||
size = emm_send_authentication_response(msg,
|
||||
&emm_msg->authentication_response);
|
||||
size = emm_send_authentication_response(
|
||||
msg,
|
||||
&emm_msg->authentication_response);
|
||||
}
|
||||
break;
|
||||
|
||||
case EMM_AS_MSG_TYPE_SMC:
|
||||
if (msg->emm_cause != EMM_CAUSE_SUCCESS) {
|
||||
size = emm_send_security_mode_reject(msg,
|
||||
&emm_msg->security_mode_reject);
|
||||
size = emm_send_security_mode_reject(
|
||||
msg,
|
||||
&emm_msg->security_mode_reject);
|
||||
} else {
|
||||
size = emm_send_security_mode_complete(msg,
|
||||
&emm_msg->security_mode_complete);
|
||||
size = emm_send_security_mode_complete(
|
||||
msg,
|
||||
&emm_msg->security_mode_complete);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1497,21 +1647,22 @@ static int _emm_as_establish_req(const emm_as_establish_t *msg,
|
||||
|
||||
case EMM_AS_NAS_INFO_DETACH:
|
||||
size = emm_send_initial_detach_request(msg,
|
||||
&emm_msg->detach_request);
|
||||
&emm_msg->detach_request);
|
||||
break;
|
||||
|
||||
case EMM_AS_NAS_INFO_TAU:
|
||||
size = emm_send_initial_tau_request(msg,
|
||||
&emm_msg->tracking_area_update_request);
|
||||
&emm_msg->tracking_area_update_request);
|
||||
break;
|
||||
|
||||
case EMM_AS_NAS_INFO_SR:
|
||||
size = emm_send_initial_sr_request(msg, &emm_msg->service_request);
|
||||
size = emm_send_initial_sr_request(msg,
|
||||
&emm_msg->service_request);
|
||||
break;
|
||||
|
||||
case EMM_AS_NAS_INFO_EXTSR:
|
||||
size = emm_send_initial_extsr_request(msg,
|
||||
&emm_msg->extended_service_request);
|
||||
&emm_msg->extended_service_request);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1574,17 +1725,18 @@ static int _emm_as_security_req(const emm_as_security_t *msg,
|
||||
/* Setup the NAS security message */
|
||||
if (emm_msg != NULL) switch (msg->msgType) {
|
||||
case EMM_AS_MSG_TYPE_IDENT:
|
||||
size = emm_send_identity_request(msg, &emm_msg->identity_request);
|
||||
size = emm_send_identity_request(msg,
|
||||
&emm_msg->identity_request);
|
||||
break;
|
||||
|
||||
case EMM_AS_MSG_TYPE_AUTH:
|
||||
size = emm_send_authentication_request(msg,
|
||||
&emm_msg->authentication_request);
|
||||
&emm_msg->authentication_request);
|
||||
break;
|
||||
|
||||
case EMM_AS_MSG_TYPE_SMC:
|
||||
size = emm_send_security_mode_command(msg,
|
||||
&emm_msg->security_mode_command);
|
||||
&emm_msg->security_mode_command);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1593,8 +1745,25 @@ static int _emm_as_security_req(const emm_as_security_t *msg,
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
/* Encode the NAS security message */
|
||||
int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
int bytes = _emm_as_encode(
|
||||
&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
LOG_FUNC_RETURN (AS_DL_INFO_TRANSFER_REQ);
|
||||
}
|
||||
@@ -1654,8 +1823,25 @@ static int _emm_as_security_rej(const emm_as_security_t *msg,
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
/* Encode the NAS security message */
|
||||
int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
int bytes = _emm_as_encode(
|
||||
&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
LOG_FUNC_RETURN (AS_DL_INFO_TRANSFER_REQ);
|
||||
}
|
||||
@@ -1708,8 +1894,9 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg,
|
||||
/* Setup the initial NAS information message */
|
||||
if (emm_msg != NULL) switch (msg->NASinfo) {
|
||||
case EMM_AS_NAS_INFO_ATTACH:
|
||||
LOG_TRACE(WARNING, "EMMAS-SAP - emm_as_establish.nasMSG.length"\
|
||||
"=%d", msg->NASmsg.length);
|
||||
LOG_TRACE(WARNING,
|
||||
"EMMAS-SAP - emm_as_establish.nasMSG.length=%d",
|
||||
msg->NASmsg.length);
|
||||
size = emm_send_attach_accept(msg, &emm_msg->attach_accept);
|
||||
break;
|
||||
|
||||
@@ -1720,8 +1907,32 @@ static int _emm_as_establish_cnf(const emm_as_establish_t *msg,
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
if (emm_security_context) {
|
||||
as_msg->nas_ul_count = 0x00000000 |
|
||||
(emm_security_context->ul_count.overflow << 8) |
|
||||
emm_security_context->ul_count.seq_num;
|
||||
LOG_TRACE(DEBUG, "EMMAS-SAP - NAS UL COUNT %8x",
|
||||
as_msg->nas_ul_count);
|
||||
}
|
||||
}
|
||||
/* Encode the initial NAS information message */
|
||||
int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
int bytes = _emm_as_encode(
|
||||
&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
|
||||
if (bytes > 0) {
|
||||
as_msg->errCode = AS_SUCCESS;
|
||||
LOG_FUNC_RETURN (AS_NAS_ESTABLISH_CNF);
|
||||
@@ -1780,7 +1991,8 @@ static int _emm_as_establish_rej(const emm_as_establish_t *msg,
|
||||
break;
|
||||
|
||||
case EMM_AS_NAS_INFO_TAU:
|
||||
size = emm_send_tracking_area_update_reject(msg, &emm_msg->tracking_area_update_reject);
|
||||
size = emm_send_tracking_area_update_reject(msg,
|
||||
&emm_msg->tracking_area_update_reject);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1790,8 +2002,24 @@ static int _emm_as_establish_rej(const emm_as_establish_t *msg,
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
struct emm_data_context_s *emm_ctx = NULL;
|
||||
emm_security_context_t *emm_security_context = NULL;
|
||||
#if defined(EPC_BUILD)
|
||||
emm_ctx = emm_data_context_get(&_emm_data, msg->ueid);
|
||||
#else
|
||||
if (msg->ueid < EMM_DATA_NB_UE_MAX) {
|
||||
emm_ctx = _emm_data.ctx[msg->ueid];
|
||||
}
|
||||
#endif
|
||||
if (emm_ctx) {
|
||||
emm_security_context = emm_ctx->security;
|
||||
}
|
||||
/* Encode the initial NAS information message */
|
||||
int bytes = _emm_as_encode(&as_msg->nasMsg, &nas_msg, size);
|
||||
int bytes = _emm_as_encode(
|
||||
&as_msg->nasMsg,
|
||||
&nas_msg,
|
||||
size,
|
||||
emm_security_context);
|
||||
if (bytes > 0) {
|
||||
as_msg->errCode = AS_TERMINATED_NAS;
|
||||
LOG_FUNC_RETURN (AS_NAS_ESTABLISH_RSP);
|
||||
|
||||
@@ -98,6 +98,10 @@ typedef struct {
|
||||
UInt8_t eea; /* Replayed EPS encryption 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_AUTH 0x02 /* Authentication message */
|
||||
#define EMM_AS_MSG_TYPE_SMC 0x03 /* Security Mode Command */
|
||||
|
||||
@@ -101,11 +101,14 @@ static int _emm_cn_authentication_res(const emm_cn_auth_res_t *msg)
|
||||
* and NAS security setup to activate integrity protection and NAS
|
||||
* ciphering are mandatory.
|
||||
*/
|
||||
rc = emm_proc_authentication(emm_ctx, emm_ctx->ueid, 0, // TODO: eksi != 0
|
||||
&loc_rand, &autn,
|
||||
emm_attach_security,
|
||||
NULL,
|
||||
NULL);
|
||||
rc = emm_proc_authentication(emm_ctx,
|
||||
emm_ctx->ueid,
|
||||
0, // TODO: eksi != 0
|
||||
&loc_rand,
|
||||
&autn,
|
||||
emm_attach_security,
|
||||
NULL,
|
||||
NULL);
|
||||
if (rc != RETURNok) {
|
||||
/* Failed to initiate the authentication procedure */
|
||||
LOG_TRACE(WARNING, "EMM-PROC - "
|
||||
|
||||
@@ -983,9 +983,11 @@ int emm_recv_authentication_failure(unsigned int ueid,
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
int emm_recv_security_mode_complete(unsigned int ueid,
|
||||
security_mode_complete_msg *msg,
|
||||
int *emm_cause)
|
||||
int
|
||||
emm_recv_security_mode_complete(
|
||||
unsigned int ueid,
|
||||
security_mode_complete_msg *msg,
|
||||
int *emm_cause)
|
||||
{
|
||||
LOG_FUNC_IN;
|
||||
|
||||
|
||||
@@ -1205,9 +1205,9 @@ int emm_send_security_mode_command(const emm_as_security_t *msg,
|
||||
/* Selected NAS security algorithms */
|
||||
size += NAS_SECURITY_ALGORITHMS_MAXIMUM_LENGTH;
|
||||
emm_msg->selectednassecurityalgorithms.typeofcipheringalgorithm =
|
||||
NAS_SECURITY_ALGORITHMS_EEA0;
|
||||
msg->selected_eea;
|
||||
emm_msg->selectednassecurityalgorithms.typeofintegrityalgorithm =
|
||||
NAS_SECURITY_ALGORITHMS_EIA0;
|
||||
msg->selected_eia;
|
||||
|
||||
/* NAS key set identifier */
|
||||
size += NAS_KEY_SET_IDENTIFIER_MAXIMUM_LENGTH;
|
||||
|
||||
@@ -48,8 +48,8 @@ Description Contains global security definitions
|
||||
#define AUTH_RES_SIZE 16 /* Authentication response: 128 bits */
|
||||
#define AUTH_SNID_SIZE 3 /* Serving network's identity: 24 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_ENC_SIZE AUTH_KASME_SIZE /* NAS cyphering key */
|
||||
#define AUTH_KNAS_INT_SIZE 16 /* NAS integrity key */
|
||||
#define AUTH_KNAS_ENC_SIZE 16 /* NAS cyphering key */
|
||||
#define AUTH_KENB_SIZE AUTH_KASME_SIZE /* eNodeB security key */
|
||||
|
||||
/* "Separation bit" of AMF field */
|
||||
|
||||
@@ -98,10 +98,15 @@ static int _esm_status(char* buffer, int length, const esm_status_msg* msg);
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process NAS message
|
||||
* Process NAS message
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
int nas_process(char* buffer, int length, const char* msg, int size)
|
||||
int
|
||||
nas_process(
|
||||
char* buffer,
|
||||
int length,
|
||||
const char* msg,
|
||||
int size)
|
||||
{
|
||||
int index = 0;
|
||||
int bytes;
|
||||
@@ -111,26 +116,28 @@ int nas_process(char* buffer, int length, const char* msg, int size)
|
||||
memset(&nas_msg, 0, sizeof(nas_message_t));
|
||||
bytes = nas_message_decode(msg, &nas_msg, size);
|
||||
if (bytes < 0) {
|
||||
printf("ERROR\t: %s - Failed to decode NAS message (err=%d)\n",
|
||||
__FUNCTION__, bytes);
|
||||
return (RETURNerror);
|
||||
printf("ERROR\t: %s - Failed to decode NAS message (err=%d)\n",
|
||||
__FUNCTION__, bytes);
|
||||
return (RETURNerror);
|
||||
}
|
||||
|
||||
int protocol_discriminator = nas_msg.header.protocol_discriminator;
|
||||
if (protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE) {
|
||||
/* Process EPS Mobility Management NAS message */
|
||||
index += _nas_process_emm(buffer + index, length - index,
|
||||
&nas_msg.plain.emm);
|
||||
/* Process EPS Mobility Management NAS message */
|
||||
index += _nas_process_emm(buffer + index,
|
||||
length - index,
|
||||
&nas_msg.plain.emm);
|
||||
}
|
||||
else if (protocol_discriminator == EPS_SESSION_MANAGEMENT_MESSAGE) {
|
||||
/* Process EPS Session Management NAS message */
|
||||
index += _nas_process_esm(buffer + index, length - index,
|
||||
&nas_msg.plain.esm);
|
||||
/* Process EPS Session Management NAS message */
|
||||
index += _nas_process_esm(buffer + index,
|
||||
length - index,
|
||||
&nas_msg.plain.esm);
|
||||
}
|
||||
else {
|
||||
printf("ERROR\t: %s - Protocol discriminator is not valid (%d)\n",
|
||||
__FUNCTION__, protocol_discriminator);
|
||||
return (RETURNerror);
|
||||
printf("ERROR\t: %s - Protocol discriminator is not valid (%d)\n",
|
||||
__FUNCTION__, protocol_discriminator);
|
||||
return (RETURNerror);
|
||||
}
|
||||
|
||||
buffer[index] = '\0';
|
||||
@@ -150,116 +157,121 @@ int nas_process(char* buffer, int length, const char* msg, int size)
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process EPS Mobility Management NAS message
|
||||
* Process EPS Mobility Management NAS message
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _nas_process_emm(char* buffer, int length, const EMM_msg* msg)
|
||||
static int
|
||||
_nas_process_emm(
|
||||
char* buffer,
|
||||
int length,
|
||||
const EMM_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
const EsmMessageContainer* esm_container = NULL;
|
||||
|
||||
printf("INFO\t: Process %s\n", emmMsgType(msg->header.message_type));
|
||||
index += snprintf(buffer + index, length - index, "%s (",
|
||||
emmMsgType(msg->header.message_type));
|
||||
emmMsgType(msg->header.message_type));
|
||||
|
||||
switch (msg->header.message_type)
|
||||
{
|
||||
case ATTACH_REQUEST:
|
||||
esm_container = &msg->attach_request.esmmessagecontainer;
|
||||
index += _attach_request(buffer + index, length - index,
|
||||
&msg->attach_request);
|
||||
break;
|
||||
case ATTACH_REQUEST:
|
||||
esm_container = &msg->attach_request.esmmessagecontainer;
|
||||
index += _attach_request(buffer + index, length - index,
|
||||
&msg->attach_request);
|
||||
break;
|
||||
|
||||
case ATTACH_ACCEPT:
|
||||
esm_container = &msg->attach_accept.esmmessagecontainer;
|
||||
index += _attach_accept(buffer + index, length - index,
|
||||
&msg->attach_accept);
|
||||
break;
|
||||
case ATTACH_ACCEPT:
|
||||
esm_container = &msg->attach_accept.esmmessagecontainer;
|
||||
index += _attach_accept(buffer + index, length - index,
|
||||
&msg->attach_accept);
|
||||
break;
|
||||
|
||||
case ATTACH_REJECT:
|
||||
esm_container = &msg->attach_reject.esmmessagecontainer;
|
||||
index += _attach_reject(buffer + index, length - index,
|
||||
&msg->attach_reject);
|
||||
break;
|
||||
case ATTACH_REJECT:
|
||||
esm_container = &msg->attach_reject.esmmessagecontainer;
|
||||
index += _attach_reject(buffer + index, length - index,
|
||||
&msg->attach_reject);
|
||||
break;
|
||||
|
||||
case ATTACH_COMPLETE:
|
||||
esm_container = &msg->attach_complete.esmmessagecontainer;
|
||||
index += _attach_complete(buffer + index, length - index,
|
||||
&msg->attach_complete);
|
||||
break;
|
||||
case ATTACH_COMPLETE:
|
||||
esm_container = &msg->attach_complete.esmmessagecontainer;
|
||||
index += _attach_complete(buffer + index, length - index,
|
||||
&msg->attach_complete);
|
||||
break;
|
||||
|
||||
case DETACH_REQUEST:
|
||||
index += _detach_request(buffer + index, length - index,
|
||||
&msg->detach_request);
|
||||
break;
|
||||
case DETACH_REQUEST:
|
||||
index += _detach_request(buffer + index, length - index,
|
||||
&msg->detach_request);
|
||||
break;
|
||||
|
||||
case DETACH_ACCEPT:
|
||||
index += _detach_accept(buffer + index, length - index,
|
||||
&msg->detach_accept);
|
||||
break;
|
||||
case DETACH_ACCEPT:
|
||||
index += _detach_accept(buffer + index, length - index,
|
||||
&msg->detach_accept);
|
||||
break;
|
||||
|
||||
case IDENTITY_REQUEST:
|
||||
index += _identity_request(buffer + index, length - index,
|
||||
&msg->identity_request);
|
||||
break;
|
||||
case IDENTITY_REQUEST:
|
||||
index += _identity_request(buffer + index, length - index,
|
||||
&msg->identity_request);
|
||||
break;
|
||||
|
||||
case IDENTITY_RESPONSE:
|
||||
index += _identity_response(buffer + index, length - index,
|
||||
&msg->identity_response);
|
||||
break;
|
||||
case IDENTITY_RESPONSE:
|
||||
index += _identity_response(buffer + index, length - index,
|
||||
&msg->identity_response);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_REQUEST:
|
||||
index += _authentication_request(buffer + index, length - index,
|
||||
&msg->authentication_request);
|
||||
break;
|
||||
case AUTHENTICATION_REQUEST:
|
||||
index += _authentication_request(buffer + index, length - index,
|
||||
&msg->authentication_request);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_RESPONSE:
|
||||
index += _authentication_response(buffer + index, length - index,
|
||||
&msg->authentication_response);
|
||||
break;
|
||||
case AUTHENTICATION_RESPONSE:
|
||||
index += _authentication_response(buffer + index, length - index,
|
||||
&msg->authentication_response);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_FAILURE:
|
||||
index += _authentication_failure(buffer + index, length - index,
|
||||
&msg->authentication_failure);
|
||||
break;
|
||||
case AUTHENTICATION_FAILURE:
|
||||
index += _authentication_failure(buffer + index, length - index,
|
||||
&msg->authentication_failure);
|
||||
break;
|
||||
|
||||
case AUTHENTICATION_REJECT:
|
||||
index += _authentication_reject(buffer + index, length - index,
|
||||
&msg->authentication_reject);
|
||||
break;
|
||||
case AUTHENTICATION_REJECT:
|
||||
index += _authentication_reject(buffer + index, length - index,
|
||||
&msg->authentication_reject);
|
||||
break;
|
||||
|
||||
case SECURITY_MODE_COMMAND:
|
||||
index += _security_mode_command(buffer + index, length - index,
|
||||
&msg->security_mode_command);
|
||||
break;
|
||||
case SECURITY_MODE_COMMAND:
|
||||
index += _security_mode_command(buffer + index, length - index,
|
||||
&msg->security_mode_command);
|
||||
break;
|
||||
|
||||
case SECURITY_MODE_COMPLETE:
|
||||
index += _security_mode_complete(buffer + index, length - index,
|
||||
&msg->security_mode_complete);
|
||||
break;
|
||||
case SECURITY_MODE_COMPLETE:
|
||||
index += _security_mode_complete(buffer + index, length - index,
|
||||
&msg->security_mode_complete);
|
||||
break;
|
||||
|
||||
case SECURITY_MODE_REJECT:
|
||||
index += _security_mode_reject(buffer + index, length - index,
|
||||
&msg->security_mode_reject);
|
||||
break;
|
||||
case SECURITY_MODE_REJECT:
|
||||
index += _security_mode_reject(buffer + index, length - index,
|
||||
&msg->security_mode_reject);
|
||||
break;
|
||||
|
||||
case EMM_STATUS:
|
||||
index += _emm_status(buffer + index, length - index,
|
||||
&msg->emm_status);
|
||||
break;
|
||||
case EMM_STATUS:
|
||||
index += _emm_status(buffer + index, length - index,
|
||||
&msg->emm_status);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("WARNING\t: %s - EMM NAS message is not valid (0x%x)\n",
|
||||
__FUNCTION__, msg->header.message_type);
|
||||
break;
|
||||
default:
|
||||
printf("WARNING\t: %s - EMM NAS message is not valid (0x%x)\n",
|
||||
__FUNCTION__, msg->header.message_type);
|
||||
break;
|
||||
}
|
||||
|
||||
index += snprintf(buffer + index, length - index, ")");
|
||||
|
||||
/* Process ESM message container */
|
||||
if (esm_container) {
|
||||
index += _esm_message_container(buffer + index, length - index,
|
||||
esm_container);
|
||||
index += _esm_message_container(buffer + index,
|
||||
length - index,
|
||||
esm_container);
|
||||
}
|
||||
|
||||
return (index);
|
||||
@@ -267,36 +279,42 @@ static int _nas_process_emm(char* buffer, int length, const EMM_msg* msg)
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process Attach Request
|
||||
* Process Attach Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _attach_request(char* buffer, int length,
|
||||
const attach_request_msg* msg)
|
||||
static int
|
||||
_attach_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const attach_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* EPS attach type */
|
||||
index += snprintf(buffer + index, length - index, "Type = %s",
|
||||
attachType(&msg->epsattachtype));
|
||||
attachType(&msg->epsattachtype));
|
||||
/* NAS key set identifier */
|
||||
index += snprintf(buffer + index, length - index, ", KSI = ");
|
||||
index += nasKeySetIdentifier(buffer + index, length - index,
|
||||
&msg->naskeysetidentifier);
|
||||
&msg->naskeysetidentifier);
|
||||
/* EPS mobile identity */
|
||||
index += snprintf(buffer + index, length - index, ", ");
|
||||
index += epsIdentity(buffer + index, length - index,
|
||||
&msg->oldgutiorimsi);
|
||||
&msg->oldgutiorimsi);
|
||||
|
||||
return (index);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process Attach Accept
|
||||
* Process Attach Accept
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _attach_accept(char* buffer, int length,
|
||||
const attach_accept_msg* msg)
|
||||
static int
|
||||
_attach_accept(
|
||||
char* buffer,
|
||||
int length,
|
||||
const attach_accept_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -310,7 +328,7 @@ static int _attach_accept(char* buffer, int length,
|
||||
#endif
|
||||
/* GUTI */
|
||||
if (msg->presencemask & ATTACH_ACCEPT_GUTI_PRESENT) {
|
||||
index += epsIdentity(buffer + index, length - index, &msg->guti);
|
||||
index += epsIdentity(buffer + index, length - index, &msg->guti);
|
||||
}
|
||||
|
||||
return (index);
|
||||
@@ -321,14 +339,17 @@ static int _attach_accept(char* buffer, int length,
|
||||
* Process Attach Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _attach_reject(char* buffer, int length,
|
||||
const attach_reject_msg* msg)
|
||||
static int
|
||||
_attach_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const attach_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* EMM cause code */
|
||||
index += snprintf(buffer + index, length - index, "EmmCause = %s (%d)",
|
||||
emmCauseCode(msg->emmcause), msg->emmcause);
|
||||
emmCauseCode(msg->emmcause), msg->emmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -338,8 +359,11 @@ static int _attach_reject(char* buffer, int length,
|
||||
* Process Attach Complete
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _attach_complete(char* buffer, int length,
|
||||
const attach_complete_msg* msg)
|
||||
static int
|
||||
_attach_complete(
|
||||
char* buffer,
|
||||
int length,
|
||||
const attach_complete_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -351,8 +375,11 @@ static int _attach_complete(char* buffer, int length,
|
||||
* Process Identity Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _identity_request(char* buffer, int length,
|
||||
const identity_request_msg* msg)
|
||||
static int
|
||||
_identity_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const identity_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -368,8 +395,11 @@ static int _identity_request(char* buffer, int length,
|
||||
* Process Detach Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _detach_request(char* buffer, int length,
|
||||
const detach_request_msg* msg)
|
||||
static int
|
||||
_detach_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const detach_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -393,8 +423,11 @@ static int _detach_request(char* buffer, int length,
|
||||
* Process Detach Accept
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _detach_accept(char* buffer, int length,
|
||||
const detach_accept_msg* msg)
|
||||
static int
|
||||
_detach_accept(
|
||||
char* buffer,
|
||||
int length,
|
||||
const detach_accept_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -406,8 +439,11 @@ static int _detach_accept(char* buffer, int length,
|
||||
* Process Identity Response
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _identity_response(char* buffer, int length,
|
||||
const identity_response_msg* msg)
|
||||
static int
|
||||
_identity_response(
|
||||
char* buffer,
|
||||
int length,
|
||||
const identity_response_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -423,8 +459,11 @@ static int _identity_response(char* buffer, int length,
|
||||
* Process Authentication Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _authentication_request(char* buffer, int length,
|
||||
const authentication_request_msg* msg)
|
||||
static int
|
||||
_authentication_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const authentication_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -449,8 +488,11 @@ static int _authentication_request(char* buffer, int length,
|
||||
* Process Authentication Response
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _authentication_response(char* buffer, int length,
|
||||
const authentication_response_msg* msg)
|
||||
static int
|
||||
_authentication_response(
|
||||
char* buffer,
|
||||
int length,
|
||||
const authentication_response_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -467,8 +509,11 @@ static int _authentication_response(char* buffer, int length,
|
||||
* Process Authentication Failure
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _authentication_failure(char* buffer, int length,
|
||||
const authentication_failure_msg* msg)
|
||||
static int
|
||||
_authentication_failure(
|
||||
char* buffer,
|
||||
int length,
|
||||
const authentication_failure_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -491,8 +536,11 @@ static int _authentication_failure(char* buffer, int length,
|
||||
* Process Authentication Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _authentication_reject(char* buffer, int length,
|
||||
const authentication_reject_msg* msg)
|
||||
static int
|
||||
_authentication_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const authentication_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -504,23 +552,28 @@ static int _authentication_reject(char* buffer, int length,
|
||||
* Process Security Mode Command
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _security_mode_command(char* buffer, int length,
|
||||
const security_mode_command_msg* msg)
|
||||
static int
|
||||
_security_mode_command(
|
||||
char* buffer,
|
||||
int length,
|
||||
const security_mode_command_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* Selected NAS ciphering algorithm */
|
||||
index += snprintf(buffer + index, length - index, "%s (%d)",
|
||||
nasCipheringAlgorithm(&msg->selectednassecurityalgorithms),
|
||||
msg->selectednassecurityalgorithms.typeofcipheringalgorithm);
|
||||
nasCipheringAlgorithm(&msg->selectednassecurityalgorithms),
|
||||
msg->selectednassecurityalgorithms.typeofcipheringalgorithm);
|
||||
|
||||
/* Selected NAS integrity algorithm */
|
||||
index += snprintf(buffer + index, length - index, ", %s (%d)",
|
||||
nasIntegrityAlgorithm(&msg->selectednassecurityalgorithms),
|
||||
msg->selectednassecurityalgorithms.typeofintegrityalgorithm);
|
||||
nasIntegrityAlgorithm(&msg->selectednassecurityalgorithms),
|
||||
msg->selectednassecurityalgorithms.typeofintegrityalgorithm);
|
||||
|
||||
/* NAS key set identifier */
|
||||
index += snprintf(buffer + index, length - index, ", KSI = ");
|
||||
index += nasKeySetIdentifier(buffer + index, length - index,
|
||||
&msg->naskeysetidentifier);
|
||||
&msg->naskeysetidentifier);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -530,8 +583,11 @@ static int _security_mode_command(char* buffer, int length,
|
||||
* Process Security Mode Complete
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _security_mode_complete(char* buffer, int length,
|
||||
const security_mode_complete_msg* msg)
|
||||
static int
|
||||
_security_mode_complete(
|
||||
char* buffer,
|
||||
int length,
|
||||
const security_mode_complete_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -543,8 +599,11 @@ static int _security_mode_complete(char* buffer, int length,
|
||||
* Process Security Mode Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _security_mode_reject(char* buffer, int length,
|
||||
const security_mode_reject_msg* msg)
|
||||
static int
|
||||
_security_mode_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const security_mode_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -560,8 +619,11 @@ static int _security_mode_reject(char* buffer, int length,
|
||||
* ESM message container
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _esm_message_container(char* buffer, int length,
|
||||
const EsmMessageContainer* msg)
|
||||
static int
|
||||
_esm_message_container(
|
||||
char* buffer,
|
||||
int length,
|
||||
const EsmMessageContainer* msg)
|
||||
{
|
||||
int index = 0;
|
||||
int bytes;
|
||||
@@ -595,7 +657,11 @@ static int _esm_message_container(char* buffer, int length,
|
||||
* Process EMM Status
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _emm_status(char* buffer, int length, const emm_status_msg* msg)
|
||||
static int
|
||||
_emm_status(
|
||||
char* buffer,
|
||||
int length,
|
||||
const emm_status_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -616,95 +682,99 @@ static int _emm_status(char* buffer, int length, const emm_status_msg* msg)
|
||||
* Process EPS Session MAnagement NAS message
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _nas_process_esm(char* buffer, int length, const ESM_msg* msg)
|
||||
static int
|
||||
_nas_process_esm(
|
||||
char* buffer,
|
||||
int length,
|
||||
const ESM_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
printf("INFO\t: Process %s\n", esmMsgType(msg->header.message_type));
|
||||
index += snprintf(buffer + index, length - index, "%s (pti=%d, ebi=%d",
|
||||
esmMsgType(msg->header.message_type),
|
||||
msg->header.procedure_transaction_identity,
|
||||
msg->header.eps_bearer_identity);
|
||||
esmMsgType(msg->header.message_type),
|
||||
msg->header.procedure_transaction_identity,
|
||||
msg->header.eps_bearer_identity);
|
||||
|
||||
switch (msg->header.message_type)
|
||||
{
|
||||
case PDN_CONNECTIVITY_REQUEST:
|
||||
index += _pdn_connectivity_request(buffer + index, length - index,
|
||||
&msg->pdn_connectivity_request);
|
||||
break;
|
||||
case PDN_CONNECTIVITY_REQUEST:
|
||||
index += _pdn_connectivity_request(buffer + index, length - index,
|
||||
&msg->pdn_connectivity_request);
|
||||
break;
|
||||
|
||||
case PDN_CONNECTIVITY_REJECT:
|
||||
index += _pdn_connectivity_reject(buffer + index, length - index,
|
||||
&msg->pdn_connectivity_reject);
|
||||
break;
|
||||
case PDN_CONNECTIVITY_REJECT:
|
||||
index += _pdn_connectivity_reject(buffer + index, length - index,
|
||||
&msg->pdn_connectivity_reject);
|
||||
break;
|
||||
|
||||
case PDN_DISCONNECT_REQUEST:
|
||||
index += _pdn_disconnect_request(buffer + index, length - index,
|
||||
&msg->pdn_disconnect_request);
|
||||
break;
|
||||
case PDN_DISCONNECT_REQUEST:
|
||||
index += _pdn_disconnect_request(buffer + index, length - index,
|
||||
&msg->pdn_disconnect_request);
|
||||
break;
|
||||
|
||||
case PDN_DISCONNECT_REJECT:
|
||||
index += _pdn_disconnect_reject(buffer + index, length - index,
|
||||
&msg->pdn_disconnect_reject);
|
||||
break;
|
||||
case PDN_DISCONNECT_REJECT:
|
||||
index += _pdn_disconnect_reject(buffer + index, length - index,
|
||||
&msg->pdn_disconnect_reject);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _activate_default_eps_bearer_context_request(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_request);
|
||||
break;
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _activate_default_eps_bearer_context_request(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_request);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _activate_default_eps_bearer_context_accept(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_accept);
|
||||
break;
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _activate_default_eps_bearer_context_accept(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_accept);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT:
|
||||
index += _activate_default_eps_bearer_context_reject(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_reject);
|
||||
break;
|
||||
case ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT:
|
||||
index += _activate_default_eps_bearer_context_reject(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_default_eps_bearer_context_reject);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _activate_dedicated_eps_bearer_context_request(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_request);
|
||||
break;
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _activate_dedicated_eps_bearer_context_request(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_request);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _activate_dedicated_eps_bearer_context_accept(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_accept);
|
||||
break;
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _activate_dedicated_eps_bearer_context_accept(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_accept);
|
||||
break;
|
||||
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT:
|
||||
index += _activate_dedicated_eps_bearer_context_reject(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_reject);
|
||||
break;
|
||||
case ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT:
|
||||
index += _activate_dedicated_eps_bearer_context_reject(
|
||||
buffer + index, length - index,
|
||||
&msg->activate_dedicated_eps_bearer_context_reject);
|
||||
break;
|
||||
|
||||
case DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _deactivate_eps_bearer_context_request(buffer + index,
|
||||
length - index,
|
||||
&msg->deactivate_eps_bearer_context_request);
|
||||
break;
|
||||
case DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST:
|
||||
index += _deactivate_eps_bearer_context_request(buffer + index,
|
||||
length - index,
|
||||
&msg->deactivate_eps_bearer_context_request);
|
||||
break;
|
||||
|
||||
case DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _deactivate_eps_bearer_context_accept(buffer + index,
|
||||
length - index,
|
||||
&msg->deactivate_eps_bearer_context_accept);
|
||||
break;
|
||||
case DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT:
|
||||
index += _deactivate_eps_bearer_context_accept(buffer + index,
|
||||
length - index,
|
||||
&msg->deactivate_eps_bearer_context_accept);
|
||||
break;
|
||||
|
||||
case ESM_STATUS:
|
||||
index += _esm_status(buffer + index, length - index,
|
||||
&msg->esm_status);
|
||||
break;
|
||||
case ESM_STATUS:
|
||||
index += _esm_status(buffer + index, length - index,
|
||||
&msg->esm_status);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("WARNING\t: %s - ESM NAS message is not valid (0x%x)\n",
|
||||
__FUNCTION__, msg->header.message_type);
|
||||
break;
|
||||
default:
|
||||
printf("WARNING\t: %s - ESM NAS message is not valid (0x%x)\n",
|
||||
__FUNCTION__, msg->header.message_type);
|
||||
break;
|
||||
}
|
||||
|
||||
index += snprintf(buffer + index, length - index, ")");
|
||||
@@ -714,24 +784,27 @@ static int _nas_process_esm(char* buffer, int length, const ESM_msg* msg)
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process PDN Connectivity Request
|
||||
* Process PDN Connectivity Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _pdn_connectivity_request(char* buffer, int length,
|
||||
const pdn_connectivity_request_msg* msg)
|
||||
static int
|
||||
_pdn_connectivity_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const pdn_connectivity_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* PDN request type and PDN type */
|
||||
index += snprintf(buffer + index, length - index,
|
||||
", RequestType = %s, PdnType = %s",
|
||||
requestType(&msg->requesttype),
|
||||
pdnType(&msg->pdntype));
|
||||
", RequestType = %s, PdnType = %s",
|
||||
requestType(&msg->requesttype),
|
||||
pdnType(&msg->pdntype));
|
||||
/* Access Point Name */
|
||||
if (msg->presencemask & PDN_CONNECTIVITY_REQUEST_ACCESS_POINT_NAME_PRESENT)
|
||||
{
|
||||
index += snprintf(buffer + index, length - index, ", APN = %s",
|
||||
(char*)msg->accesspointname.accesspointnamevalue.value);
|
||||
index += snprintf(buffer + index, length - index, ", APN = %s",
|
||||
(char*)msg->accesspointname.accesspointnamevalue.value);
|
||||
}
|
||||
|
||||
return (index);
|
||||
@@ -739,17 +812,20 @@ static int _pdn_connectivity_request(char* buffer, int length,
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process PDN Connectivity Reject
|
||||
* Process PDN Connectivity Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _pdn_connectivity_reject(char* buffer, int length,
|
||||
const pdn_connectivity_reject_msg* msg)
|
||||
static int
|
||||
_pdn_connectivity_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const pdn_connectivity_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -759,48 +835,57 @@ static int _pdn_connectivity_reject(char* buffer, int length,
|
||||
* Process PDN Disconnect Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _pdn_disconnect_request(char* buffer, int length,
|
||||
const pdn_disconnect_request_msg* msg)
|
||||
static int
|
||||
_pdn_disconnect_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const pdn_disconnect_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* Linked EPS bearer identity */
|
||||
index += snprintf(buffer + index, length - index, ", Linked EBI = %d",
|
||||
msg->linkedepsbeareridentity);
|
||||
msg->linkedepsbeareridentity);
|
||||
|
||||
return (index);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process PDN Disconnect Reject
|
||||
* Process PDN Disconnect Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _pdn_disconnect_reject(char* buffer, int length,
|
||||
const pdn_disconnect_reject_msg* msg)
|
||||
static int
|
||||
_pdn_disconnect_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const pdn_disconnect_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
* Process Activate Default EPS Bearer Context Request
|
||||
* Process Activate Default EPS Bearer Context Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_default_eps_bearer_context_request(char* buffer, int length,
|
||||
const activate_default_eps_bearer_context_request_msg* msg)
|
||||
static int
|
||||
_activate_default_eps_bearer_context_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_default_eps_bearer_context_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* Access Point Name */
|
||||
index += snprintf(buffer + index, length - index, ", APN = %s",
|
||||
(char*)msg->accesspointname.accesspointnamevalue.value);
|
||||
(char*)msg->accesspointname.accesspointnamevalue.value);
|
||||
|
||||
/* PDN address */
|
||||
index += snprintf(buffer + index, length - index, ", PDN addr = ");
|
||||
@@ -814,8 +899,11 @@ static int _activate_default_eps_bearer_context_request(char* buffer, int length
|
||||
* Process Activate Default EPS Bearer Context Accept
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_default_eps_bearer_context_accept(char* buffer, int length,
|
||||
const activate_default_eps_bearer_context_accept_msg* msg)
|
||||
static int
|
||||
_activate_default_eps_bearer_context_accept(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_default_eps_bearer_context_accept_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -827,14 +915,17 @@ static int _activate_default_eps_bearer_context_accept(char* buffer, int length,
|
||||
* Process Activate Default EPS Bearer Context Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_default_eps_bearer_context_reject(char* buffer, int length,
|
||||
const activate_default_eps_bearer_context_reject_msg* msg)
|
||||
static int
|
||||
_activate_default_eps_bearer_context_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_default_eps_bearer_context_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -844,9 +935,11 @@ static int _activate_default_eps_bearer_context_reject(char* buffer, int length,
|
||||
* Process Activate Dedicated EPS Bearer Context Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_dedicated_eps_bearer_context_request(
|
||||
char* buffer, int length,
|
||||
const activate_dedicated_eps_bearer_context_request_msg* msg)
|
||||
static int
|
||||
_activate_dedicated_eps_bearer_context_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_dedicated_eps_bearer_context_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -862,9 +955,11 @@ static int _activate_dedicated_eps_bearer_context_request(
|
||||
* Process Activate Dedicated EPS Bearer Context Accept
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_dedicated_eps_bearer_context_accept(
|
||||
char* buffer, int length,
|
||||
const activate_dedicated_eps_bearer_context_accept_msg* msg)
|
||||
static int
|
||||
_activate_dedicated_eps_bearer_context_accept(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_dedicated_eps_bearer_context_accept_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -876,15 +971,17 @@ static int _activate_dedicated_eps_bearer_context_accept(
|
||||
* Process Activate Dedicated EPS Bearer Context Reject
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _activate_dedicated_eps_bearer_context_reject(
|
||||
char* buffer, int length,
|
||||
const activate_dedicated_eps_bearer_context_reject_msg* msg)
|
||||
static int
|
||||
_activate_dedicated_eps_bearer_context_reject(
|
||||
char* buffer,
|
||||
int length,
|
||||
const activate_dedicated_eps_bearer_context_reject_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -894,14 +991,16 @@ static int _activate_dedicated_eps_bearer_context_reject(
|
||||
* Process Deactivate EPS Bearer Context Request
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _deactivate_eps_bearer_context_request(char* buffer, int length,
|
||||
const deactivate_eps_bearer_context_request_msg* msg)
|
||||
static int _deactivate_eps_bearer_context_request(
|
||||
char* buffer,
|
||||
int length,
|
||||
const deactivate_eps_bearer_context_request_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
@@ -911,8 +1010,11 @@ static int _deactivate_eps_bearer_context_request(char* buffer, int length,
|
||||
* Process Deactivate EPS Bearer Context Accept
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _deactivate_eps_bearer_context_accept(char* buffer, int length,
|
||||
const deactivate_eps_bearer_context_accept_msg* msg)
|
||||
static int
|
||||
_deactivate_eps_bearer_context_accept(
|
||||
char* buffer,
|
||||
int length,
|
||||
const deactivate_eps_bearer_context_accept_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
@@ -924,13 +1026,17 @@ static int _deactivate_eps_bearer_context_accept(char* buffer, int length,
|
||||
* Process ESM Status
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
static int _esm_status(char* buffer, int length, const esm_status_msg* msg)
|
||||
static int
|
||||
_esm_status(
|
||||
char* buffer,
|
||||
int length,
|
||||
const esm_status_msg* msg)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
/* ESM cause code */
|
||||
index += snprintf(buffer + index, length - index, ", EsmCause = %s (%d)",
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
esmCauseCode(msg->esmcause), msg->esmcause);
|
||||
|
||||
return (index);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ AM_CFLAGS = \
|
||||
-DEPC_BUILD \
|
||||
-DENABLE_ITTI \
|
||||
-I$(top_srcdir)/COMMON \
|
||||
-I$(top_srcdir)/SECU \
|
||||
-I$(top_srcdir)/INTERTASK_INTERFACE \
|
||||
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/user \
|
||||
-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/mme \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
libnas_api_SRCS = \
|
||||
EURECOM-NAS/src/api/mme/mme_api.c \
|
||||
EURECOM-NAS/src/api/mme/mme_api.h \
|
||||
EURECOM-NAS/src/api/network/nas_message.c \
|
||||
EURECOM-NAS/src/api/network/nas_message.c \
|
||||
EURECOM-NAS/src/api/network/nas_message.h
|
||||
|
||||
libnas_emm_SRCS = \
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ MME + P-GW + S-GW implementation of 3GPP standard.
|
||||
Controle plane:
|
||||
|
||||
eNB MME HSS
|
||||
|
||||
|
||||
|----------------------------|
|
||||
| MME Application layer |
|
||||
|----------------------------|
|
||||
@@ -88,7 +88,7 @@ Current options supported for configure:
|
||||
code build switch: UPDATE_RELEASE_9 and UPDATE_RELEASE_10
|
||||
NOTE: Release 10 is enabled by default
|
||||
--enable-standalone-epc: all-in-one package, MME, S-GW and P-GW are compiled in a single
|
||||
executable and S11 interface is not used; messages are exchanged internally,
|
||||
executable and S11 interface is not used; messages are exchanged internally,
|
||||
linking MME applicative layer to S+P-GW applicative layer
|
||||
|
||||
How to run EPC environnement ?
|
||||
|
||||
@@ -653,12 +653,18 @@ void s1ap_handle_conn_est_cnf(const mme_app_connection_establishment_cnf_t * con
|
||||
initialContextSetupRequest_p->ueSecurityCapabilities.integrityProtectionAlgorithms.bits_unused
|
||||
= 0;
|
||||
|
||||
// initialContextSetupRequest_p->securityKey.buf = initial_p->keNB; /* 256 bits length */
|
||||
uint8_t keNB[32];
|
||||
memset(keNB, 0, sizeof(keNB));
|
||||
if (conn_est_cnf_pP->keNB) {
|
||||
initialContextSetupRequest_p->securityKey.buf = malloc(32);
|
||||
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;
|
||||
|
||||
if (s1ap_mme_encode_pdu(&message, &buffer_p, &length) < 0) {
|
||||
|
||||
@@ -9,10 +9,15 @@
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
// test
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
|
||||
// #define SECU_DEBUG
|
||||
#define SECU_DEBUG
|
||||
|
||||
/*!
|
||||
* @brief Create integrity cmac t for a given message.
|
||||
@@ -21,19 +26,19 @@
|
||||
*/
|
||||
int nas_stream_encrypt_eia2(nas_stream_cipher_t *stream_cipher, uint8_t out[4])
|
||||
{
|
||||
uint8_t *m;
|
||||
uint32_t local_count;
|
||||
size_t size = 4;
|
||||
|
||||
uint8_t data[16];
|
||||
|
||||
CMAC_CTX *cmac_ctx;
|
||||
|
||||
uint32_t zero_bit = 0;
|
||||
uint32_t m_length;
|
||||
uint8_t *m = NULL;
|
||||
uint32_t local_count;
|
||||
size_t size = 4;
|
||||
uint8_t data[16];
|
||||
CMAC_CTX *cmac_ctx = NULL;
|
||||
const EVP_CIPHER *cipher = EVP_aes_128_cbc();
|
||||
uint32_t zero_bit = 0;
|
||||
uint32_t m_length;
|
||||
int ret;
|
||||
|
||||
DevAssert(stream_cipher != NULL);
|
||||
DevAssert(stream_cipher->key != NULL);
|
||||
DevAssert(stream_cipher->key_length > 0);
|
||||
DevAssert(out != NULL);
|
||||
|
||||
memset(data, 0, 16);
|
||||
@@ -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);
|
||||
for (i = 0; i < m_length + 8; 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");
|
||||
}
|
||||
#endif
|
||||
|
||||
cmac_ctx = CMAC_CTX_new();
|
||||
|
||||
CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, EVP_aes_128_cbc(), NULL);
|
||||
CMAC_Update(cmac_ctx, m, m_length + 8);
|
||||
|
||||
ret = CMAC_Init(cmac_ctx, stream_cipher->key, stream_cipher->key_length, cipher, NULL);
|
||||
#if defined(SECU_DEBUG)
|
||||
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);
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
printf("CMAC_Final returned %d, size = %u\n", ret, size);
|
||||
#endif
|
||||
CMAC_CTX_free(cmac_ctx);
|
||||
|
||||
#if defined(SECU_DEBUG)
|
||||
{
|
||||
int i;
|
||||
printf("out: ");
|
||||
for (i = 0; i < 16; i++)
|
||||
for (i = 0; i < size; i++)
|
||||
printf("%02x", data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
#define EIA1_128_ALG_ID 0x01
|
||||
#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
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user