* Counter value if reauthentication is used
*/
uint16_t counter;
-#ifdef VOWIFI_CFG
- /**
- * IKE SA name
- */
- char* sa_name;
-#endif
};
/**
/**
* 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;
#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))
}
+#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;
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);
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.
*/
.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,
},
},
* 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;
}
}
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;
}
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
*/
.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,
},
return &this->public;
}
-
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
/**
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;
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;
}
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
};
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: