intermediate..

We should decode NAS message, and then integrity is checked later.
Because, To get MME UE Context, at first, we need to know GUTI in NAS
message.
if S-TMSI is not available.. Sigh!

if NAS is ciphered, The seqence are 'Decrypt->Decode->Integrity Check'
if NAS is not cihpered, The sequence are 'Decode->Integrity Check'
This commit is contained in:
Sukchan Lee 2017-07-27 21:50:55 +09:00
parent 0a8f389839
commit 345ef20934
7 changed files with 143 additions and 50 deletions

View File

@ -25,6 +25,8 @@ mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message)
{
mme_ue_t *mme_ue = NULL;
d_assert(enb_ue, return NULL, "Null param");
switch(message->emm.h.message_type)
{
case NAS_ATTACH_REQUEST:
@ -68,6 +70,18 @@ mme_ue_t *emm_find_ue_by_message(enb_ue_t *enb_ue, nas_message_t *message)
guti.m_tmsi);
mme_ue = mme_ue_find_by_guti(&guti);
if (!mme_ue)
{
d_warn("Cannot find mme_ue by "
"GUTI[G:%d,C:%d,M_TMSI:0x%x]\n",
guti.mme_gid,
guti.mme_code,
guti.m_tmsi);
}
else
{
mme_associate_ue_context(mme_ue, enb_ue);
}
break;
}
default:
@ -203,27 +217,32 @@ void emm_handle_attach_request(
d_info("[NAS] Attach request : UE_IMSI[%s] --> EMM", imsi_bcd);
if (mme_ue->security_context_available)
if (!mme_ue->security_context_available)
{
if (enb_ue->mac_failed)
/* Initiate HSS Auth Process if No Security Context */
mme_s6a_send_air(mme_ue);
}
else
{
/* if Security Context is Existed */
if (!enb_ue->mac_failed)
{
/* MAC verified */
emm_handle_attach_accept(mme_ue);
}
else
{
/* Initiate Delete Session if MAC integrity Failed */
int delete_session_request_handled = 0;
emm_handle_delete_session_request(
mme_ue, &delete_session_request_handled);
if (!delete_session_request_handled)
{
/* Initiate HSS Auth Process if No Session */
mme_s6a_send_air(mme_ue);
}
}
else
{
emm_handle_attach_accept(mme_ue);
}
}
else
{
mme_s6a_send_air(mme_ue);
}
break;
@ -244,37 +263,43 @@ void emm_handle_attach_request(
guti.mme_code,
guti.m_tmsi);
/* FIXME :Check if GUTI was assigend from us */
/* FIXME :If not, forward the message to other MME */
/* FIXME : Find UE based on GUTI.
* The record with GUTI,IMSI should be
* stored in permanent DB
*/
if (mme_ue->security_context_available)
if (memcmp(&guti, &mme_ue->guti, sizeof(guti_t)) == 0)
{
if (enb_ue->mac_failed)
/* Known GUTI */
if (!mme_ue->security_context_available)
{
d_assert(0, return, "Not Implmeneted");
/* Initiate HSS Auth Process if No Security Context */
mme_s6a_send_air(mme_ue);
}
else
{
if (memcmp(&guti, &mme_ue->guti, sizeof(guti_t)) != 0)
/* if Security Context is Existed */
if (!enb_ue->mac_failed)
{
emm_handle_identity_request(mme_ue);
/* MAC verified */
emm_handle_attach_accept(mme_ue);
}
else
{
emm_handle_attach_accept(mme_ue);
/* Initiate Delete Session if MAC integrity Failed */
int delete_session_request_handled = 0;
emm_handle_delete_session_request(
mme_ue, &delete_session_request_handled);
if (!delete_session_request_handled)
{
/* Initiate HSS Auth Process if No Session */
mme_s6a_send_air(mme_ue);
}
}
}
}
else
{
d_assert(0, return, "Not Implmeneted");
/* Unknown GUTI */
emm_handle_identity_request(mme_ue);
}
break;
}
default:
@ -349,27 +374,32 @@ void emm_handle_identity_response(
return;
}
if (mme_ue->security_context_available)
if (!mme_ue->security_context_available)
{
if (enb_ue->mac_failed)
/* Initiate HSS Auth Process if No Security Context */
mme_s6a_send_air(mme_ue);
}
else
{
/* if Security Context is Existed */
if (!enb_ue->mac_failed)
{
/* MAC verified */
emm_handle_attach_accept(mme_ue);
}
else
{
/* Initiate Delete Session if MAC integrity Failed */
int delete_session_request_handled = 0;
emm_handle_delete_session_request(
mme_ue, &delete_session_request_handled);
if (!delete_session_request_handled)
{
/* Initiate HSS Auth Process if No Session */
mme_s6a_send_air(mme_ue);
}
}
else
{
emm_handle_attach_accept(mme_ue);
}
}
else
{
mme_s6a_send_air(mme_ue);
}
}

View File

@ -988,6 +988,12 @@ status_t mme_ue_remove(mme_ue_t *mme_ue)
fsm_final(&mme_ue->sm, 0);
fsm_clear(&mme_ue->sm);
/* Clear hash table */
if (mme_ue->guti.m_tmsi != 0)
hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), NULL);
if (mme_ue->imsi_len != 0)
hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, NULL);
mme_sess_remove_all(mme_ue);
mme_pdn_remove_all(mme_ue);
@ -1077,6 +1083,13 @@ static status_t mme_ue_new_guti(mme_ue_t *mme_ue)
d_assert(served_gummei->num_of_mme_code > 0,
return CORE_ERROR, "Invalid param");
if (mme_ue->guti.m_tmsi != 0)
{
/* MME has a VALID GUIT
* As such, we need to remove previous GUTI in hash table */
hash_set(self.guti_ue_hash, &mme_ue->guti, sizeof(guti_t), NULL);
}
memset(&mme_ue->guti, 0, sizeof(guti_t));
/* FIXME : How to generate GUTI?
@ -1106,6 +1119,18 @@ status_t mme_ue_set_imsi(mme_ue_t *mme_ue, c_int8_t *imsi_bcd)
return CORE_OK;
}
status_t mme_associate_ue_context(mme_ue_t *mme_ue, enb_ue_t *enb_ue)
{
d_assert(mme_ue, return CORE_ERROR, "Null param");
d_assert(enb_ue, return CORE_ERROR, "Null param");
mme_ue->enb_ue = enb_ue;
enb_ue->mme_ue = mme_ue;
return CORE_OK;
}
#if 0
unsigned int mme_ue_count()
{

View File

@ -282,13 +282,16 @@ CORE_DECLARE(mme_ue_t*) mme_ue_add(enb_ue_t *enb_ue);
CORE_DECLARE(status_t) mme_ue_remove(mme_ue_t *mme_ue);
CORE_DECLARE(status_t) mme_ue_remove_all();
CORE_DECLARE(status_t) mme_ue_set_imsi(
mme_ue_t *mme_ue, c_int8_t *imsi_bcd);
CORE_DECLARE(mme_ue_t*) mme_ue_find(index_t index);
CORE_DECLARE(mme_ue_t*) mme_ue_find_by_imsi(c_uint8_t *imsi, int imsi_len);
CORE_DECLARE(mme_ue_t*) mme_ue_find_by_imsi_bcd(c_int8_t *imsi_bcd);
CORE_DECLARE(mme_ue_t*) mme_ue_find_by_guti(guti_t *guti);
CORE_DECLARE(status_t) mme_ue_set_imsi(
mme_ue_t *mme_ue, c_int8_t *imsi_bcd);
CORE_DECLARE(status_t) mme_associate_ue_context(
mme_ue_t *mme_ue, enb_ue_t *enb_ue);
CORE_DECLARE(hash_index_t *) mme_ue_first();
CORE_DECLARE(hash_index_t *) mme_ue_next(hash_index_t *hi);
CORE_DECLARE(mme_ue_t *) mme_ue_this(hash_index_t *hi);

View File

@ -243,7 +243,7 @@ status_t nas_security_decode(mme_ue_t *mme_ue, pkbuf_t *pkbuf, int *mac_failed)
memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE);
if (h->message_authentication_code != mac32)
{
d_error("NAS MAC verification failed(0x%x != 0x%x)",
d_warn("NAS MAC verification failed(0x%x != 0x%x)",
ntohl(h->message_authentication_code), ntohl(mac32));
*mac_failed = 1;
}

View File

@ -212,8 +212,7 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, s1ap_message_t *message)
}
else
{
mme_ue->enb_ue = enb_ue;
enb_ue->mme_ue = mme_ue;
mme_associate_ue_context(mme_ue, enb_ue);
}
}
}

View File

@ -1,8 +1,8 @@
#include <mongoc.h>
#include "core_debug.h"
#include "core_pkbuf.h"
#include "core_lib.h"
#include <mongoc.h>
#include "context.h"
#include "mme_context.h"
@ -237,6 +237,16 @@ static void nas_sm_test1(abts_case *tc, void *data)
rv = tests1ap_enb_send(sock, sendbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
core_sleep(time_from_msec(300));
/* Send Initial-UE Message */
#if 0
rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+1);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tests1ap_enb_send(sock, sendbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
#endif
/* eNB disonncect from MME */
rv = tests1ap_enb_close(sock);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -419,14 +429,31 @@ static void nas_sm_test2(abts_case *tc, void *data)
core_sleep(time_from_msec(300));
/* Send Initial-UE Message */
#if 0
rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+1);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tests1ap_enb_send(sock, sendbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
#endif
core_sleep(time_from_msec(300));
/* Receive Initial Context Setup Request +
* Attach Accept +
* Activate Default Bearer Context Request */
recvbuf = pkbuf_alloc(0, MAX_SDU_LEN);
rc = tests1ap_enb_read(sock, recvbuf);
recvbuf->len = 223;
pkbuf_free(recvbuf);
/* Send Initial-UE Message with MAC failed */
rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex+2);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tests1ap_enb_send(sock, sendbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
/* Receive Authentication Request */
recvbuf = pkbuf_alloc(0, MAX_SDU_LEN);
rc = tests1ap_enb_read(sock, recvbuf);
ABTS_INT_NEQUAL(tc, 0, rc);
recvbuf->len = 60;
pkbuf_free(recvbuf);
/* eNB disonncect from MME */
rv = tests1ap_enb_close(sock);
@ -544,6 +571,9 @@ static void nas_sm_test3(abts_case *tc, void *data)
MONGOC_INSERT_NONE, doc, NULL, &error));
bson_destroy(doc);
mme_self()->mme_ue_s1ap_id = 33554631;
mme_self()->m_tmsi = 2;
d_log_set_level(D_MSG_TO_STDOUT, D_LOG_LEVEL_ERROR);
/* eNB connects to MME */
@ -566,7 +596,6 @@ static void nas_sm_test3(abts_case *tc, void *data)
pkbuf_free(recvbuf);
/* Send Initial-UE Message */
mme_self()->mme_ue_s1ap_id = 33554631;
rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
rv = tests1ap_enb_send(sock, sendbuf);

View File

@ -121,7 +121,12 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i)
"3254869104e060c0 4000050221d011d1 5c0a003103e5e034 9011035758a65d01"
"00004300060000f1 105ba00064400800 00f1101079baf000 86400130",
"",
"000c40809c00"
"0005000800030001 00001a007372178c 3e3cff070741020b f600f11000020100"
"00000105e060c040 0100210204d011d1 271a808021100100 0010810600000000"
"830600000000000d 00000a005255f501 10225c0a003103e5 c03e1355f501aaaa"
"11035758a6200b60 1404ef65233b8878 d290400804026004 00021f025d0107e0"
"004300060055f501 1022006440080055 f5010019d0100086 400130",
"",
"000c406800000500 080002001f001a00 403f074172080910 10103254866202e0"
@ -133,7 +138,9 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i)
"103254866205f0f0 000000000e023cd0 11d1270780000a00 000d00c100430006"
"0000f1102b670064 40080000f1109d67 aa500086400130",
"",
"000c405300000500 080003001f00001a 002a2917bcba67c4 8207410108091010"
"103254866205f0f0 000000000e023cd0 11d1270780000a00 000d00c100430006"
"0000f1102b670064 40080000f1109d67 aa500086400130",
"000c"
"404c000005000800 020002001a002423 0741710809101010 3254767905f0f000"
@ -145,12 +152,12 @@ status_t tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i)
};
c_uint16_t len[TESTS1AP_MAX_MESSAGE] = {
92,
0,
161,
0,
108,
87,
0,
87,
80,
0,