From 715e4c0b506357ee57df3a827ae2cbf0cadf6209 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Wed, 5 Jan 2022 22:39:06 +0900 Subject: [PATCH] Shall cipher in the NAS message container IE 3GPP TS 24.501 version 16.6.0 Release 16 4.4 NAS security 4.4.6 Protection of initial NAS signalling messages 1) the UE needs to send non-cleartext IEs in a REGISTRATION REQUEST or SERVICE REQUEST message, the UE includes the entire REGISTRATION REQUEST or SERVICE REQUEST message (i.e. containing both cleartext IEs and non-cleartext IEs) in the NAS message container IE and shall cipher the value part of the NAS message container IE. The UE shall then send a REGISTRATION REQUEST or SERVICE REQUEST message containing the cleartext IEs and the NAS message container IE; --- lib/nas/common/security.h | 3 +++ src/amf/gmm-handler.c | 46 +++++++++++++++++++++++++++++++++---- src/amf/nas-security.c | 11 ++++----- src/mme/nas-security.c | 13 ++++------- tests/common/gmm-build.c | 28 ++++++++++++++++++++++ tests/common/nas-security.c | 19 +++++++-------- 6 files changed, 89 insertions(+), 31 deletions(-) diff --git a/lib/nas/common/security.h b/lib/nas/common/security.h index 465fa2f7a..3b02059a3 100644 --- a/lib/nas/common/security.h +++ b/lib/nas/common/security.h @@ -28,6 +28,9 @@ extern "C" { #endif +#define OGS_NAS_SECURITY_DOWNLINK_DIRECTION 1 +#define OGS_NAS_SECURITY_UPLINK_DIRECTION 0 + void ogs_nas_mac_calculate(uint8_t algorithm_identity, uint8_t *knas_int, uint32_t count, uint8_t bearer, uint8_t direction, ogs_pkbuf_t *pkbuf, uint8_t *mac); diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 0f71a0a24..5118c7b96 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -28,7 +28,8 @@ #undef OGS_LOG_DOMAIN #define OGS_LOG_DOMAIN __gmm_log_domain -static int gmm_handle_nas_message_container(amf_ue_t *amf_ue, +static int gmm_handle_nas_message_container( + amf_ue_t *amf_ue, uint8_t message_type, ogs_nas_message_container_t *nas_message_container); int gmm_handle_registration_request(amf_ue_t *amf_ue, @@ -316,7 +317,8 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue, OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) { return gmm_handle_nas_message_container( - amf_ue, ®istration_request->nas_message_container); + amf_ue, OGS_NAS_5GS_REGISTRATION_REQUEST, + ®istration_request->nas_message_container); } if (registration_request->presencemask & @@ -585,7 +587,8 @@ int gmm_handle_service_update(amf_ue_t *amf_ue, OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) { return gmm_handle_nas_message_container( - amf_ue, &service_request->nas_message_container); + amf_ue, OGS_NAS_5GS_SERVICE_REQUEST, + &service_request->nas_message_container); } xact_count = amf_sess_xact_count(amf_ue); @@ -873,7 +876,8 @@ int gmm_handle_security_mode_complete(amf_ue_t *amf_ue, OGS_NAS_5GS_SECURITY_MODE_COMPLETE_NAS_MESSAGE_CONTAINER_PRESENT) { return gmm_handle_nas_message_container( - amf_ue, &security_mode_complete->nas_message_container); + amf_ue, OGS_NAS_5GS_SECURITY_MODE_COMPLETE, + &security_mode_complete->nas_message_container); } return OGS_OK; @@ -1158,7 +1162,8 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, return OGS_OK; } -static int gmm_handle_nas_message_container(amf_ue_t *amf_ue, +static int gmm_handle_nas_message_container( + amf_ue_t *amf_ue, uint8_t message_type, ogs_nas_message_container_t *nas_message_container) { int rv = OGS_ERROR; @@ -1180,6 +1185,37 @@ static int gmm_handle_nas_message_container(amf_ue_t *amf_ue, ogs_pkbuf_put_data(nasbuf, nas_message_container->buffer, nas_message_container->length); + /* + * 3GPP TS 24.501 version 16.6.0 Release 16 + * 4.4 NAS security + * 4.4.6 Protection of initial NAS signalling messages + * + * 1) the UE needs to send non-cleartext IEs in a REGISTRATION REQUEST + * or SERVICE REQUEST message, the UE includes the entire REGISTRATION + * REQUEST or SERVICE REQUEST message (i.e. containing both cleartext IEs + * and non-cleartext IEs) in the NAS message container IE and shall cipher + * the value part of the NAS message container IE. The UE shall then send + * a REGISTRATION REQUEST or SERVICE REQUEST message containing + * the cleartext IEs and the NAS message container IE; + */ + switch (message_type) { + case OGS_NAS_5GS_REGISTRATION_REQUEST: + case OGS_NAS_5GS_SERVICE_REQUEST: + switch (amf_ue->selected_enc_algorithm) { + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA1: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA2: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA3: + ogs_nas_encrypt(amf_ue->selected_enc_algorithm, + amf_ue->knas_enc, amf_ue->ul_count.i32, + amf_ue->nas.access_type, + OGS_NAS_SECURITY_UPLINK_DIRECTION, nasbuf); + default: + break; + } + default: + break; + } + if (ogs_nas_5gmm_decode(&nas_message, nasbuf) != OGS_OK) { ogs_error("ogs_nas_5gmm_decode() failed"); ogs_pkbuf_free(nasbuf); diff --git a/src/amf/nas-security.c b/src/amf/nas-security.c index 04df18557..043b8cb63 100644 --- a/src/amf/nas-security.c +++ b/src/amf/nas-security.c @@ -19,9 +19,6 @@ #include "nas-security.h" -#define NAS_SECURITY_DOWNLINK_DIRECTION 1 -#define NAS_SECURITY_UPLINK_DIRECTION 0 - #define NAS_SECURITY_MAC_SIZE 4 ogs_pkbuf_t *nas_5gs_security_encode( @@ -88,7 +85,7 @@ ogs_pkbuf_t *nas_5gs_security_encode( ogs_nas_encrypt(amf_ue->selected_enc_algorithm, amf_ue->knas_enc, amf_ue->dl_count, amf_ue->nas.access_type, - NAS_SECURITY_DOWNLINK_DIRECTION, new); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, new); } /* encode sequence number */ @@ -102,7 +99,7 @@ ogs_pkbuf_t *nas_5gs_security_encode( ogs_nas_mac_calculate(amf_ue->selected_int_algorithm, amf_ue->knas_int, amf_ue->dl_count, amf_ue->nas.access_type, - NAS_SECURITY_DOWNLINK_DIRECTION, new, mac); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, new, mac); memcpy(&h.message_authentication_code, mac, sizeof(mac)); } @@ -165,7 +162,7 @@ int nas_5gs_security_decode(amf_ue_t *amf_ue, ogs_nas_mac_calculate(amf_ue->selected_int_algorithm, amf_ue->knas_int, amf_ue->ul_count.i32, amf_ue->nas.access_type, - NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); + OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); h->message_authentication_code = original_mac; memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); @@ -184,7 +181,7 @@ int nas_5gs_security_decode(amf_ue_t *amf_ue, ogs_nas_encrypt(amf_ue->selected_enc_algorithm, amf_ue->knas_enc, amf_ue->ul_count.i32, amf_ue->nas.access_type, - NAS_SECURITY_UPLINK_DIRECTION, pkbuf); + OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf); } } diff --git a/src/mme/nas-security.c b/src/mme/nas-security.c index b13608a93..498dd8d6b 100644 --- a/src/mme/nas-security.c +++ b/src/mme/nas-security.c @@ -20,9 +20,6 @@ #include "nas-security.h" #define NAS_SECURITY_BEARER 0 -#define NAS_SECURITY_DOWNLINK_DIRECTION 1 -#define NAS_SECURITY_UPLINK_DIRECTION 0 - #define NAS_SECURITY_MAC_SIZE 4 ogs_pkbuf_t *nas_eps_security_encode( @@ -87,7 +84,7 @@ ogs_pkbuf_t *nas_eps_security_encode( /* encrypt NAS message */ ogs_nas_encrypt(mme_ue->selected_enc_algorithm, mme_ue->knas_enc, mme_ue->dl_count, NAS_SECURITY_BEARER, - NAS_SECURITY_DOWNLINK_DIRECTION, new); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, new); } /* encode sequence number */ @@ -100,7 +97,7 @@ ogs_pkbuf_t *nas_eps_security_encode( /* calculate NAS MAC(message authentication code) */ ogs_nas_mac_calculate(mme_ue->selected_int_algorithm, mme_ue->knas_int, mme_ue->dl_count, NAS_SECURITY_BEARER, - NAS_SECURITY_DOWNLINK_DIRECTION, new, mac); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, new, mac); memcpy(&h.message_authentication_code, mac, sizeof(mac)); } @@ -156,7 +153,7 @@ int nas_eps_security_decode(mme_ue_t *mme_ue, ogs_pkbuf_trim(pkbuf, 2); ogs_nas_mac_calculate(mme_ue->selected_int_algorithm, mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, - NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); + OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); ogs_pkbuf_put_data(pkbuf, original_mac, SHORT_MAC_SIZE); if (memcmp(mac + 2, pkbuf->data + 2, 2) != 0) { @@ -210,7 +207,7 @@ int nas_eps_security_decode(mme_ue_t *mme_ue, /* calculate NAS MAC(message authentication code) */ ogs_nas_mac_calculate(mme_ue->selected_int_algorithm, mme_ue->knas_int, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, - NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); + OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf, mac); h->message_authentication_code = original_mac; memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); @@ -228,7 +225,7 @@ int nas_eps_security_decode(mme_ue_t *mme_ue, /* decrypt NAS message */ ogs_nas_encrypt(mme_ue->selected_enc_algorithm, mme_ue->knas_enc, mme_ue->ul_count.i32, NAS_SECURITY_BEARER, - NAS_SECURITY_UPLINK_DIRECTION, pkbuf); + OGS_NAS_SECURITY_UPLINK_DIRECTION, pkbuf); } } diff --git a/tests/common/gmm-build.c b/tests/common/gmm-build.c index 4a77a0813..261a3506f 100644 --- a/tests/common/gmm-build.c +++ b/tests/common/gmm-build.c @@ -197,6 +197,20 @@ ogs_pkbuf_t *testgmm_build_registration_request( if (nasbuf) { registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT; + + switch (test_ue->selected_enc_algorithm) { + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA1: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA2: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA3: + ogs_nas_encrypt(test_ue->selected_enc_algorithm, + test_ue->knas_enc, test_ue->ul_count, + test_ue->nas.access_type, + OGS_NAS_SECURITY_UPLINK_DIRECTION, nasbuf); + break; + default: + break; + } + nas_message_container->length = nasbuf->len; nas_message_container->buffer = nasbuf->data; ogs_pkbuf_free(nasbuf); @@ -301,6 +315,20 @@ ogs_pkbuf_t *testgmm_build_service_request( if (nasbuf) { service_request->presencemask |= OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT; + + switch (test_ue->selected_enc_algorithm) { + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA1: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA2: + case OGS_NAS_SECURITY_ALGORITHMS_128_NEA3: + ogs_nas_encrypt(test_ue->selected_enc_algorithm, + test_ue->knas_enc, test_ue->ul_count, + test_ue->nas.access_type, + OGS_NAS_SECURITY_UPLINK_DIRECTION, nasbuf); + break; + default: + break; + } + nas_message_container->length = nasbuf->len; nas_message_container->buffer = nasbuf->data; ogs_pkbuf_free(nasbuf); diff --git a/tests/common/nas-security.c b/tests/common/nas-security.c index 3e0bc3f0a..db779dfe1 100644 --- a/tests/common/nas-security.c +++ b/tests/common/nas-security.c @@ -20,9 +20,6 @@ #include "test-common.h" #define NAS_SECURITY_BEARER 0 -#define NAS_SECURITY_DOWNLINK_DIRECTION 1 -#define NAS_SECURITY_UPLINK_DIRECTION 0 - #define NAS_SECURITY_MAC_SIZE 4 ogs_pkbuf_t *test_nas_5gs_security_encode( @@ -92,7 +89,7 @@ ogs_pkbuf_t *test_nas_5gs_security_encode( ogs_nas_encrypt(test_ue->selected_enc_algorithm, test_ue->knas_enc, test_ue->ul_count, test_ue->nas.access_type, - NAS_SECURITY_UPLINK_DIRECTION, new); + OGS_NAS_SECURITY_UPLINK_DIRECTION, new); } /* encode sequence number */ @@ -106,7 +103,7 @@ ogs_pkbuf_t *test_nas_5gs_security_encode( ogs_nas_mac_calculate(test_ue->selected_int_algorithm, test_ue->knas_int, test_ue->ul_count, test_ue->nas.access_type, - NAS_SECURITY_UPLINK_DIRECTION, new, mac); + OGS_NAS_SECURITY_UPLINK_DIRECTION, new, mac); memcpy(&h.message_authentication_code, mac, sizeof(mac)); } @@ -167,7 +164,7 @@ int test_nas_5gs_security_decode(test_ue_t *test_ue, ogs_nas_mac_calculate(test_ue->selected_int_algorithm, test_ue->knas_int, test_ue->dl_count.i32, test_ue->nas.access_type, - NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf, mac); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf, mac); h->message_authentication_code = original_mac; memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); @@ -186,7 +183,7 @@ int test_nas_5gs_security_decode(test_ue_t *test_ue, ogs_nas_encrypt(test_ue->selected_enc_algorithm, test_ue->knas_enc, test_ue->dl_count.i32, test_ue->nas.access_type, - NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf); } } @@ -259,7 +256,7 @@ ogs_pkbuf_t *test_nas_eps_security_encode( ogs_nas_encrypt(test_ue->selected_enc_algorithm, test_ue->knas_enc, test_ue->ul_count, test_ue->nas.access_type, - NAS_SECURITY_UPLINK_DIRECTION, new); + OGS_NAS_SECURITY_UPLINK_DIRECTION, new); } /* encode sequence number */ @@ -272,7 +269,7 @@ ogs_pkbuf_t *test_nas_eps_security_encode( /* calculate NAS MAC(message authentication code) */ ogs_nas_mac_calculate(test_ue->selected_int_algorithm, test_ue->knas_int, test_ue->ul_count, - NAS_SECURITY_BEARER, NAS_SECURITY_UPLINK_DIRECTION, new, mac); + NAS_SECURITY_BEARER, OGS_NAS_SECURITY_UPLINK_DIRECTION, new, mac); memcpy(&h.message_authentication_code, mac, sizeof(mac)); } @@ -333,7 +330,7 @@ int test_nas_eps_security_decode(test_ue_t *test_ue, ogs_nas_mac_calculate(test_ue->selected_int_algorithm, test_ue->knas_int, test_ue->dl_count.i32, NAS_SECURITY_BEARER, - NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf, mac); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf, mac); h->message_authentication_code = original_mac; memcpy(&mac32, mac, NAS_SECURITY_MAC_SIZE); @@ -352,7 +349,7 @@ int test_nas_eps_security_decode(test_ue_t *test_ue, ogs_nas_encrypt(test_ue->selected_enc_algorithm, test_ue->knas_enc, test_ue->dl_count.i32, test_ue->nas.access_type, - NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf); + OGS_NAS_SECURITY_DOWNLINK_DIRECTION, pkbuf); } }