provide IKE_SA name as parameter to authenticator
authorDenis Vinogradov <denis.vinogradov@samsung.com>
Tue, 25 Aug 2020 04:42:12 +0000 (13:42 +0900)
committerYoojung Heo <yoojung.heo@samsung.com>
Fri, 28 Aug 2020 09:11:33 +0000 (18:11 +0900)
  [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 <denis.vinogradov@samsung.com>
src/libcharon/plugins/eap_aka/eap_aka_peer.c
src/libcharon/plugins/eap_aka_3gpp_simril/eap_aka_3gpp_simril_card.c
src/libcharon/sa/eap/eap_method.h
src/libcharon/sa/ikev2/authenticators/eap_authenticator.c
src/libsimaka/simaka_card.h
src/libsimaka/simaka_manager.c

index 1fb976b1b414fe5b2117788560e001d03a4e1eff..9a37c5484ee45aa5d699a96d07507a1952cd51e5 100755 (executable)
@@ -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,
                        },
                },
index 0b79961de06d3e47c08f4cda10521ca3a570e827..ef11bfc508d258130963a062df23589c1cc2c2fa 100755 (executable)
@@ -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;
 }
-
index e91d23bbe3ac7fd43f8dfee323383df88d989a88..1531d67c9ebaa5c095385e247a3b5d4bcf79ef5d 100755 (executable)
@@ -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
 
        /**
index 23321873d18c8fe62c4eaa9268190952bcd44e76..111ab2e0ac74d04f49ae50872c94136be2e636a8 100755 (executable)
@@ -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;
        }
index 78ff9a5f0a0fad876cbc04d1c25198e49c26b221..6ac3c118fcc407703768e6410cfb07a4b83a123a 100755 (executable)
@@ -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
 };
 
index 28c80ecb9b53ab154d14e4179b2dabd5939b000b..cae2b9eaa3c4ec413cd7a265aceff31cec17b6c2 100755 (executable)
@@ -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: