eap_sim.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  1. /*
  2. * EAP peer method: EAP-SIM (RFC 4186)
  3. * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "pcsc_funcs.h"
  17. #include "crypto/milenage.h"
  18. #include "eap_peer/eap_i.h"
  19. #include "eap_config.h"
  20. #include "eap_common/eap_sim_common.h"
  21. struct eap_sim_data {
  22. u8 *ver_list;
  23. size_t ver_list_len;
  24. int selected_version;
  25. size_t min_num_chal, num_chal;
  26. u8 kc[3][EAP_SIM_KC_LEN];
  27. u8 sres[3][EAP_SIM_SRES_LEN];
  28. u8 nonce_mt[EAP_SIM_NONCE_MT_LEN], nonce_s[EAP_SIM_NONCE_S_LEN];
  29. u8 mk[EAP_SIM_MK_LEN];
  30. u8 k_aut[EAP_SIM_K_AUT_LEN];
  31. u8 k_encr[EAP_SIM_K_ENCR_LEN];
  32. u8 msk[EAP_SIM_KEYING_DATA_LEN];
  33. u8 emsk[EAP_EMSK_LEN];
  34. u8 rand[3][GSM_RAND_LEN];
  35. int num_id_req, num_notification;
  36. u8 *pseudonym;
  37. size_t pseudonym_len;
  38. u8 *reauth_id;
  39. size_t reauth_id_len;
  40. int reauth;
  41. unsigned int counter, counter_too_small;
  42. u8 *last_eap_identity;
  43. size_t last_eap_identity_len;
  44. enum {
  45. CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE
  46. } state;
  47. int result_ind, use_result_ind;
  48. };
  49. #ifndef CONFIG_NO_STDOUT_DEBUG
  50. static const char * eap_sim_state_txt(int state)
  51. {
  52. switch (state) {
  53. case CONTINUE:
  54. return "CONTINUE";
  55. case RESULT_SUCCESS:
  56. return "RESULT_SUCCESS";
  57. case RESULT_FAILURE:
  58. return "RESULT_FAILURE";
  59. case SUCCESS:
  60. return "SUCCESS";
  61. case FAILURE:
  62. return "FAILURE";
  63. default:
  64. return "?";
  65. }
  66. }
  67. #endif /* CONFIG_NO_STDOUT_DEBUG */
  68. static void eap_sim_state(struct eap_sim_data *data, int state)
  69. {
  70. wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s",
  71. eap_sim_state_txt(data->state),
  72. eap_sim_state_txt(state));
  73. data->state = state;
  74. }
  75. static void * eap_sim_init(struct eap_sm *sm)
  76. {
  77. struct eap_sim_data *data;
  78. struct eap_peer_config *config = eap_get_config(sm);
  79. data = os_zalloc(sizeof(*data));
  80. if (data == NULL)
  81. return NULL;
  82. if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
  83. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
  84. "for NONCE_MT");
  85. os_free(data);
  86. return NULL;
  87. }
  88. data->min_num_chal = 2;
  89. if (config && config->phase1) {
  90. char *pos = os_strstr(config->phase1, "sim_min_num_chal=");
  91. if (pos) {
  92. data->min_num_chal = atoi(pos + 17);
  93. if (data->min_num_chal < 2 || data->min_num_chal > 3) {
  94. wpa_printf(MSG_WARNING, "EAP-SIM: Invalid "
  95. "sim_min_num_chal configuration "
  96. "(%lu, expected 2 or 3)",
  97. (unsigned long) data->min_num_chal);
  98. os_free(data);
  99. return NULL;
  100. }
  101. wpa_printf(MSG_DEBUG, "EAP-SIM: Set minimum number of "
  102. "challenges to %lu",
  103. (unsigned long) data->min_num_chal);
  104. }
  105. data->result_ind = os_strstr(config->phase1, "result_ind=1") !=
  106. NULL;
  107. }
  108. eap_sim_state(data, CONTINUE);
  109. return data;
  110. }
  111. static void eap_sim_deinit(struct eap_sm *sm, void *priv)
  112. {
  113. struct eap_sim_data *data = priv;
  114. if (data) {
  115. os_free(data->ver_list);
  116. os_free(data->pseudonym);
  117. os_free(data->reauth_id);
  118. os_free(data->last_eap_identity);
  119. os_free(data);
  120. }
  121. }
  122. static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data)
  123. {
  124. struct eap_peer_config *conf;
  125. wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication algorithm");
  126. conf = eap_get_config(sm);
  127. if (conf == NULL)
  128. return -1;
  129. if (conf->pcsc) {
  130. if (scard_gsm_auth(sm->scard_ctx, data->rand[0],
  131. data->sres[0], data->kc[0]) ||
  132. scard_gsm_auth(sm->scard_ctx, data->rand[1],
  133. data->sres[1], data->kc[1]) ||
  134. (data->num_chal > 2 &&
  135. scard_gsm_auth(sm->scard_ctx, data->rand[2],
  136. data->sres[2], data->kc[2]))) {
  137. wpa_printf(MSG_DEBUG, "EAP-SIM: GSM SIM "
  138. "authentication could not be completed");
  139. return -1;
  140. }
  141. return 0;
  142. }
  143. #ifdef CONFIG_SIM_SIMULATOR
  144. if (conf->password) {
  145. u8 opc[16], k[16];
  146. const char *pos;
  147. size_t i;
  148. wpa_printf(MSG_DEBUG, "EAP-SIM: Use internal GSM-Milenage "
  149. "implementation for authentication");
  150. if (conf->password_len < 65) {
  151. wpa_printf(MSG_DEBUG, "EAP-SIM: invalid GSM-Milenage "
  152. "password");
  153. return -1;
  154. }
  155. pos = (const char *) conf->password;
  156. if (hexstr2bin(pos, k, 16))
  157. return -1;
  158. pos += 32;
  159. if (*pos != ':')
  160. return -1;
  161. pos++;
  162. if (hexstr2bin(pos, opc, 16))
  163. return -1;
  164. for (i = 0; i < data->num_chal; i++) {
  165. if (gsm_milenage(opc, k, data->rand[i],
  166. data->sres[i], data->kc[i])) {
  167. wpa_printf(MSG_DEBUG, "EAP-SIM: "
  168. "GSM-Milenage authentication "
  169. "could not be completed");
  170. return -1;
  171. }
  172. wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND",
  173. data->rand[i], GSM_RAND_LEN);
  174. wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES",
  175. data->sres[i], EAP_SIM_SRES_LEN);
  176. wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc",
  177. data->kc[i], EAP_SIM_KC_LEN);
  178. }
  179. return 0;
  180. }
  181. #endif /* CONFIG_SIM_SIMULATOR */
  182. #ifdef CONFIG_SIM_HARDCODED
  183. /* These hardcoded Kc and SRES values are used for testing. RAND to
  184. * KC/SREC mapping is very bogus as far as real authentication is
  185. * concerned, but it is quite useful for cases where the AS is rotating
  186. * the order of pre-configured values. */
  187. {
  188. size_t i;
  189. wpa_printf(MSG_DEBUG, "EAP-SIM: Use hardcoded Kc and SRES "
  190. "values for testing");
  191. for (i = 0; i < data->num_chal; i++) {
  192. if (data->rand[i][0] == 0xaa) {
  193. os_memcpy(data->kc[i],
  194. "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7",
  195. EAP_SIM_KC_LEN);
  196. os_memcpy(data->sres[i], "\xd1\xd2\xd3\xd4",
  197. EAP_SIM_SRES_LEN);
  198. } else if (data->rand[i][0] == 0xbb) {
  199. os_memcpy(data->kc[i],
  200. "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7",
  201. EAP_SIM_KC_LEN);
  202. os_memcpy(data->sres[i], "\xe1\xe2\xe3\xe4",
  203. EAP_SIM_SRES_LEN);
  204. } else {
  205. os_memcpy(data->kc[i],
  206. "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
  207. EAP_SIM_KC_LEN);
  208. os_memcpy(data->sres[i], "\xf1\xf2\xf3\xf4",
  209. EAP_SIM_SRES_LEN);
  210. }
  211. }
  212. }
  213. return 0;
  214. #else /* CONFIG_SIM_HARDCODED */
  215. wpa_printf(MSG_DEBUG, "EAP-SIM: No GSM authentication algorithm "
  216. "enabled");
  217. return -1;
  218. #endif /* CONFIG_SIM_HARDCODED */
  219. }
  220. static int eap_sim_supported_ver(int version)
  221. {
  222. return version == EAP_SIM_VERSION;
  223. }
  224. #define CLEAR_PSEUDONYM 0x01
  225. #define CLEAR_REAUTH_ID 0x02
  226. #define CLEAR_EAP_ID 0x04
  227. static void eap_sim_clear_identities(struct eap_sim_data *data, int id)
  228. {
  229. wpa_printf(MSG_DEBUG, "EAP-SIM: forgetting old%s%s%s",
  230. id & CLEAR_PSEUDONYM ? " pseudonym" : "",
  231. id & CLEAR_REAUTH_ID ? " reauth_id" : "",
  232. id & CLEAR_EAP_ID ? " eap_id" : "");
  233. if (id & CLEAR_PSEUDONYM) {
  234. os_free(data->pseudonym);
  235. data->pseudonym = NULL;
  236. data->pseudonym_len = 0;
  237. }
  238. if (id & CLEAR_REAUTH_ID) {
  239. os_free(data->reauth_id);
  240. data->reauth_id = NULL;
  241. data->reauth_id_len = 0;
  242. }
  243. if (id & CLEAR_EAP_ID) {
  244. os_free(data->last_eap_identity);
  245. data->last_eap_identity = NULL;
  246. data->last_eap_identity_len = 0;
  247. }
  248. }
  249. static int eap_sim_learn_ids(struct eap_sim_data *data,
  250. struct eap_sim_attrs *attr)
  251. {
  252. if (attr->next_pseudonym) {
  253. os_free(data->pseudonym);
  254. data->pseudonym = os_malloc(attr->next_pseudonym_len);
  255. if (data->pseudonym == NULL) {
  256. wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
  257. "next pseudonym");
  258. return -1;
  259. }
  260. os_memcpy(data->pseudonym, attr->next_pseudonym,
  261. attr->next_pseudonym_len);
  262. data->pseudonym_len = attr->next_pseudonym_len;
  263. wpa_hexdump_ascii(MSG_DEBUG,
  264. "EAP-SIM: (encr) AT_NEXT_PSEUDONYM",
  265. data->pseudonym,
  266. data->pseudonym_len);
  267. }
  268. if (attr->next_reauth_id) {
  269. os_free(data->reauth_id);
  270. data->reauth_id = os_malloc(attr->next_reauth_id_len);
  271. if (data->reauth_id == NULL) {
  272. wpa_printf(MSG_INFO, "EAP-SIM: (encr) No memory for "
  273. "next reauth_id");
  274. return -1;
  275. }
  276. os_memcpy(data->reauth_id, attr->next_reauth_id,
  277. attr->next_reauth_id_len);
  278. data->reauth_id_len = attr->next_reauth_id_len;
  279. wpa_hexdump_ascii(MSG_DEBUG,
  280. "EAP-SIM: (encr) AT_NEXT_REAUTH_ID",
  281. data->reauth_id,
  282. data->reauth_id_len);
  283. }
  284. return 0;
  285. }
  286. static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id,
  287. int err)
  288. {
  289. struct eap_sim_msg *msg;
  290. eap_sim_state(data, FAILURE);
  291. data->num_id_req = 0;
  292. data->num_notification = 0;
  293. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
  294. EAP_SIM_SUBTYPE_CLIENT_ERROR);
  295. eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
  296. return eap_sim_msg_finish(msg, NULL, NULL, 0);
  297. }
  298. static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
  299. struct eap_sim_data *data, u8 id,
  300. enum eap_sim_id_req id_req)
  301. {
  302. const u8 *identity = NULL;
  303. size_t identity_len = 0;
  304. struct eap_sim_msg *msg;
  305. data->reauth = 0;
  306. if (id_req == ANY_ID && data->reauth_id) {
  307. identity = data->reauth_id;
  308. identity_len = data->reauth_id_len;
  309. data->reauth = 1;
  310. } else if ((id_req == ANY_ID || id_req == FULLAUTH_ID) &&
  311. data->pseudonym) {
  312. identity = data->pseudonym;
  313. identity_len = data->pseudonym_len;
  314. eap_sim_clear_identities(data, CLEAR_REAUTH_ID);
  315. } else if (id_req != NO_ID_REQ) {
  316. identity = eap_get_config_identity(sm, &identity_len);
  317. if (identity) {
  318. eap_sim_clear_identities(data, CLEAR_PSEUDONYM |
  319. CLEAR_REAUTH_ID);
  320. }
  321. }
  322. if (id_req != NO_ID_REQ)
  323. eap_sim_clear_identities(data, CLEAR_EAP_ID);
  324. wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", id);
  325. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
  326. EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START);
  327. if (!data->reauth) {
  328. wpa_hexdump(MSG_DEBUG, " AT_NONCE_MT",
  329. data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
  330. eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_MT, 0,
  331. data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
  332. wpa_printf(MSG_DEBUG, " AT_SELECTED_VERSION %d",
  333. data->selected_version);
  334. eap_sim_msg_add(msg, EAP_SIM_AT_SELECTED_VERSION,
  335. data->selected_version, NULL, 0);
  336. }
  337. if (identity) {
  338. wpa_hexdump_ascii(MSG_DEBUG, " AT_IDENTITY",
  339. identity, identity_len);
  340. eap_sim_msg_add(msg, EAP_SIM_AT_IDENTITY, identity_len,
  341. identity, identity_len);
  342. }
  343. return eap_sim_msg_finish(msg, NULL, NULL, 0);
  344. }
  345. static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data,
  346. u8 id)
  347. {
  348. struct eap_sim_msg *msg;
  349. wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", id);
  350. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
  351. EAP_SIM_SUBTYPE_CHALLENGE);
  352. if (data->use_result_ind) {
  353. wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
  354. eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
  355. }
  356. wpa_printf(MSG_DEBUG, " AT_MAC");
  357. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  358. return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres,
  359. data->num_chal * EAP_SIM_SRES_LEN);
  360. }
  361. static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data,
  362. u8 id, int counter_too_small)
  363. {
  364. struct eap_sim_msg *msg;
  365. unsigned int counter;
  366. wpa_printf(MSG_DEBUG, "Generating EAP-SIM Reauthentication (id=%d)",
  367. id);
  368. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
  369. EAP_SIM_SUBTYPE_REAUTHENTICATION);
  370. wpa_printf(MSG_DEBUG, " AT_IV");
  371. wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
  372. eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
  373. if (counter_too_small) {
  374. wpa_printf(MSG_DEBUG, " *AT_COUNTER_TOO_SMALL");
  375. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER_TOO_SMALL, 0, NULL, 0);
  376. counter = data->counter_too_small;
  377. } else
  378. counter = data->counter;
  379. wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", counter);
  380. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
  381. if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
  382. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
  383. "AT_ENCR_DATA");
  384. eap_sim_msg_free(msg);
  385. return NULL;
  386. }
  387. if (data->use_result_ind) {
  388. wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
  389. eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
  390. }
  391. wpa_printf(MSG_DEBUG, " AT_MAC");
  392. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  393. return eap_sim_msg_finish(msg, data->k_aut, data->nonce_s,
  394. EAP_SIM_NONCE_S_LEN);
  395. }
  396. static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data,
  397. u8 id, u16 notification)
  398. {
  399. struct eap_sim_msg *msg;
  400. u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
  401. wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id);
  402. msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
  403. EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION);
  404. if (k_aut && data->reauth) {
  405. wpa_printf(MSG_DEBUG, " AT_IV");
  406. wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
  407. eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
  408. EAP_SIM_AT_ENCR_DATA);
  409. wpa_printf(MSG_DEBUG, " *AT_COUNTER %d", data->counter);
  410. eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
  411. NULL, 0);
  412. if (eap_sim_msg_add_encr_end(msg, data->k_encr,
  413. EAP_SIM_AT_PADDING)) {
  414. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
  415. "AT_ENCR_DATA");
  416. eap_sim_msg_free(msg);
  417. return NULL;
  418. }
  419. }
  420. if (k_aut) {
  421. wpa_printf(MSG_DEBUG, " AT_MAC");
  422. eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
  423. }
  424. return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
  425. }
  426. static struct wpabuf * eap_sim_process_start(struct eap_sm *sm,
  427. struct eap_sim_data *data, u8 id,
  428. struct eap_sim_attrs *attr)
  429. {
  430. int selected_version = -1, id_error;
  431. size_t i;
  432. u8 *pos;
  433. wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Start");
  434. if (attr->version_list == NULL) {
  435. wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in "
  436. "SIM/Start");
  437. return eap_sim_client_error(data, id,
  438. EAP_SIM_UNSUPPORTED_VERSION);
  439. }
  440. os_free(data->ver_list);
  441. data->ver_list = os_malloc(attr->version_list_len);
  442. if (data->ver_list == NULL) {
  443. wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate "
  444. "memory for version list");
  445. return eap_sim_client_error(data, id,
  446. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  447. }
  448. os_memcpy(data->ver_list, attr->version_list, attr->version_list_len);
  449. data->ver_list_len = attr->version_list_len;
  450. pos = data->ver_list;
  451. for (i = 0; i < data->ver_list_len / 2; i++) {
  452. int ver = pos[0] * 256 + pos[1];
  453. pos += 2;
  454. if (eap_sim_supported_ver(ver)) {
  455. selected_version = ver;
  456. break;
  457. }
  458. }
  459. if (selected_version < 0) {
  460. wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported "
  461. "version");
  462. return eap_sim_client_error(data, id,
  463. EAP_SIM_UNSUPPORTED_VERSION);
  464. }
  465. wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d",
  466. selected_version);
  467. data->selected_version = selected_version;
  468. id_error = 0;
  469. switch (attr->id_req) {
  470. case NO_ID_REQ:
  471. break;
  472. case ANY_ID:
  473. if (data->num_id_req > 0)
  474. id_error++;
  475. data->num_id_req++;
  476. break;
  477. case FULLAUTH_ID:
  478. if (data->num_id_req > 1)
  479. id_error++;
  480. data->num_id_req++;
  481. break;
  482. case PERMANENT_ID:
  483. if (data->num_id_req > 2)
  484. id_error++;
  485. data->num_id_req++;
  486. break;
  487. }
  488. if (id_error) {
  489. wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests "
  490. "used within one authentication");
  491. return eap_sim_client_error(data, id,
  492. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  493. }
  494. return eap_sim_response_start(sm, data, id, attr->id_req);
  495. }
  496. static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
  497. struct eap_sim_data *data,
  498. u8 id,
  499. const struct wpabuf *reqData,
  500. struct eap_sim_attrs *attr)
  501. {
  502. const u8 *identity;
  503. size_t identity_len;
  504. struct eap_sim_attrs eattr;
  505. wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge");
  506. data->reauth = 0;
  507. if (!attr->mac || !attr->rand) {
  508. wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
  509. "did not include%s%s",
  510. !attr->mac ? " AT_MAC" : "",
  511. !attr->rand ? " AT_RAND" : "");
  512. return eap_sim_client_error(data, id,
  513. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  514. }
  515. wpa_printf(MSG_DEBUG, "EAP-SIM: %lu challenges",
  516. (unsigned long) attr->num_chal);
  517. if (attr->num_chal < data->min_num_chal) {
  518. wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of "
  519. "challenges (%lu)", (unsigned long) attr->num_chal);
  520. return eap_sim_client_error(data, id,
  521. EAP_SIM_INSUFFICIENT_NUM_OF_CHAL);
  522. }
  523. if (attr->num_chal > 3) {
  524. wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges "
  525. "(%lu)", (unsigned long) attr->num_chal);
  526. return eap_sim_client_error(data, id,
  527. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  528. }
  529. /* Verify that RANDs are different */
  530. if (os_memcmp(attr->rand, attr->rand + GSM_RAND_LEN,
  531. GSM_RAND_LEN) == 0 ||
  532. (attr->num_chal > 2 &&
  533. (os_memcmp(attr->rand, attr->rand + 2 * GSM_RAND_LEN,
  534. GSM_RAND_LEN) == 0 ||
  535. os_memcmp(attr->rand + GSM_RAND_LEN,
  536. attr->rand + 2 * GSM_RAND_LEN,
  537. GSM_RAND_LEN) == 0))) {
  538. wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times");
  539. return eap_sim_client_error(data, id,
  540. EAP_SIM_RAND_NOT_FRESH);
  541. }
  542. os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN);
  543. data->num_chal = attr->num_chal;
  544. if (eap_sim_gsm_auth(sm, data)) {
  545. wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed");
  546. return eap_sim_client_error(data, id,
  547. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  548. }
  549. if (data->last_eap_identity) {
  550. identity = data->last_eap_identity;
  551. identity_len = data->last_eap_identity_len;
  552. } else if (data->pseudonym) {
  553. identity = data->pseudonym;
  554. identity_len = data->pseudonym_len;
  555. } else
  556. identity = eap_get_config_identity(sm, &identity_len);
  557. wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Selected identity for MK "
  558. "derivation", identity, identity_len);
  559. eap_sim_derive_mk(identity, identity_len, data->nonce_mt,
  560. data->selected_version, data->ver_list,
  561. data->ver_list_len, data->num_chal,
  562. (const u8 *) data->kc, data->mk);
  563. eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
  564. data->emsk);
  565. if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt,
  566. EAP_SIM_NONCE_MT_LEN)) {
  567. wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
  568. "used invalid AT_MAC");
  569. return eap_sim_client_error(data, id,
  570. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  571. }
  572. /* Old reauthentication and pseudonym identities must not be used
  573. * anymore. In other words, if no new identities are received, full
  574. * authentication will be used on next reauthentication. */
  575. eap_sim_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID |
  576. CLEAR_EAP_ID);
  577. if (attr->encr_data) {
  578. u8 *decrypted;
  579. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  580. attr->encr_data_len, attr->iv,
  581. &eattr, 0);
  582. if (decrypted == NULL) {
  583. return eap_sim_client_error(
  584. data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  585. }
  586. eap_sim_learn_ids(data, &eattr);
  587. os_free(decrypted);
  588. }
  589. if (data->result_ind && attr->result_ind)
  590. data->use_result_ind = 1;
  591. if (data->state != FAILURE && data->state != RESULT_FAILURE) {
  592. eap_sim_state(data, data->use_result_ind ?
  593. RESULT_SUCCESS : SUCCESS);
  594. }
  595. data->num_id_req = 0;
  596. data->num_notification = 0;
  597. /* RFC 4186 specifies that counter is initialized to one after
  598. * fullauth, but initializing it to zero makes it easier to implement
  599. * reauth verification. */
  600. data->counter = 0;
  601. return eap_sim_response_challenge(data, id);
  602. }
  603. static int eap_sim_process_notification_reauth(struct eap_sim_data *data,
  604. struct eap_sim_attrs *attr)
  605. {
  606. struct eap_sim_attrs eattr;
  607. u8 *decrypted;
  608. if (attr->encr_data == NULL || attr->iv == NULL) {
  609. wpa_printf(MSG_WARNING, "EAP-SIM: Notification message after "
  610. "reauth did not include encrypted data");
  611. return -1;
  612. }
  613. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  614. attr->encr_data_len, attr->iv, &eattr,
  615. 0);
  616. if (decrypted == NULL) {
  617. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
  618. "data from notification message");
  619. return -1;
  620. }
  621. if (eattr.counter < 0 || (size_t) eattr.counter != data->counter) {
  622. wpa_printf(MSG_WARNING, "EAP-SIM: Counter in notification "
  623. "message does not match with counter in reauth "
  624. "message");
  625. os_free(decrypted);
  626. return -1;
  627. }
  628. os_free(decrypted);
  629. return 0;
  630. }
  631. static int eap_sim_process_notification_auth(struct eap_sim_data *data,
  632. const struct wpabuf *reqData,
  633. struct eap_sim_attrs *attr)
  634. {
  635. if (attr->mac == NULL) {
  636. wpa_printf(MSG_INFO, "EAP-SIM: no AT_MAC in after_auth "
  637. "Notification message");
  638. return -1;
  639. }
  640. if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
  641. {
  642. wpa_printf(MSG_WARNING, "EAP-SIM: Notification message "
  643. "used invalid AT_MAC");
  644. return -1;
  645. }
  646. if (data->reauth &&
  647. eap_sim_process_notification_reauth(data, attr)) {
  648. wpa_printf(MSG_WARNING, "EAP-SIM: Invalid notification "
  649. "message after reauth");
  650. return -1;
  651. }
  652. return 0;
  653. }
  654. static struct wpabuf * eap_sim_process_notification(
  655. struct eap_sm *sm, struct eap_sim_data *data, u8 id,
  656. const struct wpabuf *reqData, struct eap_sim_attrs *attr)
  657. {
  658. wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Notification");
  659. if (data->num_notification > 0) {
  660. wpa_printf(MSG_INFO, "EAP-SIM: too many notification "
  661. "rounds (only one allowed)");
  662. return eap_sim_client_error(data, id,
  663. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  664. }
  665. data->num_notification++;
  666. if (attr->notification == -1) {
  667. wpa_printf(MSG_INFO, "EAP-SIM: no AT_NOTIFICATION in "
  668. "Notification message");
  669. return eap_sim_client_error(data, id,
  670. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  671. }
  672. if ((attr->notification & 0x4000) == 0 &&
  673. eap_sim_process_notification_auth(data, reqData, attr)) {
  674. return eap_sim_client_error(data, id,
  675. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  676. }
  677. eap_sim_report_notification(sm->msg_ctx, attr->notification, 0);
  678. if (attr->notification >= 0 && attr->notification < 32768) {
  679. eap_sim_state(data, FAILURE);
  680. } else if (attr->notification == EAP_SIM_SUCCESS &&
  681. data->state == RESULT_SUCCESS)
  682. eap_sim_state(data, SUCCESS);
  683. return eap_sim_response_notification(data, id, attr->notification);
  684. }
  685. static struct wpabuf * eap_sim_process_reauthentication(
  686. struct eap_sm *sm, struct eap_sim_data *data, u8 id,
  687. const struct wpabuf *reqData, struct eap_sim_attrs *attr)
  688. {
  689. struct eap_sim_attrs eattr;
  690. u8 *decrypted;
  691. wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication");
  692. if (data->reauth_id == NULL) {
  693. wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying "
  694. "reauthentication, but no reauth_id available");
  695. return eap_sim_client_error(data, id,
  696. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  697. }
  698. data->reauth = 1;
  699. if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
  700. {
  701. wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
  702. "did not have valid AT_MAC");
  703. return eap_sim_client_error(data, id,
  704. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  705. }
  706. if (attr->encr_data == NULL || attr->iv == NULL) {
  707. wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
  708. "message did not include encrypted data");
  709. return eap_sim_client_error(data, id,
  710. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  711. }
  712. decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
  713. attr->encr_data_len, attr->iv, &eattr,
  714. 0);
  715. if (decrypted == NULL) {
  716. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
  717. "data from reauthentication message");
  718. return eap_sim_client_error(data, id,
  719. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  720. }
  721. if (eattr.nonce_s == NULL || eattr.counter < 0) {
  722. wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet",
  723. !eattr.nonce_s ? " AT_NONCE_S" : "",
  724. eattr.counter < 0 ? " AT_COUNTER" : "");
  725. os_free(decrypted);
  726. return eap_sim_client_error(data, id,
  727. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  728. }
  729. if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
  730. wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid counter "
  731. "(%d <= %d)", eattr.counter, data->counter);
  732. data->counter_too_small = eattr.counter;
  733. /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
  734. * reauth_id must not be used to start a new reauthentication.
  735. * However, since it was used in the last EAP-Response-Identity
  736. * packet, it has to saved for the following fullauth to be
  737. * used in MK derivation. */
  738. os_free(data->last_eap_identity);
  739. data->last_eap_identity = data->reauth_id;
  740. data->last_eap_identity_len = data->reauth_id_len;
  741. data->reauth_id = NULL;
  742. data->reauth_id_len = 0;
  743. os_free(decrypted);
  744. return eap_sim_response_reauth(data, id, 1);
  745. }
  746. data->counter = eattr.counter;
  747. os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN);
  748. wpa_hexdump(MSG_DEBUG, "EAP-SIM: (encr) AT_NONCE_S",
  749. data->nonce_s, EAP_SIM_NONCE_S_LEN);
  750. eap_sim_derive_keys_reauth(data->counter,
  751. data->reauth_id, data->reauth_id_len,
  752. data->nonce_s, data->mk, data->msk,
  753. data->emsk);
  754. eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
  755. eap_sim_learn_ids(data, &eattr);
  756. if (data->result_ind && attr->result_ind)
  757. data->use_result_ind = 1;
  758. if (data->state != FAILURE && data->state != RESULT_FAILURE) {
  759. eap_sim_state(data, data->use_result_ind ?
  760. RESULT_SUCCESS : SUCCESS);
  761. }
  762. data->num_id_req = 0;
  763. data->num_notification = 0;
  764. if (data->counter > EAP_SIM_MAX_FAST_REAUTHS) {
  765. wpa_printf(MSG_DEBUG, "EAP-SIM: Maximum number of "
  766. "fast reauths performed - force fullauth");
  767. eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
  768. }
  769. os_free(decrypted);
  770. return eap_sim_response_reauth(data, id, 0);
  771. }
  772. static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv,
  773. struct eap_method_ret *ret,
  774. const struct wpabuf *reqData)
  775. {
  776. struct eap_sim_data *data = priv;
  777. const struct eap_hdr *req;
  778. u8 subtype, id;
  779. struct wpabuf *res;
  780. const u8 *pos;
  781. struct eap_sim_attrs attr;
  782. size_t len;
  783. wpa_hexdump_buf(MSG_DEBUG, "EAP-SIM: EAP data", reqData);
  784. if (eap_get_config_identity(sm, &len) == NULL) {
  785. wpa_printf(MSG_INFO, "EAP-SIM: Identity not configured");
  786. eap_sm_request_identity(sm);
  787. ret->ignore = TRUE;
  788. return NULL;
  789. }
  790. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len);
  791. if (pos == NULL || len < 1) {
  792. ret->ignore = TRUE;
  793. return NULL;
  794. }
  795. req = wpabuf_head(reqData);
  796. id = req->identifier;
  797. len = be_to_host16(req->length);
  798. ret->ignore = FALSE;
  799. ret->methodState = METHOD_MAY_CONT;
  800. ret->decision = DECISION_FAIL;
  801. ret->allowNotifications = TRUE;
  802. subtype = *pos++;
  803. wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype);
  804. pos += 2; /* Reserved */
  805. if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 0,
  806. 0)) {
  807. res = eap_sim_client_error(data, id,
  808. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  809. goto done;
  810. }
  811. switch (subtype) {
  812. case EAP_SIM_SUBTYPE_START:
  813. res = eap_sim_process_start(sm, data, id, &attr);
  814. break;
  815. case EAP_SIM_SUBTYPE_CHALLENGE:
  816. res = eap_sim_process_challenge(sm, data, id, reqData, &attr);
  817. break;
  818. case EAP_SIM_SUBTYPE_NOTIFICATION:
  819. res = eap_sim_process_notification(sm, data, id, reqData,
  820. &attr);
  821. break;
  822. case EAP_SIM_SUBTYPE_REAUTHENTICATION:
  823. res = eap_sim_process_reauthentication(sm, data, id, reqData,
  824. &attr);
  825. break;
  826. case EAP_SIM_SUBTYPE_CLIENT_ERROR:
  827. wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Client-Error");
  828. res = eap_sim_client_error(data, id,
  829. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  830. break;
  831. default:
  832. wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown subtype=%d", subtype);
  833. res = eap_sim_client_error(data, id,
  834. EAP_SIM_UNABLE_TO_PROCESS_PACKET);
  835. break;
  836. }
  837. done:
  838. if (data->state == FAILURE) {
  839. ret->decision = DECISION_FAIL;
  840. ret->methodState = METHOD_DONE;
  841. } else if (data->state == SUCCESS) {
  842. ret->decision = data->use_result_ind ?
  843. DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
  844. ret->methodState = data->use_result_ind ?
  845. METHOD_DONE : METHOD_MAY_CONT;
  846. } else if (data->state == RESULT_FAILURE)
  847. ret->methodState = METHOD_CONT;
  848. else if (data->state == RESULT_SUCCESS)
  849. ret->methodState = METHOD_CONT;
  850. if (ret->methodState == METHOD_DONE) {
  851. ret->allowNotifications = FALSE;
  852. }
  853. return res;
  854. }
  855. static Boolean eap_sim_has_reauth_data(struct eap_sm *sm, void *priv)
  856. {
  857. struct eap_sim_data *data = priv;
  858. return data->pseudonym || data->reauth_id;
  859. }
  860. static void eap_sim_deinit_for_reauth(struct eap_sm *sm, void *priv)
  861. {
  862. struct eap_sim_data *data = priv;
  863. eap_sim_clear_identities(data, CLEAR_EAP_ID);
  864. data->use_result_ind = 0;
  865. }
  866. static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv)
  867. {
  868. struct eap_sim_data *data = priv;
  869. if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
  870. wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
  871. "for NONCE_MT");
  872. os_free(data);
  873. return NULL;
  874. }
  875. data->num_id_req = 0;
  876. data->num_notification = 0;
  877. eap_sim_state(data, CONTINUE);
  878. return priv;
  879. }
  880. static const u8 * eap_sim_get_identity(struct eap_sm *sm, void *priv,
  881. size_t *len)
  882. {
  883. struct eap_sim_data *data = priv;
  884. if (data->reauth_id) {
  885. *len = data->reauth_id_len;
  886. return data->reauth_id;
  887. }
  888. if (data->pseudonym) {
  889. *len = data->pseudonym_len;
  890. return data->pseudonym;
  891. }
  892. return NULL;
  893. }
  894. static Boolean eap_sim_isKeyAvailable(struct eap_sm *sm, void *priv)
  895. {
  896. struct eap_sim_data *data = priv;
  897. return data->state == SUCCESS;
  898. }
  899. static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len)
  900. {
  901. struct eap_sim_data *data = priv;
  902. u8 *key;
  903. if (data->state != SUCCESS)
  904. return NULL;
  905. key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
  906. if (key == NULL)
  907. return NULL;
  908. *len = EAP_SIM_KEYING_DATA_LEN;
  909. os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
  910. return key;
  911. }
  912. static u8 * eap_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
  913. {
  914. struct eap_sim_data *data = priv;
  915. u8 *key;
  916. if (data->state != SUCCESS)
  917. return NULL;
  918. key = os_malloc(EAP_EMSK_LEN);
  919. if (key == NULL)
  920. return NULL;
  921. *len = EAP_EMSK_LEN;
  922. os_memcpy(key, data->emsk, EAP_EMSK_LEN);
  923. return key;
  924. }
  925. int eap_peer_sim_register(void)
  926. {
  927. struct eap_method *eap;
  928. int ret;
  929. eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
  930. EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM");
  931. if (eap == NULL)
  932. return -1;
  933. eap->init = eap_sim_init;
  934. eap->deinit = eap_sim_deinit;
  935. eap->process = eap_sim_process;
  936. eap->isKeyAvailable = eap_sim_isKeyAvailable;
  937. eap->getKey = eap_sim_getKey;
  938. eap->has_reauth_data = eap_sim_has_reauth_data;
  939. eap->deinit_for_reauth = eap_sim_deinit_for_reauth;
  940. eap->init_for_reauth = eap_sim_init_for_reauth;
  941. eap->get_identity = eap_sim_get_identity;
  942. eap->get_emsk = eap_sim_get_emsk;
  943. ret = eap_peer_method_register(eap);
  944. if (ret)
  945. eap_peer_method_free(eap);
  946. return ret;
  947. }