diff options
14 files changed, 57 insertions, 34 deletions
diff --git a/src/charon/plugins/eap_aka/eap_aka_peer.c b/src/charon/plugins/eap_aka/eap_aka_peer.c index 527c38e7c..080c09d28 100644 --- a/src/charon/plugins/eap_aka/eap_aka_peer.c +++ b/src/charon/plugins/eap_aka/eap_aka_peer.c @@ -181,7 +181,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this, enumerator_t *enumerator; simaka_attribute_t type; chunk_t data, rand = chunk_empty, autn = chunk_empty, mk; - u_char res[AKA_RES_LEN], ck[AKA_CK_LEN], ik[AKA_IK_LEN], auts[AKA_AUTS_LEN]; + u_char res[AKA_RES_MAX], ck[AKA_CK_LEN], ik[AKA_IK_LEN], auts[AKA_AUTS_LEN]; + int res_len; identification_t *id; status_t status; @@ -216,7 +217,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this, } status = charon->sim->card_get_quintuplet(charon->sim, this->permanent, - rand.ptr, autn.ptr, ck, ik, res); + rand.ptr, autn.ptr, ck, ik, res, &res_len); if (status == INVALID_STATE && charon->sim->card_resync(charon->sim, this->permanent, rand.ptr, auts)) { @@ -286,7 +287,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this, message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA, AKA_CHALLENGE, this->crypto); - message->add_attribute(message, AT_RES, chunk_create(res, AKA_RES_LEN)); + message->add_attribute(message, AT_RES, chunk_create(res, res_len)); *out = message->generate(message, chunk_empty); message->destroy(message); return NEED_MORE; diff --git a/src/charon/plugins/eap_aka/eap_aka_server.c b/src/charon/plugins/eap_aka/eap_aka_server.c index 452758575..459dbba30 100644 --- a/src/charon/plugins/eap_aka/eap_aka_server.c +++ b/src/charon/plugins/eap_aka/eap_aka_server.c @@ -146,13 +146,14 @@ static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out) static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out) { simaka_message_t *message; - char rand[AKA_RAND_LEN], xres[AKA_RES_LEN]; + char rand[AKA_RAND_LEN], xres[AKA_RES_MAX]; char ck[AKA_CK_LEN], ik[AKA_IK_LEN], autn[AKA_AUTN_LEN]; + int xres_len; chunk_t data, mk; identification_t *id; if (!charon->sim->provider_get_quintuplet(charon->sim, this->permanent, - rand, xres, ck, ik, autn)) + rand, xres, &xres_len, ck, ik, autn)) { if (this->use_pseudonym) { @@ -176,7 +177,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out) free(this->msk.ptr); this->msk = this->crypto->derive_keys_full(this->crypto, id, data, &mk); this->rand = chunk_clone(chunk_create(rand, AKA_RAND_LEN)); - this->xres = chunk_clone(chunk_create(xres, AKA_RES_LEN)); + this->xres = chunk_clone(chunk_create(xres, xres_len)); message = simaka_message_create(TRUE, this->identifier++, EAP_AKA, AKA_CHALLENGE, this->crypto); diff --git a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c index 9365eb2e8..5c0fe38ad 100644 --- a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c +++ b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c @@ -57,7 +57,8 @@ void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset); static status_t get_quintuplet(private_eap_aka_3gpp2_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_LEN]) + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], + int *res_len) { char *amf, *mac; char k[AKA_K_LEN], ak[AKA_AK_LEN], sqn[AKA_SQN_LEN], xmac[AKA_MAC_LEN]; @@ -106,6 +107,7 @@ static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this, this->f->f4(this->f, k, rand, ik); /* calculate RES */ this->f->f2(this->f, k, rand, res); + *res_len = AKA_RES_MAX; return SUCCESS; } @@ -152,7 +154,7 @@ eap_aka_3gpp2_card_t *eap_aka_3gpp2_card_create(eap_aka_3gpp2_functions_t *f) private_eap_aka_3gpp2_card_t *this = malloc_thing(private_eap_aka_3gpp2_card_t); this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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_LEN]))get_quintuplet; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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))get_quintuplet; this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync; this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *id))return_null; this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; diff --git a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c index 2307c551e..1d3d246d1 100644 --- a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c +++ b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c @@ -307,10 +307,10 @@ static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], * Calculate RES from RAND using K */ static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_LEN]) + u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]) { fx(this->prf, F2, k, rand, res); - DBG3(DBG_IKE, "RES %b", res, AKA_RES_LEN); + DBG3(DBG_IKE, "RES %b", res, AKA_RES_MAX); } /** @@ -374,7 +374,7 @@ eap_aka_3gpp2_functions_t *eap_aka_3gpp2_functions_create() this->public.f1 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]))f1; this->public.f1star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]))f1star; - this->public.f2 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_LEN]))f2; + this->public.f2 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]))f2; this->public.f3 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]))f3; this->public.f4 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]))f4; this->public.f5 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]))f5; diff --git a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h index 1d999d643..95c6da6a9 100644 --- a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h +++ b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h @@ -68,10 +68,10 @@ struct eap_aka_3gpp2_functions_t { * * @param k secret key K * @param rand random value RAND - * @param macs buffer receiving result RES + * @param res buffer receiving result RES, uses full 128 bit */ void (*f2)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], - u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_LEN]); + u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]); /** * Calculate CK from RAND using K * diff --git a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c index 8dba38d9b..9817fff8f 100644 --- a/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c +++ b/src/charon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c @@ -86,8 +86,9 @@ void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset) */ static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this, identification_t *id, char rand[AKA_RAND_LEN], - char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) + char xres[AKA_RES_MAX], int *xres_len, + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char autn[AKA_AUTN_LEN]) { rng_t *rng; char mac[AKA_MAC_LEN], ak[AKA_AK_LEN], k[AKA_K_LEN]; @@ -117,6 +118,7 @@ static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this, this->f->f5(this->f, k, rand, ak); /* XRES as expected from client */ this->f->f2(this->f, k, rand, xres); + *xres_len = AKA_RES_MAX; /* AUTN = (SQN xor AK) || AMF || MAC */ memcpy(autn, this->sqn, AKA_SQN_LEN); memxor(autn, ak, AKA_AK_LEN); @@ -185,7 +187,7 @@ eap_aka_3gpp2_provider_t *eap_aka_3gpp2_provider_create( private_eap_aka_3gpp2_provider_t *this = malloc_thing(private_eap_aka_3gpp2_provider_t); this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet; this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync; this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c index f6ff20710..4dccf566a 100644 --- a/src/charon/plugins/eap_sim_file/eap_sim_file_card.c +++ b/src/charon/plugins/eap_sim_file/eap_sim_file_card.c @@ -92,7 +92,7 @@ eap_sim_file_card_t *eap_sim_file_card_create(eap_sim_file_triplets_t *triplets) private_eap_sim_file_card_t *this = malloc_thing(private_eap_sim_file_card_t); this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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_LEN]))get_quintuplet; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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))get_quintuplet; this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null; this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; diff --git a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c index 9e791e94c..9bee31fc3 100644 --- a/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c +++ b/src/charon/plugins/eap_sim_file/eap_sim_file_provider.c @@ -78,7 +78,7 @@ eap_sim_file_provider_t *eap_sim_file_provider_create( private_eap_sim_file_provider_t *this = malloc_thing(private_eap_sim_file_provider_t); this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))get_triplet; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c index babe12835..d44097e4d 100644 --- a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c @@ -138,7 +138,7 @@ eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create() this = malloc_thing(private_eap_simaka_pseudonym_card_t); this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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_LEN]))get_quintuplet; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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))get_quintuplet; this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))get_pseudonym; this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym; diff --git a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c index 851f42889..0613b8807 100644 --- a/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c +++ b/src/charon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c @@ -160,7 +160,7 @@ eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create() this = malloc_thing(private_eap_simaka_pseudonym_provider_t); this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym; this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym; diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c index 8455c2071..a6d30989c 100644 --- a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c @@ -155,7 +155,7 @@ eap_simaka_reauth_card_t *eap_simaka_reauth_card_create() this = malloc_thing(private_eap_simaka_reauth_card_t); this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_null; - this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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_LEN]))get_quintuplet; + this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, 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))get_quintuplet; this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null; this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop; diff --git a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c index bdc7e7b84..f962b2d84 100644 --- a/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c +++ b/src/charon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c @@ -187,7 +187,7 @@ eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create() private_eap_simaka_reauth_provider_t *this = malloc_thing(private_eap_simaka_reauth_provider_t); this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false; - this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; + this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false; this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false; this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null; diff --git a/src/charon/sa/authenticators/eap/sim_manager.c b/src/charon/sa/authenticators/eap/sim_manager.c index e11d83502..4fbb16e8e 100644 --- a/src/charon/sa/authenticators/eap/sim_manager.c +++ b/src/charon/sa/authenticators/eap/sim_manager.c @@ -90,7 +90,8 @@ static bool card_get_triplet(private_sim_manager_t *this, identification_t *id, static status_t card_get_quintuplet(private_sim_manager_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_LEN]) + char ik[AKA_IK_LEN], char res[AKA_RES_MAX], + int *res_len) { enumerator_t *enumerator; sim_card_t *card; @@ -100,7 +101,7 @@ static status_t card_get_quintuplet(private_sim_manager_t *this, enumerator = this->cards->create_enumerator(this->cards); while (enumerator->enumerate(enumerator, &card)) { - status = card->get_quintuplet(card, id, rand, autn, ck, ik, res); + status = card->get_quintuplet(card, id, rand, autn, ck, ik, res, res_len); if (status != FAILED) { /* try next on error, but not on INVALID_STATE */ enumerator->destroy(enumerator); @@ -276,8 +277,9 @@ static bool provider_get_triplet(private_sim_manager_t *this, */ static bool provider_get_quintuplet(private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN], - char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], - char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]) + char xres[AKA_RES_MAX], int *xres_len, + char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], + char autn[AKA_AUTN_LEN]) { enumerator_t *enumerator; sim_provider_t *provider; @@ -286,7 +288,8 @@ static bool provider_get_quintuplet(private_sim_manager_t *this, enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, &provider)) { - if (provider->get_quintuplet(provider, id, rand, xres, ck, ik, autn)) + if (provider->get_quintuplet(provider, id, rand, xres, xres_len, + ck, ik, autn)) { enumerator->destroy(enumerator); return TRUE; @@ -439,7 +442,7 @@ sim_manager_t *sim_manager_create() this->public.add_card = (void(*)(sim_manager_t*, sim_card_t *card))add_card; this->public.remove_card = (void(*)(sim_manager_t*, sim_card_t *card))remove_card; this->public.card_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))card_get_triplet; - this->public.card_get_quintuplet = (status_t(*)(sim_manager_t*, 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_LEN]))card_get_quintuplet; + this->public.card_get_quintuplet = (status_t(*)(sim_manager_t*, 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))card_get_quintuplet; this->public.card_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))card_resync; this->public.card_set_pseudonym = (void(*)(sim_manager_t*, identification_t *id, identification_t *pseudonym))card_set_pseudonym; this->public.card_get_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))card_get_pseudonym; @@ -448,7 +451,7 @@ sim_manager_t *sim_manager_create() this->public.add_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))add_provider; this->public.remove_provider = (void(*)(sim_manager_t*, sim_provider_t *provider))remove_provider; this->public.provider_get_triplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))provider_get_triplet; - this->public.provider_get_quintuplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))provider_get_quintuplet; + this->public.provider_get_quintuplet = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))provider_get_quintuplet; this->public.provider_resync = (bool(*)(sim_manager_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))provider_resync; this->public.provider_is_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_is_pseudonym; this->public.provider_gen_pseudonym = (identification_t*(*)(sim_manager_t*, identification_t *id))provider_gen_pseudonym; diff --git a/src/charon/sa/authenticators/eap/sim_manager.h b/src/charon/sa/authenticators/eap/sim_manager.h index a4dbffa6b..75f3acee1 100644 --- a/src/charon/sa/authenticators/eap/sim_manager.h +++ b/src/charon/sa/authenticators/eap/sim_manager.h @@ -34,7 +34,7 @@ typedef struct sim_provider_t sim_provider_t; #define SIM_KC_LEN 8 #define AKA_RAND_LEN 16 -#define AKA_RES_LEN 16 +#define AKA_RES_MAX 16 #define AKA_CK_LEN 16 #define AKA_IK_LEN 16 #define AKA_AUTN_LEN 16 @@ -68,6 +68,10 @@ struct sim_card_t { * * 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 @@ -75,12 +79,13 @@ struct sim_card_t { * @param ck buffer receiving encryption key ck * @param ik buffer receiving integrity key ik * @param res buffer receiving authentication result res + * @param res_len nubmer of bytes written to res buffer * @return SUCCESS, FAILED, or INVALID_STATE if out of sync */ status_t (*get_quintuplet)(sim_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_LEN]); + char res[AKA_RES_MAX], int *res_len); /** * Calculate AUTS from RAND for AKA resynchronization. @@ -161,16 +166,23 @@ struct sim_provider_t { /** * Create a challenge for AKA authentication. * + * The XRES 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 + * xres_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 of peer to create challenge for * @param rand buffer receiving random value rand * @param xres buffer receiving expected authentication result xres + * @param xres_len nubmer of bytes written to xres buffer * @param ck buffer receiving encryption key ck * @param ik buffer receiving integrity key ik * @param autn authentication token autn * @return TRUE if quintuplet generated successfully */ bool (*get_quintuplet)(sim_provider_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], + char rand[AKA_RAND_LEN], + char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]); @@ -266,12 +278,13 @@ struct sim_manager_t { * @param ck buffer receiving encryption key ck * @param ik buffer receiving integrity key ik * @param res buffer receiving authentication result res + * @param res_len nubmer of bytes written to res buffer * @return SUCCESS, FAILED, or INVALID_STATE if out of sync */ status_t (*card_get_quintuplet)(sim_manager_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_LEN]); + char res[AKA_RES_MAX], int *res_len); /** * Calculate resynchronization data on one of the registered SIM cards. @@ -365,7 +378,8 @@ struct sim_manager_t { * @return TRUE if quintuplet received, FALSE if no match found */ bool (*provider_get_quintuplet)(sim_manager_t *this, identification_t *id, - char rand[AKA_RAND_LEN], char xres[AKA_RES_LEN], + char rand[AKA_RAND_LEN], + char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]); |