From bcb275dadcf1f52afdaece424b4f44fd38cd1ec1 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 8 Mar 2017 19:10:01 +0900 Subject: [PATCH] NAS MAC is added, but not verified --- lib/nas/nas_encoder.c | 2 ++ src/mme/context.c | 3 +- src/mme/context.h | 2 ++ src/mme/nas_security.c | 68 +++++++++++++++++++++++++++++++++++++++++- src/mme/nas_security.h | 8 +++++ src/mme/ue_emm_sm.c | 6 +++- test/nas_sm_test.c | 24 +++++++++++++++ 7 files changed, 110 insertions(+), 3 deletions(-) diff --git a/lib/nas/nas_encoder.c b/lib/nas/nas_encoder.c index fefe3c369..6ebf4b97e 100644 --- a/lib/nas/nas_encoder.c +++ b/lib/nas/nas_encoder.c @@ -349,6 +349,8 @@ status_t nas_encode_pdu(pkbuf_t **pkbuf, nas_message_t *message) size = sizeof(nas_header_t); rv = pkbuf_header(*pkbuf, -size); d_assert(rv == CORE_OK, return CORE_ERROR, "pkbuf_header error"); + + message->h.security_header_type = 0; memcpy((*pkbuf)->payload - size, &message->h, size); encoded += size; diff --git a/src/mme/context.c b/src/mme/context.c index ad9d1f16f..6822bd3bd 100644 --- a/src/mme/context.c +++ b/src/mme/context.c @@ -195,10 +195,11 @@ ue_ctx_t* mme_ctx_ue_add(enb_ctx_t *enb) ue->enb = enb; list_init(&ue->rab_list); - self.mme_ue_s1ap_id = self.mme_ue_s1ap_id + 1; if (self.mme_ue_s1ap_id == 0) self.mme_ue_s1ap_id = 1; ue->mme_ue_s1ap_id = self.mme_ue_s1ap_id; + self.mme_ue_s1ap_id = self.mme_ue_s1ap_id + 1; + list_append(&enb->ue_list, ue); return ue; diff --git a/src/mme/context.h b/src/mme/context.h index 37a2b8c2e..9d998e194 100644 --- a/src/mme/context.h +++ b/src/mme/context.h @@ -104,6 +104,8 @@ typedef struct _ue_ctx_t { c_uint8_t kasme[SHA256_DIGEST_SIZE]; c_uint8_t knas_int[SHA256_DIGEST_SIZE/2]; c_uint8_t knas_enc[SHA256_DIGEST_SIZE/2]; + c_uint32_t dl_count; + c_uint32_t ul_count; /* Related Context for UE */ rab_list_t rab_list; diff --git a/src/mme/nas_security.c b/src/mme/nas_security.c index 099c49ec1..80022f361 100644 --- a/src/mme/nas_security.c +++ b/src/mme/nas_security.c @@ -2,9 +2,75 @@ #include "core_debug.h" -#include "nas_ies.h" +#include "context.h" +#include "nas_message.h" #include "nas_security.h" +status_t nas_security_encode(pkbuf_t **pkbuf, + ue_ctx_t *ue, nas_message_t *message) +{ + d_assert(ue, return CORE_ERROR, "Null param"); + d_assert(message, return CORE_ERROR, "Null param"); + + switch(message->h.security_header_type) + { + case NAS_SECURITY_HEADER_PLAIN_NAS_MESSAGE: + { + return nas_encode_pdu(pkbuf, message); + } + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT: + { + ue->dl_count = 0; + ue->ul_count = 0; + } + case NAS_SECURITY_HEADER_INTEGRITY_PROTECTED: + { + nas_security_header_t h; + c_uint8_t mac[4]; + pkbuf_t *new = NULL; + + memset(&h, 0, sizeof(nas_security_header_t)); + h.security_header_type = message->h.security_header_type; + h.protocol_discriminator = message->h.protocol_discriminator; + h.sequence_number = (ue->dl_count & 0xff); + + d_assert(nas_encode_pdu(&new, message) == CORE_OK, + return CORE_ERROR, + "NAS encoding error"); + + d_assert(CORE_OK == pkbuf_header(new, sizeof(h.sequence_number)), + pkbuf_free(new);return CORE_ERROR, + "pkbuf_header error"); + *(c_uint8_t *)(new->payload) = h.sequence_number; + + nas_mac_calculate(mme_self()->selected_int_algorithm, + ue->knas_int, ue->dl_count, NAS_SECURITY_BEARER, + NAS_SECURITY_DOWNLINK_DIRECTION, new, mac); + d_print_hex(mac, 4); + + d_assert(CORE_OK == pkbuf_header(new, + sizeof(nas_security_header_t) - sizeof(h.sequence_number)), + pkbuf_free(new);return CORE_ERROR, + "pkbuf_header error"); + memcpy(new->payload, &h, sizeof(nas_security_header_t)); + memcpy(new->payload+1, mac, sizeof(mac)); + + ue->dl_count = (ue->dl_count + 1) & 0xffffff; /* Use 24bit */ + + *pkbuf = new; + break; + } + default: + { + d_warn("Not implemented(securiry header type:0x%x)", + message->h.security_header_type); + return CORE_ERROR; + } + } + + return CORE_OK; +} + void nas_mac_calculate(c_uint8_t algorithm_identity, c_uint8_t *knas_int, c_uint32_t count, c_uint8_t bearer, c_uint8_t direction, pkbuf_t *pkbuf, c_uint8_t *mac) diff --git a/src/mme/nas_security.h b/src/mme/nas_security.h index d7d0cdff9..de18a244e 100644 --- a/src/mme/nas_security.h +++ b/src/mme/nas_security.h @@ -5,13 +5,21 @@ #include "core_aes.h" #include "core_aes_cmac.h" +#include "context.h" #include "snow_3g.h" #include "zuc.h" +#define NAS_SECURITY_BEARER 0 +#define NAS_SECURITY_DOWNLINK_DIRECTION 1 +#define NAS_SECURITY_UPLINK_DIRECTION 0 + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +CORE_DECLARE(status_t) nas_security_encode(pkbuf_t **pkbuf, + ue_ctx_t *ue, nas_message_t *message); + CORE_DECLARE(void) nas_mac_calculate(c_uint8_t algorithm_identity, c_uint8_t *knas_int, c_uint32_t count, c_uint8_t bearer, c_uint8_t direction, pkbuf_t *pkbuf, c_uint8_t *mac); diff --git a/src/mme/ue_emm_sm.c b/src/mme/ue_emm_sm.c index 767d08152..8f25efef7 100644 --- a/src/mme/ue_emm_sm.c +++ b/src/mme/ue_emm_sm.c @@ -10,6 +10,7 @@ #include "event.h" #include "kdf.h" +#include "nas_security.h" #include "s1ap_path.h" #include "s1ap_conv.h" #include "nas_conv.h" @@ -257,7 +258,10 @@ static void ue_emm_handle_authentication_response( mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_self()->selected_enc_algorithm, ue->kasme, ue->knas_enc); - d_assert(nas_encode_pdu(&sendbuf, &message) == CORE_OK && sendbuf,,); + message.h.security_header_type = + NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT; + d_assert(nas_security_encode(&sendbuf, ue, &message) == CORE_OK && + sendbuf,,); ue_emm_send_to_enb(ue, sendbuf); d_assert(ue->imsi, return,); diff --git a/test/nas_sm_test.c b/test/nas_sm_test.c index 9a9beea35..a35009b75 100644 --- a/test/nas_sm_test.c +++ b/test/nas_sm_test.c @@ -1,6 +1,8 @@ #include "core_debug.h" #include "core_pkbuf.h" +#include "core_lib.h" +#include "mme/context.h" #include "s1ap_message.h" #include "testutil.h" @@ -16,6 +18,14 @@ static void nas_sm_test1(abts_case *tc, void *data) int rc; int i; + c_uint8_t tmp[MESSAGE_SDU_SIZE]; + char *_authentication_request = + "000b403b00000300 000005c00100009d 000800020001001a 0025240752002008" + "0c3818183b522614 162c07601d0d10f1 1b89a2a8de8000ad 0ccf7f55e8b20d"; + char *_security_mode_command = + "000b402700000300 000005c00100009d 000800020001001a 00111037f933b5d5" + "00075d010005e060 c04070"; + /* eNB connects to MME */ sock = tests1ap_enb_connect(); ABTS_PTR_NOTNULL(tc, sock); @@ -37,6 +47,7 @@ static void nas_sm_test1(abts_case *tc, void *data) pkbuf_free(recvbuf); /* Send Initial-UE Message */ + mme_self()->mme_ue_s1ap_id = 16777373; rv = tests1ap_build_initial_ue_msg(&sendbuf); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf); @@ -47,6 +58,12 @@ static void nas_sm_test1(abts_case *tc, void *data) recvbuf = pkbuf_alloc(0, MESSAGE_SDU_SIZE); rc = tests1ap_enb_read(sock, recvbuf); ABTS_INT_NEQUAL(tc, 0, rc); + recvbuf->len = 63; + + ABTS_TRUE(tc, memcmp(recvbuf->payload, + core_ascii_to_hex(_authentication_request, + strlen(_authentication_request), tmp, sizeof(tmp)), + recvbuf->len) == 0); pkbuf_free(recvbuf); /* Send Authentication-Response */ @@ -59,6 +76,13 @@ static void nas_sm_test1(abts_case *tc, void *data) /* Receive Security-mode-Command */ recvbuf = pkbuf_alloc(0, MESSAGE_SDU_SIZE); rc = tests1ap_enb_read(sock, recvbuf); + recvbuf->len = 43; + + core_ascii_to_hex(_security_mode_command, + strlen(_security_mode_command), tmp, sizeof(tmp)); + d_print_hex(tmp, recvbuf->len); + d_print_hex(recvbuf->payload, recvbuf->len); + ABTS_INT_NEQUAL(tc, 0, rc); pkbuf_free(recvbuf);