Authentication failure(Resynch failure) is added

This commit is contained in:
Sukchan Lee 2017-12-18 00:01:07 +09:00
parent 8f1df48a95
commit 649fd75b14
17 changed files with 184 additions and 82 deletions

View File

@ -41,6 +41,7 @@ extern "C" {
#define RAND_LEN 16
#define AUTN_LEN 16
#define AUTS_LEN 14
#define MAX_RES_LEN 16
#define MAX_APN_LEN 100

View File

@ -229,7 +229,7 @@ ED4(c_uint8_t type:4;,
* O TLV 16 */
typedef struct _nas_authentication_failure_parameter_t {
c_uint8_t length;
c_uint8_t parameter[14];
c_uint8_t auts[AUTS_LEN];
} __attribute__ ((packed)) nas_authentication_failure_parameter_t;
/* 9.9.3.2 Authentication parameter AUTN

View File

@ -315,7 +315,7 @@ status_t hss_db_increment_sqn(char *imsi_bcd)
bson_t *query = NULL;
bson_t *update = NULL;
bson_error_t error;
c_uint64_t max_sqn = 0x7ffffffffff;
c_uint64_t max_sqn = HSS_MAX_SQN;
mutex_lock(self.db_lock);

View File

@ -13,6 +13,8 @@ extern "C" {
#define HSS_KEY_LEN 16
#define HSS_AMF_LEN 2
#define HSS_MAX_SQN 0x7ffffffffff
typedef struct _hss_db_auth_info_t {
c_uint8_t k[HSS_KEY_LEN];
c_uint8_t use_opc;

View File

@ -13,9 +13,6 @@
#include "hss_kdf.h"
#include "milenage.h"
#define HSS_SQN_LEN 6
#define HSS_AK_LEN 6
/* handler for fallback cb */
static struct disp_hdl *hdl_s6a_fb = NULL;
/* handler for Authentication-Information-Request cb */
@ -38,6 +35,7 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
struct session *session, void *opaque, enum disp_action *act)
{
struct msg *ans, *qry;
struct avp *avpch;
struct avp *avp_e_utran_vector, *avp_xres, *avp_kasme, *avp_rand, *avp_autn;
struct avp_hdr *hdr;
union avp_value val;
@ -53,6 +51,9 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
c_uint8_t kasme[SHA256_DIGEST_SIZE];
size_t xres_len = 8;
#define MAC_S_LEN 8
c_uint8_t mac_s[MAC_S_LEN];
hss_db_auth_info_t auth_info;
c_uint8_t zero[RAND_LEN];
status_t rv;
@ -84,6 +85,43 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
core_generate_random_bytes(auth_info.rand, RAND_LEN);
}
if (auth_info.use_opc)
memcpy(opc, auth_info.opc, sizeof(opc));
else
milenage_opc(auth_info.k, auth_info.op, opc);
CHECK_FCT( fd_msg_search_avp(qry, s6a_req_eutran_auth_info, &avp) );
if (avp)
{
CHECK_FCT( fd_avp_search_avp(avp,
s6a_re_synchronization_info, &avpch) );
if (avpch)
{
CHECK_FCT( fd_msg_avp_hdr(avpch, &hdr) );
hss_kdf_sqn(opc, auth_info.k, auth_info.amf,
hdr->avp_value->os.data, sqn, mac_s);
if (memcmp(mac_s, hdr->avp_value->os.data +
RAND_LEN + HSS_SQN_LEN, MAC_S_LEN) == 0)
{
core_generate_random_bytes(auth_info.rand, RAND_LEN);
auth_info.sqn = core_buffer_to_uint64(sqn, HSS_SQN_LEN);
auth_info.sqn = (auth_info.sqn + 32) & HSS_MAX_SQN;
}
else
{
d_error("Re-synch MAC failed for IMSI:`%s`", imsi_bcd);
d_print("MAC_S: ");
d_print_hex(mac_s, MAC_S_LEN);
d_print_hex(hdr->avp_value->os.data +
RAND_LEN + HSS_SQN_LEN, MAC_S_LEN);
d_print("SQN: ");
d_print_hex(sqn, HSS_SQN_LEN);
result_code = S6A_DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE;
goto out;
}
}
}
rv = hss_db_update_rand_and_sqn(imsi_bcd, auth_info.rand, auth_info.sqn);
if (rv != CORE_OK)
{
@ -106,10 +144,6 @@ static int hss_s6a_air_cb( struct msg **msg, struct avp *avp,
memcpy(visited_plmn_id, hdr->avp_value->os.data, hdr->avp_value->os.len);
#endif
if (auth_info.use_opc)
memcpy(opc, auth_info.opc, sizeof(opc));
else
milenage_opc(auth_info.k, auth_info.op, opc);
milenage_generate(opc, auth_info.amf, auth_info.k,
core_uint64_to_buffer(auth_info.sqn, HSS_SQN_LEN, sqn), auth_info.rand,
autn, ik, ck, ak, xres, &xres_len);

View File

@ -1,6 +1,11 @@
#define TRACE_MODULE _hss_kdf
#include "core_debug.h"
#include "core_sha2_hmac.h"
#include "3gpp_types.h"
#include "hss_kdf.h"
#include "milenage.h"
#define FC_VALUE 0x10
@ -27,3 +32,19 @@ void hss_kdf_kasme(const c_uint8_t *ck, const c_uint8_t *ik,
hmac_sha256(k, 32, s, 14, kasme, 32);
}
void hss_kdf_sqn(
const c_uint8_t *opc, const c_uint8_t *k,
const c_uint8_t *amf, const c_uint8_t *auts,
c_uint8_t *sqn_ms, c_uint8_t *mac_s)
{
int i;
c_uint8_t ak[HSS_AK_LEN];
const c_uint8_t *rand = auts;
const c_uint8_t *conc_sqn_ms = auts + RAND_LEN;
milenage_f2345(opc, k, rand, NULL, NULL, NULL, NULL, ak);
for (i = 0; i < HSS_SQN_LEN; i++)
sqn_ms[i] = ak[i] ^ conc_sqn_ms[i];
milenage_f1(opc, k, auts, sqn_ms, amf, NULL, mac_s);
}

View File

@ -3,8 +3,16 @@
#include "core.h"
void hss_kdf_kasme(const c_uint8_t *ck, const c_uint8_t *ik,
#define HSS_SQN_LEN 6
#define HSS_AK_LEN 6
CORE_DECLARE(void) hss_kdf_kasme(const c_uint8_t *ck, const c_uint8_t *ik,
const c_uint8_t plmn_id[3], const c_uint8_t *sqn, const c_uint8_t *ak,
c_uint8_t *kasme);
CORE_DECLARE(void) hss_kdf_sqn(
const c_uint8_t *opc, const c_uint8_t *k,
const c_uint8_t *amf, const c_uint8_t *auts,
c_uint8_t *sqn_ms, c_uint8_t *mac_s);
#endif /* __HSS_KDF_H__ */

View File

@ -154,7 +154,7 @@ void emm_handle_attach_request(
}
else
{
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
}
}
@ -270,7 +270,7 @@ void emm_handle_identity_response(
}
else
{
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
}
}
@ -286,7 +286,7 @@ void emm_handle_identity_response(
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
else
{
@ -307,7 +307,7 @@ void emm_handle_identity_response(
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
else
{
@ -410,7 +410,7 @@ void emm_handle_service_request(
{
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
else
{
@ -547,7 +547,7 @@ void emm_handle_tau_request(
if (MME_HAVE_SGW_S11_PATH(mme_ue))
{
/* Re-authentication */
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
}
else
{

View File

@ -303,8 +303,6 @@ void emm_state_authentication(fsm_t *s, event_t *e)
&authentication_response->
authentication_response_parameter;
d_assert(mme_ue, return, "Null param");
if (authentication_response_parameter->length !=
mme_ue->xres_len ||
memcmp(authentication_response_parameter->res,
@ -324,6 +322,18 @@ void emm_state_authentication(fsm_t *s, event_t *e)
}
break;
}
case NAS_AUTHENTICATION_FAILURE:
{
nas_authentication_failure_t *authentication_failure =
&message->emm.authentication_failure;
nas_authentication_failure_parameter_t
*authentication_failure_parameter =
&authentication_failure->
authentication_failure_parameter;
mme_s6a_send_air(mme_ue, authentication_failure_parameter);
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);

View File

@ -213,6 +213,7 @@ struct _mme_ue_t {
c_uint8_t xres[MAX_RES_LEN];
c_uint8_t xres_len;
c_uint8_t kasme[SHA256_DIGEST_SIZE];
c_uint8_t rand[RAND_LEN];
c_uint8_t knas_int[SHA256_DIGEST_SIZE/2];
c_uint8_t knas_enc[SHA256_DIGEST_SIZE/2];
c_uint32_t dl_count;

View File

@ -26,7 +26,8 @@ static void mme_s6a_aia_cb(void *data, struct msg **msg);
static void mme_s6a_ula_cb(void *data, struct msg **msg);
/* MME Sends Authentication Information Request to HSS */
void mme_s6a_send_air(mme_ue_t *mme_ue)
void mme_s6a_send_air(mme_ue_t *mme_ue,
nas_authentication_failure_parameter_t *authentication_failure_parameter)
{
struct msg *req = NULL;
struct avp *avp;
@ -35,6 +36,8 @@ void mme_s6a_send_air(mme_ue_t *mme_ue)
struct sess_state *mi = NULL, *svg;
struct session *session = NULL;
c_uint8_t resync[AUTS_LEN + RAND_LEN];
d_assert(mme_ue, return, "Null param");
/* Clear Security Context */
@ -93,6 +96,19 @@ void mme_s6a_send_air(mme_ue_t *mme_ue)
CHECK_FCT_DO( fd_msg_avp_setvalue(avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch), goto out );
if (authentication_failure_parameter)
{
CHECK_FCT_DO( fd_msg_avp_new(s6a_re_synchronization_info, 0, &avpch),
goto out );
memcpy(resync, mme_ue->rand, RAND_LEN);
memcpy(resync+RAND_LEN,
authentication_failure_parameter->auts, AUTS_LEN);
val.os.len = RAND_LEN+AUTS_LEN;
val.os.data = resync;
CHECK_FCT_DO( fd_msg_avp_setvalue(avpch, &val), goto out );
CHECK_FCT_DO( fd_msg_avp_add(avp, MSG_BRW_LAST_CHILD, avpch), goto out );
}
CHECK_FCT_DO( fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp), goto out );
/* Set the Visited-PLMN-Id AVP */

View File

@ -13,7 +13,8 @@ CORE_DECLARE(int) mme_fd_init(void);
CORE_DECLARE(void) mme_fd_final(void);
/* MME Sends Authentication Information Request to HSS */
CORE_DECLARE(void) mme_s6a_send_air(mme_ue_t *mme_ue);
CORE_DECLARE(void) mme_s6a_send_air(mme_ue_t *mme_ue,
nas_authentication_failure_parameter_t *authentication_failure_parameter);
/* MME Sends Update Location Request to HSS */
CORE_DECLARE(void) mme_s6a_send_ulr(mme_ue_t *mme_ue);

View File

@ -170,7 +170,7 @@ void mme_s11_handle_delete_session_response(
{
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_DELETE_SESSION,
CLEAR_SGW_S11_PATH(mme_ue);
mme_s6a_send_air(mme_ue);
mme_s6a_send_air(mme_ue, NULL);
);
mme_sess_remove(sess);

View File

@ -22,6 +22,7 @@ void mme_s6a_handle_aia(mme_ue_t *mme_ue, s6a_aia_message_t *aia_message)
mme_ue->xres_len = e_utran_vector->xres_len;
memcpy(mme_ue->xres, e_utran_vector->xres, mme_ue->xres_len);
memcpy(mme_ue->kasme, e_utran_vector->kasme, SHA256_DIGEST_SIZE);
memcpy(mme_ue->rand, e_utran_vector->rand, RAND_LEN);
rv = nas_send_authentication_request(mme_ue, e_utran_vector);
d_assert(rv == CORE_OK,, "nas send failed");

View File

@ -92,46 +92,6 @@ static void attach_test1(abts_case *tc, void *data)
"}, "
"\"__v\" : 0 "
"}";
const char *json2 =
"{"
"\"_id\" : { \"$oid\" : \"697223158b8861d7605378c6\" }, "
"\"imsi\" : \"001010123456815\", "
"\"pdn\" : ["
"{"
"\"apn\" : \"internet\", "
"\"_id\" : { \"$oid\" : \"697223158b8861d7605378c7\" }, "
"\"ambr\" : {"
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
"},"
"\"qos\" : { "
"\"qci\" : 9, "
"\"arp\" : { "
"\"priority_level\" : 8,"
"\"pre_emption_vulnerability\" : 1, "
"\"pre_emption_capability\" : 1"
"} "
"}, "
"\"type\" : 2"
"}"
"],"
"\"ambr\" : { "
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
"},"
"\"subscribed_rau_tau_timer\" : 12,"
"\"network_access_mode\" : 2, "
"\"subscriber_status\" : 0, "
"\"access_restriction_data\" : 32, "
"\"security\" : { "
"\"k\" : \"465B5CE8 B199B49F AA5F0A2E E238A6BC\", "
"\"op\" : \"5F1D289C 5D354D0A 140C2548 F5F3E3BA\", "
"\"amf\" : \"8000\", "
"\"sqn\" : { \"$numberLong\" : \"64\" }, "
"\"rand\" : \"20080C38 18183B52 2614162C 07601D0D\" "
"}, "
"\"__v\" : 0 "
"}";
core_sleep(time_from_msec(300));
@ -180,21 +140,6 @@ static void attach_test1(abts_case *tc, void *data)
} while (count == 0);
bson_destroy(doc);
doc = bson_new_from_json((const uint8_t *)json2, -1, &error);;
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_insert(collection,
MONGOC_INSERT_NONE, doc, NULL, &error));
bson_destroy(doc);
doc = BCON_NEW("imsi", BCON_UTF8("001010123456815"));
ABTS_PTR_NOTNULL(tc, doc);
do
{
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
} while (count == 0);
bson_destroy(doc);
/***********************************************************************
* Attach Request : Known IMSI, Integrity Protected, No Security Context
* Send Initial-UE Message + Attach Request + PDN Connectivity */
@ -422,12 +367,6 @@ static void attach_test1(abts_case *tc, void *data)
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
bson_destroy(doc);
doc = BCON_NEW("imsi", BCON_UTF8("001010123456815"));
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_remove(collection,
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
bson_destroy(doc);
mongoc_collection_destroy(collection);
/* Send Identity Response */
@ -702,6 +641,20 @@ static void attach_test2(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, CORE_OK, rv);
pkbuf_free(recvbuf);
/* Send Authentication Authentication Failure */
rv = tests1ap_build_authentication_failure(&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);
rv = tests1ap_enb_read(sock, recvbuf);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
pkbuf_free(recvbuf);
core_sleep(time_from_msec(300));
doc = BCON_NEW("imsi", BCON_UTF8("001010123456826"));
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_remove(collection,

View File

@ -341,6 +341,58 @@ status_t tests1ap_build_authentication_response(pkbuf_t **pkbuf, int i)
return CORE_OK;
}
status_t tests1ap_build_authentication_failure(pkbuf_t **pkbuf, int i)
{
char *payload[TESTS1AP_MAX_MESSAGE] = {
"",
"",
"",
"",
"",
"000d"
"403d000005000000 0200030008000200 21001a001413075c 15300e9a73df7ef8"
"05f893f312a930a9 8f006440080000f1 100019b010004340 060000f1100001",
"",
"",
"",
"",
"",
"",
};
c_uint16_t len[TESTS1AP_MAX_MESSAGE] = {
0,
0,
0,
0,
0,
65,
0,
0,
0,
0,
0,
0,
};
char hexbuf[MAX_SDU_LEN];
*pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
if (!(*pkbuf)) return CORE_ERROR;
(*pkbuf)->len = len[i];
memcpy((*pkbuf)->payload, CORE_HEX(payload[i], strlen(payload[i]), hexbuf),
(*pkbuf)->len);
return CORE_OK;
}
status_t tests1ap_build_security_mode_complete(pkbuf_t **pkbuf, int i)
{
char *payload[TESTS1AP_MAX_MESSAGE] = {

View File

@ -24,6 +24,8 @@ CORE_DECLARE(status_t) tests1ap_build_initial_ue_msg(pkbuf_t **pkbuf, int i);
CORE_DECLARE(status_t) tests1ap_build_identity_response(pkbuf_t **pkbuf, int i);
CORE_DECLARE(status_t) tests1ap_build_authentication_response(
pkbuf_t **pkbuf, int i);
CORE_DECLARE(status_t) tests1ap_build_authentication_failure(
pkbuf_t **pkbuf, int i);
CORE_DECLARE(status_t) tests1ap_build_security_mode_complete(
pkbuf_t **pkbuf, int i);
CORE_DECLARE(status_t) tests1ap_build_esm_information_response(