From e10ef206692eca42240aa495fa0ede90b7c99240 Mon Sep 17 00:00:00 2001 From: Denis Vinogradov Date: Tue, 25 Aug 2020 13:42:12 +0900 Subject: [PATCH] provide IKE_SA name as parameter to authenticator [JIRA]: NEUS7920-25337 [Problem]: Could not create connection for SIM1 [Issue]: SIM1 and SIM2 authentication stated same time and last incoming request overwrite previous authenticator saved connection name. Both requests were sent to SIM2, and error received from SIM for SIM1 challenge request. [Solution]: Remove authenticator pluGin name, add IKE_SA name as parameter to request Change-Id: I68531d629ad5a7b6b81984a195efea77fff38e37 Signed-off-by: Denis Vinogradov --- src/libcharon/plugins/eap_aka/eap_aka_peer.c | 37 ++++++------ .../eap_aka_3gpp_simril_card.c | 56 ++++++------------- src/libcharon/sa/eap/eap_method.h | 20 +++++-- .../ikev2/authenticators/eap_authenticator.c | 32 +++++++++-- src/libsimaka/simaka_card.h | 28 ++++++++-- src/libsimaka/simaka_manager.c | 12 +++- 6 files changed, 110 insertions(+), 75 deletions(-) diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.c b/src/libcharon/plugins/eap_aka/eap_aka_peer.c index 1fb976b..9a37c54 100755 --- a/src/libcharon/plugins/eap_aka/eap_aka_peer.c +++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.c @@ -78,12 +78,6 @@ struct private_eap_aka_peer_t { * Counter value if reauthentication is used */ uint16_t counter; -#ifdef VOWIFI_CFG - /** - * IKE SA name - */ - char* sa_name; -#endif }; /** @@ -211,8 +205,13 @@ static status_t process_identity(private_eap_aka_peer_t *this, /** * Process an EAP-AKA/Request/Challenge message */ +#ifdef VOWIFI_CFG +static status_t process_challenge(private_eap_aka_peer_t *this, + simaka_message_t *in, eap_payload_t **out, char *sa_name) +#else static status_t process_challenge(private_eap_aka_peer_t *this, simaka_message_t *in, eap_payload_t **out) +#endif { simaka_message_t *message; enumerator_t *enumerator; @@ -263,7 +262,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this, #ifndef VOWIFI_CFG rand.ptr, autn.ptr, ck, ik, res, &res_len); #else - rand.ptr, autn.ptr, ck, ik, res, &res_len, this->sa_name); + rand.ptr, autn.ptr, ck, ik, res, &res_len, sa_name); #endif if (status == INVALID_STATE && this->mgr->card_resync(this->mgr, this->permanent, rand.ptr, auts)) @@ -538,8 +537,13 @@ static status_t process_notification(private_eap_aka_peer_t *this, } +#ifdef VOWIFI_CFG +METHOD(eap_method_t, process, status_t, + private_eap_aka_peer_t *this, eap_payload_t *in, eap_payload_t **out, char *sa_name) +#else METHOD(eap_method_t, process, status_t, private_eap_aka_peer_t *this, eap_payload_t *in, eap_payload_t **out) +#endif { simaka_message_t *message; status_t status; @@ -571,7 +575,11 @@ METHOD(eap_method_t, process, status_t, status = process_identity(this, message, out); break; case AKA_CHALLENGE: +#ifdef VOWIFI_CFG + status = process_challenge(this, message, out, sa_name); +#else status = process_challenge(this, message, out); +#endif break; case AKA_REAUTHENTICATION: status = process_reauthentication(this, message, out); @@ -650,14 +658,6 @@ METHOD(eap_method_t, destroy, void, free(this); } -#ifdef VOWIFI_CFG -METHOD(eap_method_t, set_sa_name, void, - private_eap_aka_peer_t *this, char* name) -{ - this->sa_name = name; -} -#endif - /* * Described in header. */ @@ -670,15 +670,16 @@ eap_aka_peer_t *eap_aka_peer_create(identification_t *server, .public = { .interface = { .initiate = _initiate, +#ifdef VOWIFI_CFG + .process2 = _process, +#else .process = _process, +#endif .get_type = _get_type, .is_mutual = _is_mutual, .get_msk = _get_msk, .get_identifier = _get_identifier, .set_identifier = _set_identifier, -#ifdef VOWIFI_CFG - .set_sa_name = _set_sa_name, -#endif .destroy = _destroy, }, }, diff --git a/src/libcharon/plugins/eap_aka_3gpp_simril/eap_aka_3gpp_simril_card.c b/src/libcharon/plugins/eap_aka_3gpp_simril/eap_aka_3gpp_simril_card.c index 0b79961..ef11bfc 100755 --- a/src/libcharon/plugins/eap_aka_3gpp_simril/eap_aka_3gpp_simril_card.c +++ b/src/libcharon/plugins/eap_aka_3gpp_simril/eap_aka_3gpp_simril_card.c @@ -35,52 +35,38 @@ struct private_eap_aka_3gpp_simril_card_t { * Public eap_aka_3gpp_simril_card_t interface. */ eap_aka_3gpp_simril_card_t public; - - char* sa_name; }; METHOD(simaka_card_t, get_quintuplet, status_t, private_eap_aka_3gpp_simril_card_t *this, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len) + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len, char *sa_name) { sim_auth_resp_code_t status = AUTH_FAILURE; int ret; - DBG1(DBG_IKE, "WRAPPER: received RAND %b", rand, AKA_RAND_LEN); - DBG1(DBG_IKE, "WRAPPER: received AUTN %b", autn, AKA_AUTN_LEN); - ret = charon_process_sim_auth(this->sa_name, rand, autn, ck, ik, res, res_len, &status); - if (ret == SUCCESS) - { - DBG1(DBG_IKE, "[WRAPPER]: Response received from SIM: res_len: %d \n",*res_len); - DBG1(DBG_IKE, "computed Status %d", status); - DBG1(DBG_IKE, "computed RES %b", res, AKA_RES_MAX); - DBG1(DBG_IKE, "computed CK %b", ck, AKA_CK_LEN); - DBG1(DBG_IKE, "computed IK %b", ik, AKA_IK_LEN); - } - else + DBG1(DBG_IKE, "3gpp_simril_card get_quintuplet for %s", sa_name); + ret = charon_process_sim_auth(sa_name, rand, autn, ck, ik, res, res_len, &status); + if (ret != SUCCESS) { - DBG1(DBG_IKE, "[WRAPPER]: send_ril_sim_handler() API returned failure\n"); + DBG1(DBG_IKE, "3gpp_simril_card send_ril_sim_handler failed"); return FAILED; } - /* Handling Respose Code Received from Sim Auth API */ - switch (status) + DBG1(DBG_IKE, "3gpp_simril_card response status = %d, %d length", status, *res_len); + switch(status) { case AUTH_SUCCESS: - DBG1(DBG_IKE, "[WRAPPER] get_quintuplet: CK, IK and RES generated Successfully \n"); return SUCCESS; - case AUTH_FAILURE: - DBG1(DBG_IKE, "[WRAPPER] get_quintuplet: Error occoured!! \n"); - return FAILED; case AUTH_SYNC_FAIL: - DBG1(DBG_IKE, "[wrapper] get_quintuplet: Synch Failure... Overwriting RAND value with RES value \n"); - memset(rand,0x00,AKA_RAND_LEN); - memcpy(rand,res,AKA_RES_MAX); + DBG1(DBG_IKE, "3gpp_simril_card get_quintuplet: sync failure, overwrite RAND"); + memset(rand, 0x00, AKA_RAND_LEN); + memcpy(rand, res, AKA_RES_MAX); return INVALID_STATE; + case AUTH_FAILURE: default: - DBG1(DBG_IKE, "[WRAPPER] get_quintuplet: Default case. Returning failure. \n"); + DBG1(DBG_IKE, "3gpp_simril_card get_quintuplet failed"); return FAILED; } } @@ -89,9 +75,8 @@ METHOD(simaka_card_t, resync, bool, private_eap_aka_3gpp_simril_card_t *this, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]) { - DBG1(DBG_IKE, "[WRAPPER]: Generating AUTS Using RAND(indirect RES) value %b", rand, AKA_RAND_LEN); - memcpy(auts,rand,AKA_AUTS_LEN); - DBG1(DBG_IKE, "[WRAPPER]: Computed AUTS %b", auts, AKA_AUTS_LEN); + DBG1(DBG_IKE, "3gpp_simril_card resync, use RAND %b", rand, AKA_RAND_LEN); + memcpy(auts, rand, AKA_AUTS_LEN); return TRUE; } @@ -101,13 +86,6 @@ METHOD(eap_aka_3gpp_simril_card_t, destroy, void, free(this); } -METHOD(simaka_card_t, set_sa_name, void, - private_eap_aka_3gpp_simril_card_t *this, char *name) -{ - DBG1(DBG_IKE, "[WRAPPER]: Set SA name as %s", name); - this->sa_name = name; -} - /** * See header */ @@ -119,13 +97,16 @@ eap_aka_3gpp_simril_card_t *eap_aka_3gpp_simril_card_create() .public = { .card = { .get_triplet = (void*)return_false, +#ifdef VOWIFI_CFG + .get_quintuplet2 = _get_quintuplet, +#else .get_quintuplet = _get_quintuplet, +#endif .resync = _resync, .get_pseudonym = (void*)return_null, .set_pseudonym = (void*)nop, .get_reauth = (void*)return_null, .set_reauth = (void*)nop, - .set_sa_name = _set_sa_name, }, .destroy = _destroy, }, @@ -133,4 +114,3 @@ eap_aka_3gpp_simril_card_t *eap_aka_3gpp_simril_card_create() return &this->public; } - diff --git a/src/libcharon/sa/eap/eap_method.h b/src/libcharon/sa/eap/eap_method.h index e91d23b..1531d67 100755 --- a/src/libcharon/sa/eap/eap_method.h +++ b/src/libcharon/sa/eap/eap_method.h @@ -149,11 +149,21 @@ struct eap_method_t { auth_cfg_t* (*get_auth)(eap_method_t *this); #ifdef VOWIFI_CFG /** - * Provide IKE SA name to authenticator - * - * Required to send challenge to correct SIM slot - */ - void (*set_sa_name) (eap_method_t *this, char *name); + * Process a received EAP message. + * + * A eap_payload is created in "out" if result is NEED_MORE. + * + * @param in eap_payload response received + * @param out created eap_payload to send + * @param sa_name IKE_SA name + * @return + * - NEED_MORE, if an other exchange is required + * - FAILED, if EAP method failed + * - SUCCESS, if EAP method succeeded + */ + status_t (*process2) (eap_method_t *this, eap_payload_t *in, + eap_payload_t **out, + char *sa_name); #endif /** diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c index 2332187..111ab2e 100755 --- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c @@ -375,11 +375,21 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this, if (this->method) { #ifdef VOWIFI_CFG - if (this->method->set_sa_name) { - this->method->set_sa_name(this->method, this->ike_sa->get_name(this->ike_sa)); + status_t result; + + if (this->method->process2) + { + result = this->method->process2(this->method, in, &out, + this->ike_sa->get_name(this->ike_sa)); } -#endif + else + { + result = this->method->process(this->method, in, &out); + } + if (result == SUCCESS) +#else if (this->method->process(this->method, in, &out) == SUCCESS) +#endif { this->method->destroy(this->method); this->method = NULL; @@ -445,11 +455,21 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this, type = this->method->get_type(this->method, &vendor); #ifdef VOWIFI_CFG - if (this->method->set_sa_name) { - this->method->set_sa_name(this->method, this->ike_sa->get_name(this->ike_sa)); + status_t result; + + if (this->method->process2) + { + result = this->method->process2(this->method, in, &out, + this->ike_sa->get_name(this->ike_sa)); } -#endif + else + { + result = this->method->process(this->method, in, &out); + } + if (result == NEED_MORE) +#else if (this->method->process(this->method, in, &out) == NEED_MORE) +#endif { /* client methods should never return SUCCESS */ return out; } diff --git a/src/libsimaka/simaka_card.h b/src/libsimaka/simaka_card.h index 78ff9a5..6ac3c11 100755 --- a/src/libsimaka/simaka_card.h +++ b/src/libsimaka/simaka_card.h @@ -126,11 +126,29 @@ struct simaka_card_t { char mk[HASH_SIZE_SHA1], uint16_t *counter); #ifdef VOWIFI_CFG /** - * Provide IKE SA name to card - * - * Required for multi-SIM authentication - */ - void (*set_sa_name)(simaka_card_t *this, char *name); + * Calculate CK/IK/RES from RAND/AUTN for AKA authentication. + * + * If the received sequence number (in autn) is out of sync, INVALID_STATE + * is returned. + * The RES value is the only one with variable length. Pass a buffer + * of at least AKA_RES_MAX, the actual number of bytes is written to the + * res_len value. While the standard would allow any bit length between + * 32 and 128 bits, we support only full bytes for now. + * + * @param id permanent identity to request quintuplet for + * @param rand random value rand + * @param autn authentication token autn + * @param ck buffer receiving encryption key ck + * @param ik buffer receiving integrity key ik + * @param res buffer receiving authentication result res + * @param res_len number of bytes written to res buffer + * @param name IKE_SA name + * @return SUCCESS, FAILED, or INVALID_STATE if out of sync + */ + status_t (*get_quintuplet2)(simaka_card_t *this, identification_t *id, + char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char res[AKA_RES_MAX], int *res_len, char *sa_name); #endif }; diff --git a/src/libsimaka/simaka_manager.c b/src/libsimaka/simaka_manager.c index 28c80ec..cae2b9e 100755 --- a/src/libsimaka/simaka_manager.c +++ b/src/libsimaka/simaka_manager.c @@ -125,11 +125,17 @@ METHOD(simaka_manager_t, card_get_quintuplet, status_t, while (enumerator->enumerate(enumerator, &card)) { #ifdef VOWIFI_CFG - if (card->set_sa_name) { - card->set_sa_name(card, sa_name); + if (card->get_quintuplet2) + { + status = card->get_quintuplet2(card, id, rand, autn, ck, ik, res, res_len, sa_name); } -#endif + else + { + status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len); + } +#else status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len); +#endif switch (status) { /* try next on error, but not on INVALID_STATE */ case SUCCESS: -- 2.20.1