From 6f5c0332a03537694e57250c4f80683e8be446e6 Mon Sep 17 00:00:00 2001 From: Lionel Gauthier <lionel.gauthier@eurecom.fr> Date: Wed, 7 May 2014 14:47:50 +0000 Subject: [PATCH] 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 --- openair-cn/COMMON/mme_app_messages_types.h | 3 + openair-cn/COMMON/nas_messages_types.h | 2 +- openair-cn/MME_APP/mme_app_bearer.c | 15 +- openair-cn/NAS/EURECOM-NAS/Makefile.inc | 2 +- .../EURECOM-NAS/src/api/network/nas_message.c | 473 +++++++++---- .../EURECOM-NAS/src/api/network/nas_message.h | 36 +- openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c | 62 +- .../NAS/EURECOM-NAS/src/emm/Authentication.c | 8 +- .../NAS/EURECOM-NAS/src/emm/LowerLayer.c | 14 + .../EURECOM-NAS/src/emm/SecurityModeControl.c | 152 +++- openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h | 4 + .../NAS/EURECOM-NAS/src/emm/msg/emm_cause.h | 2 +- .../NAS/EURECOM-NAS/src/emm/sap/emm_as.c | 436 +++++++++--- .../NAS/EURECOM-NAS/src/emm/sap/emm_asDef.h | 4 + .../NAS/EURECOM-NAS/src/emm/sap/emm_cn.c | 13 +- .../NAS/EURECOM-NAS/src/emm/sap/emm_recv.c | 8 +- .../NAS/EURECOM-NAS/src/emm/sap/emm_send.c | 4 +- .../NAS/EURECOM-NAS/src/include/securityDef.h | 4 +- .../tst/as_simulator/nas_process.c | 662 ++++++++++-------- openair-cn/NAS/Makefile.am | 1 + openair-cn/NAS/Makefile.inc | 2 +- openair-cn/README | 4 +- openair-cn/S1AP/s1ap_mme_nas_procedures.c | 16 +- openair-cn/SECU/nas_stream_eia2.c | 51 +- openair-cn/SECU/secu_defs.h | 7 + 25 files changed, 1366 insertions(+), 619 deletions(-) diff --git a/openair-cn/COMMON/mme_app_messages_types.h b/openair-cn/COMMON/mme_app_messages_types.h index ca5b205fb1..3b2f08d55e 100644 --- a/openair-cn/COMMON/mme_app_messages_types.h +++ b/openair-cn/COMMON/mme_app_messages_types.h @@ -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; diff --git a/openair-cn/COMMON/nas_messages_types.h b/openair-cn/COMMON/nas_messages_types.h index ec2d751c8c..b66f9f16a9 100644 --- a/openair-cn/COMMON/nas_messages_types.h +++ b/openair-cn/COMMON/nas_messages_types.h @@ -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; diff --git a/openair-cn/MME_APP/mme_app_bearer.c b/openair-cn/MME_APP/mme_app_bearer.c index bf8ebb09da..de87e4c660 100644 --- a/openair-cn/MME_APP/mme_app_bearer.c +++ b/openair-cn/MME_APP/mme_app_bearer.c @@ -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 diff --git a/openair-cn/NAS/EURECOM-NAS/Makefile.inc b/openair-cn/NAS/EURECOM-NAS/Makefile.inc index 1efed2d9da..314a445766 100644 --- a/openair-cn/NAS/EURECOM-NAS/Makefile.inc +++ b/openair-cn/NAS/EURECOM-NAS/Makefile.inc @@ -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 diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c index 5161a44dc0..2153eafe0d 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c +++ b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.c @@ -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); - } - - /* 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; + /* 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; } 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); +#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); + LOG_FUNC_RETURN (0xabababab); #endif + break; + + default: + AssertFatal(0 , + "Unknown integrity protection algorithm %d", + emm_security_context->selected_algorithms.integrity); + } + LOG_FUNC_RETURN (0); } diff --git a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.h b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.h index ab78123b24..c90b4c00dd 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.h +++ b/openair-cn/NAS/EURECOM-NAS/src/api/network/nas_message.h @@ -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_decrypt(const char *inbuf, char *outbuf, - nas_message_security_header_t *header, int length); - -int nas_message_decode(const char * const buffer, nas_message_t *msg, int length); - -int nas_message_encode(char *buffer, const nas_message_t * const msg, 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, + void *security); + +int nas_message_decode( + const char * const buffer, + nas_message_t *msg, + int length, + void *security); + +int nas_message_encode( + char *buffer, + const nas_message_t * const msg, + int length, + void *security); #endif /* __NAS_MESSAGE_H__*/ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c index 6bfb52521a..d308432b2d 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Attach.c @@ -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 diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c index 0346101068..acf4fa88a9 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/Authentication.c @@ -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; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c index 49042cea1c..50a7a99458 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/LowerLayer.c @@ -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; } diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c index 8027d81ece..1492f27afa 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/SecurityModeControl.c @@ -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 diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h index a15a664d06..afc061fb4e 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/emmData.h @@ -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; /* diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/msg/emm_cause.h b/openair-cn/NAS/EURECOM-NAS/src/emm/msg/emm_cause.h index 8d7dc3cbe8..77f17f6889 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/msg/emm_cause.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/msg/emm_cause.h @@ -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 diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c index 37b39b1143..9315bc4abd 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_as.c @@ -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); diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_asDef.h b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_asDef.h index b5171339da..eaa0a943f4 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_asDef.h +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_asDef.h @@ -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 */ diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c index b44b3cc174..ddc005f0c1 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_cn.c @@ -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 - " diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_recv.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_recv.c index dcd5ad4692..2b3f69507b 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_recv.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_recv.c @@ -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; diff --git a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_send.c b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_send.c index 68703ff0c4..7401ef6fda 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_send.c +++ b/openair-cn/NAS/EURECOM-NAS/src/emm/sap/emm_send.c @@ -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; diff --git a/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h b/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h index 605f14b71b..3e75f04732 100644 --- a/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h +++ b/openair-cn/NAS/EURECOM-NAS/src/include/securityDef.h @@ -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 */ diff --git a/openair-cn/NAS/EURECOM-NAS/tst/as_simulator/nas_process.c b/openair-cn/NAS/EURECOM-NAS/tst/as_simulator/nas_process.c index 2dac50c923..de4a66f3af 100644 --- a/openair-cn/NAS/EURECOM-NAS/tst/as_simulator/nas_process.c +++ b/openair-cn/NAS/EURECOM-NAS/tst/as_simulator/nas_process.c @@ -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_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_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_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_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_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_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_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 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; + 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_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 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 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 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_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 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_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; + + 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_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_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_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_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_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_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; - - default: - printf("WARNING\t: %s - ESM NAS message is not valid (0x%x)\n", - __FUNCTION__, msg->header.message_type); - 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_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 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_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_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 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 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; } 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); } diff --git a/openair-cn/NAS/Makefile.am b/openair-cn/NAS/Makefile.am index 91ddf3358c..302e96edc2 100644 --- a/openair-cn/NAS/Makefile.am +++ b/openair-cn/NAS/Makefile.am @@ -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 \ diff --git a/openair-cn/NAS/Makefile.inc b/openair-cn/NAS/Makefile.inc index 8e66de5609..3222655e1b 100644 --- a/openair-cn/NAS/Makefile.inc +++ b/openair-cn/NAS/Makefile.inc @@ -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 = \ diff --git a/openair-cn/README b/openair-cn/README index 08c7575eb9..e3205fb798 100644 --- a/openair-cn/README +++ b/openair-cn/README @@ -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 ? diff --git a/openair-cn/S1AP/s1ap_mme_nas_procedures.c b/openair-cn/S1AP/s1ap_mme_nas_procedures.c index 2bc27ee822..273c4467d1 100644 --- a/openair-cn/S1AP/s1ap_mme_nas_procedures.c +++ b/openair-cn/S1AP/s1ap_mme_nas_procedures.c @@ -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) { diff --git a/openair-cn/SECU/nas_stream_eia2.c b/openair-cn/SECU/nas_stream_eia2.c index 5942498813..517d388098 100644 --- a/openair-cn/SECU/nas_stream_eia2.c +++ b/openair-cn/SECU/nas_stream_eia2.c @@ -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"); } diff --git a/openair-cn/SECU/secu_defs.h b/openair-cn/SECU/secu_defs.h index 8987f55edd..6be6db2c8c 100644 --- a/openair-cn/SECU/secu_defs.h +++ b/openair-cn/SECU/secu_defs.h @@ -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); -- 2.26.2