eap_aka.c 38 KB

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