eap_sim.c 30 KB

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