eap_aka.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568
  1. /*
  2. * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448)
  3. * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "pcsc_funcs.h"
  11. #include "crypto/crypto.h"
  12. #include "crypto/sha1.h"
  13. #include "crypto/sha256.h"
  14. #include "crypto/milenage.h"
  15. #include "eap_common/eap_sim_common.h"
  16. #include "eap_config.h"
  17. #include "eap_i.h"
  18. struct eap_aka_data {
  19. u8 ik[EAP_AKA_IK_LEN], ck[EAP_AKA_CK_LEN], res[EAP_AKA_RES_MAX_LEN];
  20. size_t res_len;
  21. u8 nonce_s[EAP_SIM_NONCE_S_LEN];
  22. u8 mk[EAP_SIM_MK_LEN];
  23. u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
  24. u8 k_encr[EAP_SIM_K_ENCR_LEN];
  25. u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */
  26. u8 msk[EAP_SIM_KEYING_DATA_LEN];
  27. u8 emsk[EAP_EMSK_LEN];
  28. u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
  29. u8 auts[EAP_AKA_AUTS_LEN];
  30. int num_id_req, num_notification;
  31. u8 *pseudonym;
  32. size_t pseudonym_len;
  33. u8 *reauth_id;
  34. size_t reauth_id_len;
  35. int reauth;
  36. unsigned int counter, counter_too_small;
  37. u8 *last_eap_identity;
  38. size_t last_eap_identity_len;
  39. enum {
  40. CONTINUE, RESULT_SUCCESS, SUCCESS, FAILURE
  41. } state;
  42. struct wpabuf *id_msgs;
  43. int prev_id;
  44. int result_ind, use_result_ind;
  45. int use_pseudonym;
  46. u8 eap_method;
  47. u8 *network_name;
  48. size_t network_name_len;
  49. u16 kdf;
  50. int kdf_negotiation;
  51. u16 last_kdf_attrs[EAP_AKA_PRIME_KDF_MAX];
  52. size_t last_kdf_count;
  53. };
  54. #ifndef CONFIG_NO_STDOUT_DEBUG
  55. static const char * eap_aka_state_txt(int state)
  56. {
  57. switch (state) {
  58. case CONTINUE:
  59. return "CONTINUE";
  60. case RESULT_SUCCESS:
  61. return "RESULT_SUCCESS";
  62. case SUCCESS:
  63. return "SUCCESS";
  64. case FAILURE:
  65. return "FAILURE";
  66. default:
  67. return "?";
  68. }
  69. }
  70. #endif /* CONFIG_NO_STDOUT_DEBUG */
  71. static void eap_aka_state(struct eap_aka_data *data, int state)
  72. {
  73. wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s",
  74. eap_aka_state_txt(data->state),
  75. eap_aka_state_txt(state));
  76. data->state = state;
  77. }
  78. static void * eap_aka_init(struct eap_sm *sm)
  79. {
  80. struct eap_aka_data *data;
  81. const char *phase1 = eap_get_config_phase1(sm);
  82. struct eap_peer_config *config = eap_get_config(sm);
  83. data = os_zalloc(sizeof(*data));
  84. if (data == NULL)
  85. return NULL;
  86. data->eap_method = EAP_TYPE_AKA;
  87. eap_aka_state(data, CONTINUE);
  88. data->prev_id = -1;
  89. data->result_ind = phase1 && os_strstr(phase1, "result_ind=1") != NULL;
  90. data->use_pseudonym = !sm->init_phase2;
  91. if (config && config->anonymous_identity && data->use_pseudonym) {
  92. data->pseudonym = os_malloc(config->anonymous_identity_len);
  93. if (data->pseudonym) {
  94. os_memcpy(data->pseudonym, config->anonymous_identity,
  95. config->anonymous_identity_len);
  96. data->pseudonym_len = config->anonymous_identity_len;
  97. }
  98. }
  99. return data;
  100. }
  101. #ifdef EAP_AKA_PRIME
  102. static void * eap_aka_prime_init(struct eap_sm *sm)
  103. {
  104. struct eap_aka_data *data = eap_aka_init(sm);
  105. if (data == NULL)
  106. return NULL;
  107. data->eap_method = EAP_TYPE_AKA_PRIME;
  108. return data;
  109. }
  110. #endif /* EAP_AKA_PRIME */
  111. static void eap_aka_clear_keys(struct eap_aka_data *data, int reauth)
  112. {
  113. if (!reauth) {
  114. os_memset(data->mk, 0, EAP_SIM_MK_LEN);
  115. os_memset(data->k_aut, 0, EAP_AKA_PRIME_K_AUT_LEN);
  116. os_memset(data->k_encr, 0, EAP_SIM_K_ENCR_LEN);
  117. os_memset(data->k_re, 0, EAP_AKA_PRIME_K_RE_LEN);
  118. }
  119. os_memset(data->msk, 0, EAP_SIM_KEYING_DATA_LEN);
  120. os_memset(data->emsk, 0, EAP_EMSK_LEN);
  121. os_memset(data->autn, 0, EAP_AKA_AUTN_LEN);
  122. os_memset(data->auts, 0, EAP_AKA_AUTS_LEN);
  123. }
  124. static void eap_aka_deinit(struct eap_sm *sm, void *priv)
  125. {
  126. struct eap_aka_data *data = priv;
  127. if (data) {
  128. os_free(data->pseudonym);
  129. os_free(data->reauth_id);
  130. os_free(data->last_eap_identity);
  131. wpabuf_free(data->id_msgs);
  132. os_free(data->network_name);
  133. eap_aka_clear_keys(data, 0);
  134. os_free(data);
  135. }
  136. }
  137. static int eap_aka_ext_sim_req(struct eap_sm *sm, struct eap_aka_data *data)
  138. {
  139. char req[200], *pos, *end;
  140. wpa_printf(MSG_DEBUG, "EAP-AKA: Use external USIM processing");
  141. pos = req;
  142. end = pos + sizeof(req);
  143. pos += os_snprintf(pos, end - pos, "UMTS-AUTH");
  144. pos += os_snprintf(pos, end - pos, ":");
  145. pos += wpa_snprintf_hex(pos, end - pos, data->rand, EAP_AKA_RAND_LEN);
  146. pos += os_snprintf(pos, end - pos, ":");
  147. wpa_snprintf_hex(pos, end - pos, data->autn, EAP_AKA_AUTN_LEN);
  148. eap_sm_request_sim(sm, req);
  149. return 1;
  150. }
  151. static int eap_aka_ext_sim_result(struct eap_sm *sm, struct eap_aka_data *data,
  152. struct eap_peer_config *conf)
  153. {
  154. char *resp, *pos;
  155. wpa_printf(MSG_DEBUG,
  156. "EAP-AKA: Use result from external USIM processing");
  157. resp = conf->external_sim_resp;
  158. conf->external_sim_resp = NULL;
  159. if (os_strncmp(resp, "UMTS-AUTS:", 10) == 0) {
  160. pos = resp + 10;
  161. if (hexstr2bin(pos, data->auts, EAP_AKA_AUTS_LEN) < 0)
  162. goto invalid;
  163. wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: AUTS", data->auts,
  164. EAP_AKA_AUTS_LEN);
  165. os_free(resp);
  166. return -2;
  167. }
  168. if (os_strncmp(resp, "UMTS-AUTH:", 10) != 0) {
  169. wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized external USIM processing response");
  170. os_free(resp);
  171. return -1;
  172. }
  173. pos = resp + 10;
  174. wpa_hexdump(MSG_DEBUG, "EAP-AKA: RAND", data->rand, EAP_AKA_RAND_LEN);
  175. if (hexstr2bin(pos, data->ik, EAP_AKA_IK_LEN) < 0)
  176. goto invalid;
  177. wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: IK", data->ik, EAP_AKA_IK_LEN);
  178. pos += EAP_AKA_IK_LEN * 2;
  179. if (*pos != ':')
  180. goto invalid;
  181. pos++;
  182. if (hexstr2bin(pos, data->ck, EAP_AKA_CK_LEN) < 0)
  183. goto invalid;
  184. wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: CK", data->ck, EAP_AKA_CK_LEN);
  185. pos += EAP_AKA_CK_LEN * 2;
  186. if (*pos != ':')
  187. goto invalid;
  188. pos++;
  189. data->res_len = os_strlen(pos) / 2;
  190. if (data->res_len > EAP_AKA_RES_MAX_LEN) {
  191. data->res_len = 0;
  192. goto invalid;
  193. }
  194. if (hexstr2bin(pos, data->res, data->res_len) < 0)
  195. goto invalid;
  196. wpa_hexdump_key(MSG_DEBUG, "EAP-AKA: RES", data->res, data->res_len);
  197. os_free(resp);
  198. return 0;
  199. invalid:
  200. wpa_printf(MSG_DEBUG, "EAP-AKA: Invalid external USIM processing UMTS-AUTH response");
  201. os_free(resp);
  202. return -1;
  203. }
  204. static int eap_aka_umts_auth(struct eap_sm *sm, struct eap_aka_data *data)
  205. {
  206. struct eap_peer_config *conf;
  207. wpa_printf(MSG_DEBUG, "EAP-AKA: UMTS authentication algorithm");
  208. conf = eap_get_config(sm);
  209. if (conf == NULL)
  210. return -1;
  211. if (sm->external_sim) {
  212. if (conf->external_sim_resp)
  213. return eap_aka_ext_sim_result(sm, data, conf);
  214. else
  215. return eap_aka_ext_sim_req(sm, data);
  216. }
  217. if (conf->pcsc) {
  218. return scard_umts_auth(sm->scard_ctx, data->rand,
  219. data->autn, data->res, &data->res_len,
  220. data->ik, data->ck, data->auts);
  221. }
  222. #ifdef CONFIG_USIM_SIMULATOR
  223. if (conf->password) {
  224. u8 opc[16], k[16], sqn[6];
  225. const char *pos;
  226. wpa_printf(MSG_DEBUG, "EAP-AKA: Use internal Milenage "
  227. "implementation for UMTS authentication");
  228. if (conf->password_len < 78) {
  229. wpa_printf(MSG_DEBUG, "EAP-AKA: invalid Milenage "
  230. "password");
  231. return -1;
  232. }
  233. pos = (const char *) conf->password;
  234. if (hexstr2bin(pos, k, 16))
  235. return -1;
  236. pos += 32;
  237. if (*pos != ':')
  238. return -1;
  239. pos++;
  240. if (hexstr2bin(pos, opc, 16))
  241. return -1;
  242. pos += 32;
  243. if (*pos != ':')
  244. return -1;
  245. pos++;
  246. if (hexstr2bin(pos, sqn, 6))
  247. return -1;
  248. return milenage_check(opc, k, sqn, data->rand, data->autn,
  249. data->ik, data->ck,
  250. data->res, &data->res_len, data->auts);
  251. }
  252. #endif /* CONFIG_USIM_SIMULATOR */
  253. #ifdef CONFIG_USIM_HARDCODED
  254. wpa_printf(MSG_DEBUG, "EAP-AKA: Use hardcoded Kc and SRES values for "
  255. "testing");
  256. /* These hardcoded Kc and SRES values are used for testing.
  257. * Could consider making them configurable. */
  258. os_memset(data->res, '2', EAP_AKA_RES_MAX_LEN);
  259. data->res_len = EAP_AKA_RES_MAX_LEN;
  260. os_memset(data->ik, '3', EAP_AKA_IK_LEN);
  261. os_memset(data->ck, '4', EAP_AKA_CK_LEN);
  262. {
  263. u8 autn[EAP_AKA_AUTN_LEN];
  264. os_memset(autn, '1', EAP_AKA_AUTN_LEN);
  265. if (os_memcmp_const(autn, data->autn, EAP_AKA_AUTN_LEN) != 0) {
  266. wpa_printf(MSG_WARNING, "EAP-AKA: AUTN did not match "
  267. "with expected value");
  268. return -1;
  269. }
  270. }
  271. #if 0
  272. {
  273. static int test_resync = 1;
  274. if (test_resync) {
  275. /* Test Resynchronization */
  276. test_resync = 0;
  277. return -2;
  278. }
  279. }
  280. #endif
  281. return 0;
  282. #else /* CONFIG_USIM_HARDCODED */
  283. wpa_printf(MSG_DEBUG, "EAP-AKA: No UMTS authentication algorithm "
  284. "enabled");
  285. return -1;
  286. #endif /* CONFIG_USIM_HARDCODED */
  287. }
  288. #define CLEAR_PSEUDONYM 0x01
  289. #define CLEAR_REAUTH_ID 0x02
  290. #define CLEAR_EAP_ID 0x04
  291. static void eap_aka_clear_identities(struct eap_sm *sm,
  292. struct eap_aka_data *data, int id)
  293. {
  294. if ((id & CLEAR_PSEUDONYM) && data->pseudonym) {
  295. wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old pseudonym");
  296. os_free(data->pseudonym);
  297. data->pseudonym = NULL;
  298. data->pseudonym_len = 0;
  299. if (data->use_pseudonym)
  300. eap_set_anon_id(sm, NULL, 0);
  301. }
  302. if ((id & CLEAR_REAUTH_ID) && data->reauth_id) {
  303. wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old reauth_id");
  304. os_free(data->reauth_id);
  305. data->reauth_id = NULL;
  306. data->reauth_id_len = 0;
  307. }
  308. if ((id & CLEAR_EAP_ID) && data->last_eap_identity) {
  309. wpa_printf(MSG_DEBUG, "EAP-AKA: forgetting old eap_id");
  310. os_free(data->last_eap_identity);
  311. data->last_eap_identity = NULL;
  312. data->last_eap_identity_len = 0;
  313. }
  314. }
  315. static int eap_aka_learn_ids(struct eap_sm *sm, struct eap_aka_data *data,
  316. struct eap_sim_attrs *attr)
  317. {
  318. if (attr->next_pseudonym) {
  319. const u8 *identity = NULL;
  320. size_t identity_len = 0;
  321. const u8 *realm = NULL;
  322. size_t realm_len = 0;
  323. wpa_hexdump_ascii(MSG_DEBUG,
  324. "EAP-AKA: (encr) AT_NEXT_PSEUDONYM",
  325. attr->next_pseudonym,
  326. attr->next_pseudonym_len);
  327. os_free(data->pseudonym);
  328. /* Look for the realm of the permanent identity */
  329. identity = eap_get_config_identity(sm, &identity_len);
  330. if (identity) {
  331. for (realm = identity, realm_len = identity_len;
  332. realm_len > 0; realm_len--, realm++) {
  333. if (*realm == '@')
  334. break;
  335. }
  336. }
  337. data->pseudonym = os_malloc(attr->next_pseudonym_len +
  338. realm_len);
  339. if (data->pseudonym == NULL) {
  340. wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
  341. "next pseudonym");
  342. data->pseudonym_len = 0;
  343. return -1;
  344. }
  345. os_memcpy(data->pseudonym, attr->next_pseudonym,
  346. attr->next_pseudonym_len);
  347. if (realm_len) {
  348. os_memcpy(data->pseudonym + attr->next_pseudonym_len,
  349. realm, realm_len);
  350. }
  351. data->pseudonym_len = attr->next_pseudonym_len + realm_len;
  352. if (data->use_pseudonym)
  353. eap_set_anon_id(sm, data->pseudonym,
  354. data->pseudonym_len);
  355. }
  356. if (attr->next_reauth_id) {
  357. os_free(data->reauth_id);
  358. data->reauth_id = os_memdup(attr->next_reauth_id,
  359. attr->next_reauth_id_len);
  360. if (data->reauth_id == NULL) {
  361. wpa_printf(MSG_INFO, "EAP-AKA: (encr) No memory for "
  362. "next reauth_id");
  363. data->reauth_id_len = 0;
  364. return -1;
  365. }
  366. data->reauth_id_len = attr->next_reauth_id_len;
  367. wpa_hexdump_ascii(MSG_DEBUG,
  368. "EAP-AKA: (encr) AT_NEXT_REAUTH_ID",
  369. data->reauth_id,
  370. data->reauth_id_len);
  371. }
  372. return 0;
  373. }
  374. static int eap_aka_add_id_msg(struct eap_aka_data *data,
  375. const struct wpabuf *msg)
  376. {
  377. if (msg == NULL)
  378. return -1;
  379. if (data->id_msgs == NULL) {
  380. data->id_msgs = wpabuf_dup(msg);
  381. return data->id_msgs == NULL ? -1 : 0;
  382. }
  383. if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
  384. return -1;
  385. wpabuf_put_buf(data->id_msgs, msg);
  386. return 0;
  387. }
  388. static void eap_aka_add_checkcode(struct eap_aka_data *data,
  389. struct eap_sim_msg *msg)
  390. {
  391. const u8 *addr;
  392. size_t len;
  393. u8 hash[SHA256_MAC_LEN];
  394. wpa_printf(MSG_DEBUG, " AT_CHECKCODE");
  395. if (data->id_msgs == NULL) {
  396. /*
  397. * No EAP-AKA/Identity packets were exchanged - send empty
  398. * checkcode.
  399. */
  400. eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0);
  401. return;
  402. }
  403. /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
  404. addr = wpabuf_head(data->id_msgs);
  405. len = wpabuf_len(data->id_msgs);
  406. wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
  407. #ifdef EAP_AKA_PRIME
  408. if (data->eap_method == EAP_TYPE_AKA_PRIME)
  409. sha256_vector(1, &addr, &len, hash);
  410. else
  411. #endif /* EAP_AKA_PRIME */
  412. sha1_vector(1, &addr, &len, hash);
  413. eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
  414. data->eap_method == EAP_TYPE_AKA_PRIME ?
  415. EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
  416. }
  417. static int eap_aka_verify_checkcode(struct eap_aka_data *data,
  418. const u8 *checkcode, size_t checkcode_len)
  419. {
  420. const u8 *addr;
  421. size_t len;
  422. u8 hash[SHA256_MAC_LEN];
  423. size_t hash_len;
  424. if (checkcode == NULL)
  425. return -1;
  426. if (data->id_msgs == NULL) {
  427. if (checkcode_len != 0) {
  428. wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
  429. "indicates that AKA/Identity messages were "
  430. "used, but they were not");
  431. return -1;
  432. }
  433. return 0;
  434. }
  435. hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
  436. EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
  437. if (checkcode_len != hash_len) {
  438. wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
  439. "indicates that AKA/Identity message were not "
  440. "used, but they were");
  441. return -1;
  442. }
  443. /* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
  444. addr = wpabuf_head(data->id_msgs);
  445. len = wpabuf_len(data->id_msgs);
  446. #ifdef EAP_AKA_PRIME
  447. if (data->eap_method == EAP_TYPE_AKA_PRIME)
  448. sha256_vector(1, &addr, &len, hash);
  449. else
  450. #endif /* EAP_AKA_PRIME */
  451. sha1_vector(1, &addr, &len, hash);
  452. if (os_memcmp_const(hash, checkcode, hash_len) != 0) {
  453. wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
  454. return -1;
  455. }
  456. return 0;
  457. }
  458. static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id,
  459. int err)
  460. {
  461. struct eap_sim_msg *msg;
  462. eap_aka_state(data, FAILURE);
  463. data->num_id_req = 0;
  464. data->num_notification = 0;
  465. wpa_printf(MSG_DEBUG, "EAP-AKA: Send Client-Error (error code %d)",
  466. err);
  467. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  468. EAP_AKA_SUBTYPE_CLIENT_ERROR);
  469. eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
  470. return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
  471. }
  472. static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data,
  473. u8 id)
  474. {
  475. struct eap_sim_msg *msg;
  476. eap_aka_state(data, FAILURE);
  477. data->num_id_req = 0;
  478. data->num_notification = 0;
  479. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
  480. "(id=%d)", id);
  481. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  482. EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
  483. return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
  484. }
  485. static struct wpabuf * eap_aka_synchronization_failure(
  486. struct eap_aka_data *data, u8 id, struct eap_sim_attrs *attr)
  487. {
  488. struct eap_sim_msg *msg;
  489. data->num_id_req = 0;
  490. data->num_notification = 0;
  491. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
  492. "(id=%d)", id);
  493. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  494. EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
  495. wpa_printf(MSG_DEBUG, " AT_AUTS");
  496. eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
  497. EAP_AKA_AUTS_LEN);
  498. if (data->eap_method == EAP_TYPE_AKA_PRIME) {
  499. size_t i;
  500. for (i = 0; i < attr->kdf_count; i++) {
  501. wpa_printf(MSG_DEBUG, " AT_KDF");
  502. eap_sim_msg_add(msg, EAP_SIM_AT_KDF, attr->kdf[i],
  503. NULL, 0);
  504. }
  505. }
  506. return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
  507. }
  508. static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
  509. struct eap_aka_data *data,
  510. u8 id,
  511. enum eap_sim_id_req id_req)
  512. {
  513. const u8 *identity = NULL;
  514. size_t identity_len = 0;
  515. struct eap_sim_msg *msg;
  516. data->reauth = 0;
  517. if (id_req == ANY_ID && data->reauth_id) {
  518. identity = data->reauth_id;
  519. identity_len = data->reauth_id_len;
  520. data->reauth = 1;
  521. } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
  522. data->pseudonym) {
  523. identity = data->pseudonym;
  524. identity_len = data->pseudonym_len;
  525. eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
  526. } else if (id_req != NO_ID_REQ) {
  527. identity = eap_get_config_identity(sm, &identity_len);
  528. if (identity) {
  529. eap_aka_clear_identities(sm, data, CLEAR_PSEUDONYM |
  530. CLEAR_REAUTH_ID);
  531. }
  532. }
  533. if (id_req != NO_ID_REQ)
  534. eap_aka_clear_identities(sm, data, CLEAR_EAP_ID);
  535. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);
  536. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  537. EAP_AKA_SUBTYPE_IDENTITY);
  538. if (identity) {
  539. wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY",
  540. identity, identity_len);
  541. eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
  542. identity, identity_len);
  543. }
  544. return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
  545. }
  546. static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data,
  547. u8 id)
  548. {
  549. struct eap_sim_msg *msg;
  550. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);
  551. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  552. EAP_AKA_SUBTYPE_CHALLENGE);
  553. wpa_printf(MSG_DEBUG, " AT_RES");
  554. eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
  555. data->res, data->res_len);
  556. eap_aka_add_checkcode(data, msg);
  557. if (data->use_result_ind) {
  558. wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
  559. eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
  560. }
  561. wpa_printf(MSG_DEBUG, " AT_MAC");
  562. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  563. return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, (u8 *) "",
  564. 0);
  565. }
  566. static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data,
  567. u8 id, int counter_too_small,
  568. const u8 *nonce_s)
  569. {
  570. struct eap_sim_msg *msg;
  571. unsigned int counter;
  572. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
  573. id);
  574. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  575. EAP_AKA_SUBTYPE_REAUTHENTICATION);
  576. wpa_printf(MSG_DEBUG, " AT_IV");
  577. wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
  578. eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
  579. if (counter_too_small) {
  580. wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL");
  581. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
  582. counter = data->counter_too_small;
  583. } else
  584. counter = data->counter;
  585. wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter);
  586. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
  587. if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
  588. wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
  589. "AT_ENCR_DATA");
  590. eap_sim_msg_free(msg);
  591. return NULL;
  592. }
  593. eap_aka_add_checkcode(data, msg);
  594. if (data->use_result_ind) {
  595. wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
  596. eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
  597. }
  598. wpa_printf(MSG_DEBUG, " AT_MAC");
  599. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  600. return eap_sim_msg_finish(msg, data->eap_method, data->k_aut, nonce_s,
  601. EAP_SIM_NONCE_S_LEN);
  602. }
  603. static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data,
  604. u8 id, u16 notification)
  605. {
  606. struct eap_sim_msg *msg;
  607. u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
  608. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);
  609. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  610. EAP_AKA_SUBTYPE_NOTIFICATION);
  611. if (k_aut && data->reauth) {
  612. wpa_printf(MSG_DEBUG, " AT_IV");
  613. wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
  614. eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
  615. EAP_SIM_AT_ENCR_DATA);
  616. wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter);
  617. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
  618. NULL, 0);
  619. if (eap_sim_msg_add_encr_end(msg, data->k_encr,
  620. EAP_SIM_AT_PADDING)) {
  621. wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
  622. "AT_ENCR_DATA");
  623. eap_sim_msg_free(msg);
  624. return NULL;
  625. }
  626. }
  627. if (k_aut) {
  628. wpa_printf(MSG_DEBUG, " AT_MAC");
  629. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  630. }
  631. return eap_sim_msg_finish(msg, data->eap_method, k_aut, (u8 *) "", 0);
  632. }
  633. static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm,
  634. struct eap_aka_data *data,
  635. u8 id,
  636. const struct wpabuf *reqData,
  637. struct eap_sim_attrs *attr)
  638. {
  639. int id_error;
  640. struct wpabuf *buf;
  641. wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");
  642. id_error = 0;
  643. switch (attr->id_req) {
  644. case NO_ID_REQ:
  645. break;
  646. case ANY_ID:
  647. if (data->num_id_req > 0)
  648. id_error++;
  649. data->num_id_req++;
  650. break;
  651. case FULLAUTH_ID:
  652. if (data->num_id_req > 1)
  653. id_error++;
  654. data->num_id_req++;
  655. break;
  656. case PERMANENT_ID:
  657. if (data->num_id_req > 2)
  658. id_error++;
  659. data->num_id_req++;
  660. break;
  661. }
  662. if (id_error) {
  663. wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "
  664. "used within one authentication");
  665. return eap_aka_client_error(data, id,
  666. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  667. }
  668. buf = eap_aka_response_identity(sm, data, id, attr->id_req);
  669. if (data->prev_id != id) {
  670. eap_aka_add_id_msg(data, reqData);
  671. eap_aka_add_id_msg(data, buf);
  672. data->prev_id = id;
  673. }
  674. return buf;
  675. }
  676. static int eap_aka_verify_mac(struct eap_aka_data *data,
  677. const struct wpabuf *req,
  678. const u8 *mac, const u8 *extra,
  679. size_t extra_len)
  680. {
  681. if (data->eap_method == EAP_TYPE_AKA_PRIME)
  682. return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra,
  683. extra_len);
  684. return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);
  685. }
  686. #ifdef EAP_AKA_PRIME
  687. static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data,
  688. u8 id, u16 kdf)
  689. {
  690. struct eap_sim_msg *msg;
  691. data->kdf_negotiation = 1;
  692. data->kdf = kdf;
  693. wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF "
  694. "select)", id);
  695. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
  696. EAP_AKA_SUBTYPE_CHALLENGE);
  697. wpa_printf(MSG_DEBUG, " AT_KDF");
  698. eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);
  699. return eap_sim_msg_finish(msg, data->eap_method, NULL, NULL, 0);
  700. }
  701. static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data,
  702. u8 id, struct eap_sim_attrs *attr)
  703. {
  704. size_t i;
  705. for (i = 0; i < attr->kdf_count; i++) {
  706. if (attr->kdf[i] == EAP_AKA_PRIME_KDF) {
  707. os_memcpy(data->last_kdf_attrs, attr->kdf,
  708. sizeof(u16) * attr->kdf_count);
  709. data->last_kdf_count = attr->kdf_count;
  710. return eap_aka_prime_kdf_select(data, id,
  711. EAP_AKA_PRIME_KDF);
  712. }
  713. }
  714. /* No matching KDF found - fail authentication as if AUTN had been
  715. * incorrect */
  716. return eap_aka_authentication_reject(data, id);
  717. }
  718. static int eap_aka_prime_kdf_valid(struct eap_aka_data *data,
  719. struct eap_sim_attrs *attr)
  720. {
  721. size_t i, j;
  722. if (attr->kdf_count == 0)
  723. return 0;
  724. /* The only allowed (and required) duplication of a KDF is the addition
  725. * of the selected KDF into the beginning of the list. */
  726. if (data->kdf_negotiation) {
  727. /* When the peer receives the new EAP-Request/AKA'-Challenge
  728. * message, must check only requested change occurred in the
  729. * list of AT_KDF attributes. If there are any other changes,
  730. * the peer must behave like the case that AT_MAC had been
  731. * incorrect and authentication is failed. These are defined in
  732. * EAP-AKA' specification RFC 5448, Section 3.2. */
  733. if (attr->kdf[0] != data->kdf) {
  734. wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
  735. "accept the selected KDF");
  736. return -1;
  737. }
  738. if (attr->kdf_count > EAP_AKA_PRIME_KDF_MAX ||
  739. attr->kdf_count != data->last_kdf_count + 1) {
  740. wpa_printf(MSG_WARNING,
  741. "EAP-AKA': The length of KDF attributes is wrong");
  742. return -1;
  743. }
  744. for (i = 1; i < attr->kdf_count; i++) {
  745. if (attr->kdf[i] != data->last_kdf_attrs[i - 1]) {
  746. wpa_printf(MSG_WARNING,
  747. "EAP-AKA': The KDF attributes except selected KDF are not same as original one");
  748. return -1;
  749. }
  750. }
  751. }
  752. for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) {
  753. for (j = i + 1; j < attr->kdf_count; j++) {
  754. if (attr->kdf[i] == attr->kdf[j]) {
  755. wpa_printf(MSG_WARNING, "EAP-AKA': The server "
  756. "included a duplicated KDF");
  757. return 0;
  758. }
  759. }
  760. }
  761. return 1;
  762. }
  763. #endif /* EAP_AKA_PRIME */
  764. static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
  765. struct eap_aka_data *data,
  766. u8 id,
  767. const struct wpabuf *reqData,
  768. struct eap_sim_attrs *attr)
  769. {
  770. const u8 *identity;
  771. size_t identity_len;
  772. int res;
  773. struct eap_sim_attrs eattr;
  774. wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");
  775. if (attr->checkcode &&
  776. eap_aka_verify_checkcode(data, attr->checkcode,
  777. attr->checkcode_len)) {
  778. wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
  779. "message");
  780. return eap_aka_client_error(data, id,
  781. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  782. }
  783. #ifdef EAP_AKA_PRIME
  784. if (data->eap_method == EAP_TYPE_AKA_PRIME) {
  785. if (!attr->kdf_input || attr->kdf_input_len == 0) {
  786. wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message "
  787. "did not include non-empty AT_KDF_INPUT");
  788. /* Fail authentication as if AUTN had been incorrect */
  789. return eap_aka_authentication_reject(data, id);
  790. }
  791. os_free(data->network_name);
  792. data->network_name = os_memdup(attr->kdf_input,
  793. attr->kdf_input_len);
  794. if (data->network_name == NULL) {
  795. wpa_printf(MSG_WARNING, "EAP-AKA': No memory for "
  796. "storing Network Name");
  797. return eap_aka_authentication_reject(data, id);
  798. }
  799. data->network_name_len = attr->kdf_input_len;
  800. wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name "
  801. "(AT_KDF_INPUT)",
  802. data->network_name, data->network_name_len);
  803. /* TODO: check Network Name per 3GPP.33.402 */
  804. res = eap_aka_prime_kdf_valid(data, attr);
  805. if (res == 0)
  806. return eap_aka_authentication_reject(data, id);
  807. else if (res == -1)
  808. return eap_aka_client_error(
  809. data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  810. if (attr->kdf[0] != EAP_AKA_PRIME_KDF)
  811. return eap_aka_prime_kdf_neg(data, id, attr);
  812. data->kdf = EAP_AKA_PRIME_KDF;
  813. wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);
  814. }
  815. if (data->eap_method == EAP_TYPE_AKA && attr->bidding) {
  816. u16 flags = WPA_GET_BE16(attr->bidding);
  817. if ((flags & EAP_AKA_BIDDING_FLAG_D) &&
  818. eap_allowed_method(sm, EAP_VENDOR_IETF,
  819. EAP_TYPE_AKA_PRIME)) {
  820. wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from "
  821. "AKA' to AKA detected");
  822. /* Fail authentication as if AUTN had been incorrect */
  823. return eap_aka_authentication_reject(data, id);
  824. }
  825. }
  826. #endif /* EAP_AKA_PRIME */
  827. data->reauth = 0;
  828. if (!attr->mac || !attr->rand || !attr->autn) {
  829. wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
  830. "did not include%s%s%s",
  831. !attr->mac ? " AT_MAC" : "",
  832. !attr->rand ? " AT_RAND" : "",
  833. !attr->autn ? " AT_AUTN" : "");
  834. return eap_aka_client_error(data, id,
  835. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  836. }
  837. os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);
  838. os_memcpy(data->autn, attr->autn, EAP_AKA_AUTN_LEN);
  839. res = eap_aka_umts_auth(sm, data);
  840. if (res == -1) {
  841. wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
  842. "failed (AUTN)");
  843. return eap_aka_authentication_reject(data, id);
  844. } else if (res == -2) {
  845. wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
  846. "failed (AUTN seq# -> AUTS)");
  847. return eap_aka_synchronization_failure(data, id, attr);
  848. } else if (res > 0) {
  849. wpa_printf(MSG_DEBUG, "EAP-AKA: Wait for external USIM processing");
  850. return NULL;
  851. } else if (res) {
  852. wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");
  853. return eap_aka_client_error(data, id,
  854. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  855. }
  856. #ifdef EAP_AKA_PRIME
  857. if (data->eap_method == EAP_TYPE_AKA_PRIME) {
  858. /* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the
  859. * needed 6-octet SQN ^ AK for CK',IK' derivation */
  860. u16 amf = WPA_GET_BE16(data->autn + 6);
  861. if (!(amf & 0x8000)) {
  862. wpa_printf(MSG_WARNING, "EAP-AKA': AMF separation bit "
  863. "not set (AMF=0x%4x)", amf);
  864. return eap_aka_authentication_reject(data, id);
  865. }
  866. eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,
  867. data->autn,
  868. data->network_name,
  869. data->network_name_len);
  870. }
  871. #endif /* EAP_AKA_PRIME */
  872. if (data->last_eap_identity) {
  873. identity = data->last_eap_identity;
  874. identity_len = data->last_eap_identity_len;
  875. } else if (data->pseudonym) {
  876. identity = data->pseudonym;
  877. identity_len = data->pseudonym_len;
  878. } else
  879. identity = eap_get_config_identity(sm, &identity_len);
  880. wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
  881. "derivation", identity, identity_len);
  882. if (data->eap_method == EAP_TYPE_AKA_PRIME) {
  883. eap_aka_prime_derive_keys(identity, identity_len, data->ik,
  884. data->ck, data->k_encr, data->k_aut,
  885. data->k_re, data->msk, data->emsk);
  886. } else {
  887. eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
  888. data->mk);
  889. eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
  890. data->msk, data->emsk);
  891. }
  892. if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
  893. wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
  894. "used invalid AT_MAC");
  895. return eap_aka_client_error(data, id,
  896. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  897. }
  898. /* Old reauthentication identity must not be used anymore. In
  899. * other words, if no new identities are received, full
  900. * authentication will be used on next reauthentication (using
  901. * pseudonym identity or permanent identity). */
  902. eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
  903. if (attr->encr_data) {
  904. u8 *decrypted;
  905. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  906. attr->encr_data_len, attr->iv,
  907. &eattr, 0);
  908. if (decrypted == NULL) {
  909. return eap_aka_client_error(
  910. data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  911. }
  912. eap_aka_learn_ids(sm, data, &eattr);
  913. os_free(decrypted);
  914. }
  915. if (data->result_ind && attr->result_ind)
  916. data->use_result_ind = 1;
  917. if (data->state != FAILURE) {
  918. eap_aka_state(data, data->use_result_ind ?
  919. RESULT_SUCCESS : SUCCESS);
  920. }
  921. data->num_id_req = 0;
  922. data->num_notification = 0;
  923. /* RFC 4187 specifies that counter is initialized to one after
  924. * fullauth, but initializing it to zero makes it easier to implement
  925. * reauth verification. */
  926. data->counter = 0;
  927. return eap_aka_response_challenge(data, id);
  928. }
  929. static int eap_aka_process_notification_reauth(struct eap_aka_data *data,
  930. struct eap_sim_attrs *attr)
  931. {
  932. struct eap_sim_attrs eattr;
  933. u8 *decrypted;
  934. if (attr->encr_data == NULL || attr->iv == NULL) {
  935. wpa_printf(MSG_WARNING, "EAP-AKA: Notification message after "
  936. "reauth did not include encrypted data");
  937. return -1;
  938. }
  939. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  940. attr->encr_data_len, attr->iv, &eattr,
  941. 0);
  942. if (decrypted == NULL) {
  943. wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
  944. "data from notification message");
  945. return -1;
  946. }
  947. if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
  948. wpa_printf(MSG_WARNING, "EAP-AKA: Counter in notification "
  949. "message does not match with counter in reauth "
  950. "message");
  951. os_free(decrypted);
  952. return -1;
  953. }
  954. os_free(decrypted);
  955. return 0;
  956. }
  957. static int eap_aka_process_notification_auth(struct eap_aka_data *data,
  958. const struct wpabuf *reqData,
  959. struct eap_sim_attrs *attr)
  960. {
  961. if (attr->mac == NULL) {
  962. wpa_printf(MSG_INFO, "EAP-AKA: no AT_MAC in after_auth "
  963. "Notification message");
  964. return -1;
  965. }
  966. if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
  967. wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
  968. "used invalid AT_MAC");
  969. return -1;
  970. }
  971. if (data->reauth &&
  972. eap_aka_process_notification_reauth(data, attr)) {
  973. wpa_printf(MSG_WARNING, "EAP-AKA: Invalid notification "
  974. "message after reauth");
  975. return -1;
  976. }
  977. return 0;
  978. }
  979. static struct wpabuf * eap_aka_process_notification(
  980. struct eap_sm *sm, struct eap_aka_data *data, u8 id,
  981. const struct wpabuf *reqData, struct eap_sim_attrs *attr)
  982. {
  983. wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification");
  984. if (data->num_notification > 0) {
  985. wpa_printf(MSG_INFO, "EAP-AKA: too many notification "
  986. "rounds (only one allowed)");
  987. return eap_aka_client_error(data, id,
  988. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  989. }
  990. data->num_notification++;
  991. if (attr->notification == -1) {
  992. wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in "
  993. "Notification message");
  994. return eap_aka_client_error(data, id,
  995. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  996. }
  997. if ((attr->notification & 0x4000) == 0 &&
  998. eap_aka_process_notification_auth(data, reqData, attr)) {
  999. return eap_aka_client_error(data, id,
  1000. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1001. }
  1002. eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
  1003. if (attr->notification >= 0 && attr->notification < 32768) {
  1004. eap_aka_state(data, FAILURE);
  1005. } else if (attr->notification == EAP_SIM_SUCCESS &&
  1006. data->state == RESULT_SUCCESS)
  1007. eap_aka_state(data, SUCCESS);
  1008. return eap_aka_response_notification(data, id, attr->notification);
  1009. }
  1010. static struct wpabuf * eap_aka_process_reauthentication(
  1011. struct eap_sm *sm, struct eap_aka_data *data, u8 id,
  1012. const struct wpabuf *reqData, struct eap_sim_attrs *attr)
  1013. {
  1014. struct eap_sim_attrs eattr;
  1015. u8 *decrypted;
  1016. wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication");
  1017. if (attr->checkcode &&
  1018. eap_aka_verify_checkcode(data, attr->checkcode,
  1019. attr->checkcode_len)) {
  1020. wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
  1021. "message");
  1022. return eap_aka_client_error(data, id,
  1023. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1024. }
  1025. if (data->reauth_id == NULL) {
  1026. wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying "
  1027. "reauthentication, but no reauth_id available");
  1028. return eap_aka_client_error(data, id,
  1029. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1030. }
  1031. data->reauth = 1;
  1032. if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
  1033. wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
  1034. "did not have valid AT_MAC");
  1035. return eap_aka_client_error(data, id,
  1036. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1037. }
  1038. if (attr->encr_data == NULL || attr->iv == NULL) {
  1039. wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
  1040. "message did not include encrypted data");
  1041. return eap_aka_client_error(data, id,
  1042. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1043. }
  1044. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  1045. attr->encr_data_len, attr->iv, &eattr,
  1046. 0);
  1047. if (decrypted == NULL) {
  1048. wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
  1049. "data from reauthentication message");
  1050. return eap_aka_client_error(data, id,
  1051. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1052. }
  1053. if (eattr.nonce_s == NULL || eattr.counter < 0) {
  1054. wpa_printf(MSG_INFO, "EAP-AKA: (encr) No%s%s in reauth packet",
  1055. !eattr.nonce_s ? " AT_NONCE_S" : "",
  1056. eattr.counter < 0 ? " AT_COUNTER" : "");
  1057. os_free(decrypted);
  1058. return eap_aka_client_error(data, id,
  1059. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1060. }
  1061. if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
  1062. struct wpabuf *res;
  1063. wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
  1064. "(%d <= %d)", eattr.counter, data->counter);
  1065. data->counter_too_small = eattr.counter;
  1066. /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
  1067. * reauth_id must not be used to start a new reauthentication.
  1068. * However, since it was used in the last EAP-Response-Identity
  1069. * packet, it has to saved for the following fullauth to be
  1070. * used in MK derivation. */
  1071. os_free(data->last_eap_identity);
  1072. data->last_eap_identity = data->reauth_id;
  1073. data->last_eap_identity_len = data->reauth_id_len;
  1074. data->reauth_id = NULL;
  1075. data->reauth_id_len = 0;
  1076. res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s);
  1077. os_free(decrypted);
  1078. return res;
  1079. }
  1080. data->counter = eattr.counter;
  1081. os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
  1082. wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
  1083. data->nonce_s, EAP_SIM_NONCE_S_LEN);
  1084. if (data->eap_method == EAP_TYPE_AKA_PRIME) {
  1085. eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
  1086. data->reauth_id,
  1087. data->reauth_id_len,
  1088. data->nonce_s,
  1089. data->msk, data->emsk);
  1090. } else {
  1091. eap_sim_derive_keys_reauth(data->counter, data->reauth_id,
  1092. data->reauth_id_len,
  1093. data->nonce_s, data->mk,
  1094. data->msk, data->emsk);
  1095. }
  1096. eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
  1097. eap_aka_learn_ids(sm, data, &eattr);
  1098. if (data->result_ind && attr->result_ind)
  1099. data->use_result_ind = 1;
  1100. if (data->state != FAILURE) {
  1101. eap_aka_state(data, data->use_result_ind ?
  1102. RESULT_SUCCESS : SUCCESS);
  1103. }
  1104. data->num_id_req = 0;
  1105. data->num_notification = 0;
  1106. if (data->counter > EAP_AKA_MAX_FAST_REAUTHS) {
  1107. wpa_printf(MSG_DEBUG, "EAP-AKA: Maximum number of "
  1108. "fast reauths performed - force fullauth");
  1109. eap_aka_clear_identities(sm, data,
  1110. CLEAR_REAUTH_ID | CLEAR_EAP_ID);
  1111. }
  1112. os_free(decrypted);
  1113. return eap_aka_response_reauth(data, id, 0, data->nonce_s);
  1114. }
  1115. static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
  1116. struct eap_method_ret *ret,
  1117. const struct wpabuf *reqData)
  1118. {
  1119. struct eap_aka_data *data = priv;
  1120. const struct eap_hdr *req;
  1121. u8 subtype, id;
  1122. struct wpabuf *res;
  1123. const u8 *pos;
  1124. struct eap_sim_attrs attr;
  1125. size_t len;
  1126. wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData);
  1127. if (eap_get_config_identity(sm, &len) == NULL) {
  1128. wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
  1129. eap_sm_request_identity(sm);
  1130. ret->ignore = TRUE;
  1131. return NULL;
  1132. }
  1133. pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
  1134. &len);
  1135. if (pos == NULL || len < 3) {
  1136. ret->ignore = TRUE;
  1137. return NULL;
  1138. }
  1139. req = wpabuf_head(reqData);
  1140. id = req->identifier;
  1141. len = be_to_host16(req->length);
  1142. ret->ignore = FALSE;
  1143. ret->methodState = METHOD_MAY_CONT;
  1144. ret->decision = DECISION_FAIL;
  1145. ret->allowNotifications = TRUE;
  1146. subtype = *pos++;
  1147. wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
  1148. pos += 2; /* Reserved */
  1149. if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr,
  1150. data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
  1151. 0)) {
  1152. res = eap_aka_client_error(data, id,
  1153. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1154. goto done;
  1155. }
  1156. switch (subtype) {
  1157. case EAP_AKA_SUBTYPE_IDENTITY:
  1158. res = eap_aka_process_identity(sm, data, id, reqData, &attr);
  1159. break;
  1160. case EAP_AKA_SUBTYPE_CHALLENGE:
  1161. res = eap_aka_process_challenge(sm, data, id, reqData, &attr);
  1162. break;
  1163. case EAP_AKA_SUBTYPE_NOTIFICATION:
  1164. res = eap_aka_process_notification(sm, data, id, reqData,
  1165. &attr);
  1166. break;
  1167. case EAP_AKA_SUBTYPE_REAUTHENTICATION:
  1168. res = eap_aka_process_reauthentication(sm, data, id, reqData,
  1169. &attr);
  1170. break;
  1171. case EAP_AKA_SUBTYPE_CLIENT_ERROR:
  1172. wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
  1173. res = eap_aka_client_error(data, id,
  1174. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1175. break;
  1176. default:
  1177. wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
  1178. res = eap_aka_client_error(data, id,
  1179. EAP_AKA_UNABLE_TO_PROCESS_PACKET);
  1180. break;
  1181. }
  1182. done:
  1183. if (data->state == FAILURE) {
  1184. ret->decision = DECISION_FAIL;
  1185. ret->methodState = METHOD_DONE;
  1186. } else if (data->state == SUCCESS) {
  1187. ret->decision = data->use_result_ind ?
  1188. DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
  1189. /*
  1190. * It is possible for the server to reply with AKA
  1191. * Notification, so we must allow the method to continue and
  1192. * not only accept EAP-Success at this point.
  1193. */
  1194. ret->methodState = data->use_result_ind ?
  1195. METHOD_DONE : METHOD_MAY_CONT;
  1196. } else if (data->state == RESULT_SUCCESS)
  1197. ret->methodState = METHOD_CONT;
  1198. if (ret->methodState == METHOD_DONE) {
  1199. ret->allowNotifications = FALSE;
  1200. }
  1201. return res;
  1202. }
  1203. static Boolean eap_aka_has_reauth_data(struct eap_sm *sm, void *priv)
  1204. {
  1205. struct eap_aka_data *data = priv;
  1206. return data->pseudonym || data->reauth_id;
  1207. }
  1208. static void eap_aka_deinit_for_reauth(struct eap_sm *sm, void *priv)
  1209. {
  1210. struct eap_aka_data *data = priv;
  1211. eap_aka_clear_identities(sm, data, CLEAR_EAP_ID);
  1212. data->prev_id = -1;
  1213. wpabuf_free(data->id_msgs);
  1214. data->id_msgs = NULL;
  1215. data->use_result_ind = 0;
  1216. data->kdf_negotiation = 0;
  1217. eap_aka_clear_keys(data, 1);
  1218. }
  1219. static void * eap_aka_init_for_reauth(struct eap_sm *sm, void *priv)
  1220. {
  1221. struct eap_aka_data *data = priv;
  1222. data->num_id_req = 0;
  1223. data->num_notification = 0;
  1224. eap_aka_state(data, CONTINUE);
  1225. return priv;
  1226. }
  1227. static const u8 * eap_aka_get_identity(struct eap_sm *sm, void *priv,
  1228. size_t *len)
  1229. {
  1230. struct eap_aka_data *data = priv;
  1231. if (data->reauth_id) {
  1232. *len = data->reauth_id_len;
  1233. return data->reauth_id;
  1234. }
  1235. if (data->pseudonym) {
  1236. *len = data->pseudonym_len;
  1237. return data->pseudonym;
  1238. }
  1239. return NULL;
  1240. }
  1241. static Boolean eap_aka_isKeyAvailable(struct eap_sm *sm, void *priv)
  1242. {
  1243. struct eap_aka_data *data = priv;
  1244. return data->state == SUCCESS;
  1245. }
  1246. static u8 * eap_aka_getKey(struct eap_sm *sm, void *priv, size_t *len)
  1247. {
  1248. struct eap_aka_data *data = priv;
  1249. u8 *key;
  1250. if (data->state != SUCCESS)
  1251. return NULL;
  1252. key = os_memdup(data->msk, EAP_SIM_KEYING_DATA_LEN);
  1253. if (key == NULL)
  1254. return NULL;
  1255. *len = EAP_SIM_KEYING_DATA_LEN;
  1256. return key;
  1257. }
  1258. static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
  1259. {
  1260. struct eap_aka_data *data = priv;
  1261. u8 *id;
  1262. if (data->state != SUCCESS)
  1263. return NULL;
  1264. *len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
  1265. id = os_malloc(*len);
  1266. if (id == NULL)
  1267. return NULL;
  1268. id[0] = data->eap_method;
  1269. os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
  1270. os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN);
  1271. wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len);
  1272. return id;
  1273. }
  1274. static u8 * eap_aka_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
  1275. {
  1276. struct eap_aka_data *data = priv;
  1277. u8 *key;
  1278. if (data->state != SUCCESS)
  1279. return NULL;
  1280. key = os_memdup(data->emsk, EAP_EMSK_LEN);
  1281. if (key == NULL)
  1282. return NULL;
  1283. *len = EAP_EMSK_LEN;
  1284. return key;
  1285. }
  1286. int eap_peer_aka_register(void)
  1287. {
  1288. struct eap_method *eap;
  1289. eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
  1290. EAP_VENDOR_IETF, EAP_TYPE_AKA, "AKA");
  1291. if (eap == NULL)
  1292. return -1;
  1293. eap->init = eap_aka_init;
  1294. eap->deinit = eap_aka_deinit;
  1295. eap->process = eap_aka_process;
  1296. eap->isKeyAvailable = eap_aka_isKeyAvailable;
  1297. eap->getKey = eap_aka_getKey;
  1298. eap->getSessionId = eap_aka_get_session_id;
  1299. eap->has_reauth_data = eap_aka_has_reauth_data;
  1300. eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
  1301. eap->init_for_reauth = eap_aka_init_for_reauth;
  1302. eap->get_identity = eap_aka_get_identity;
  1303. eap->get_emsk = eap_aka_get_emsk;
  1304. return eap_peer_method_register(eap);
  1305. }
  1306. #ifdef EAP_AKA_PRIME
  1307. int eap_peer_aka_prime_register(void)
  1308. {
  1309. struct eap_method *eap;
  1310. eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
  1311. EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,
  1312. "AKA'");
  1313. if (eap == NULL)
  1314. return -1;
  1315. eap->init = eap_aka_prime_init;
  1316. eap->deinit = eap_aka_deinit;
  1317. eap->process = eap_aka_process;
  1318. eap->isKeyAvailable = eap_aka_isKeyAvailable;
  1319. eap->getKey = eap_aka_getKey;
  1320. eap->getSessionId = eap_aka_get_session_id;
  1321. eap->has_reauth_data = eap_aka_has_reauth_data;
  1322. eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
  1323. eap->init_for_reauth = eap_aka_init_for_reauth;
  1324. eap->get_identity = eap_aka_get_identity;
  1325. eap->get_emsk = eap_aka_get_emsk;
  1326. return eap_peer_method_register(eap);
  1327. }
  1328. #endif /* EAP_AKA_PRIME */