2
* hostapd / EAP-SIM (RFC 4186)
3
* Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
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.
9
* Alternatively, this software may be distributed under the terms of BSD
12
* See README and COPYING for more details.
18
#include "eap_server/eap_i.h"
19
#include "eap_common/eap_sim_common.h"
20
#include "eap_server/eap_sim_db.h"
24
u8 mk[EAP_SIM_MK_LEN];
25
u8 nonce_mt[EAP_SIM_NONCE_MT_LEN];
26
u8 nonce_s[EAP_SIM_NONCE_S_LEN];
27
u8 k_aut[EAP_SIM_K_AUT_LEN];
28
u8 k_encr[EAP_SIM_K_ENCR_LEN];
29
u8 msk[EAP_SIM_KEYING_DATA_LEN];
30
u8 emsk[EAP_EMSK_LEN];
31
u8 kc[EAP_SIM_MAX_CHAL][EAP_SIM_KC_LEN];
32
u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN];
33
u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN];
36
START, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE
41
struct eap_sim_reauth *reauth;
47
static const char * eap_sim_state_txt(int state)
61
return "NOTIFICATION";
68
static void eap_sim_state(struct eap_sim_data *data, int state)
70
wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s",
71
eap_sim_state_txt(data->state),
72
eap_sim_state_txt(state));
77
static void * eap_sim_init(struct eap_sm *sm)
79
struct eap_sim_data *data;
81
if (sm->eap_sim_db_priv == NULL) {
82
wpa_printf(MSG_WARNING, "EAP-SIM: eap_sim_db not configured");
86
data = os_zalloc(sizeof(*data));
95
static void eap_sim_reset(struct eap_sm *sm, void *priv)
97
struct eap_sim_data *data = priv;
98
os_free(data->next_pseudonym);
99
os_free(data->next_reauth_id);
104
static struct wpabuf * eap_sim_build_start(struct eap_sm *sm,
105
struct eap_sim_data *data, u8 id)
107
struct eap_sim_msg *msg;
110
wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Start");
111
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
112
EAP_SIM_SUBTYPE_START);
113
if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity,
115
wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
116
eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
119
* RFC 4186, Chap. 4.2.4 recommends that identity from EAP is
120
* ignored and the SIM/Start is used to request the identity.
122
wpa_printf(MSG_DEBUG, " AT_ANY_ID_REQ");
123
eap_sim_msg_add(msg, EAP_SIM_AT_ANY_ID_REQ, 0, NULL, 0);
125
wpa_printf(MSG_DEBUG, " AT_VERSION_LIST");
127
ver[1] = EAP_SIM_VERSION;
128
eap_sim_msg_add(msg, EAP_SIM_AT_VERSION_LIST, sizeof(ver),
130
return eap_sim_msg_finish(msg, NULL, NULL, 0);
134
static int eap_sim_build_encr(struct eap_sm *sm, struct eap_sim_data *data,
135
struct eap_sim_msg *msg, u16 counter,
138
os_free(data->next_pseudonym);
139
data->next_pseudonym =
140
eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0);
141
os_free(data->next_reauth_id);
142
if (data->counter <= EAP_SIM_MAX_FAST_REAUTHS) {
143
data->next_reauth_id =
144
eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 0);
146
wpa_printf(MSG_DEBUG, "EAP-SIM: Max fast re-authentication "
147
"count exceeded - force full authentication");
148
data->next_reauth_id = NULL;
151
if (data->next_pseudonym == NULL && data->next_reauth_id == NULL &&
152
counter == 0 && nonce_s == NULL)
155
wpa_printf(MSG_DEBUG, " AT_IV");
156
wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
157
eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV, EAP_SIM_AT_ENCR_DATA);
160
wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)", counter);
161
eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, counter, NULL, 0);
165
wpa_printf(MSG_DEBUG, " *AT_NONCE_S");
166
eap_sim_msg_add(msg, EAP_SIM_AT_NONCE_S, 0, nonce_s,
167
EAP_SIM_NONCE_S_LEN);
170
if (data->next_pseudonym) {
171
wpa_printf(MSG_DEBUG, " *AT_NEXT_PSEUDONYM (%s)",
172
data->next_pseudonym);
173
eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_PSEUDONYM,
174
os_strlen(data->next_pseudonym),
175
(u8 *) data->next_pseudonym,
176
os_strlen(data->next_pseudonym));
179
if (data->next_reauth_id) {
180
wpa_printf(MSG_DEBUG, " *AT_NEXT_REAUTH_ID (%s)",
181
data->next_reauth_id);
182
eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_REAUTH_ID,
183
os_strlen(data->next_reauth_id),
184
(u8 *) data->next_reauth_id,
185
os_strlen(data->next_reauth_id));
188
if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
189
wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
198
static struct wpabuf * eap_sim_build_challenge(struct eap_sm *sm,
199
struct eap_sim_data *data,
202
struct eap_sim_msg *msg;
204
wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Challenge");
205
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
206
EAP_SIM_SUBTYPE_CHALLENGE);
207
wpa_printf(MSG_DEBUG, " AT_RAND");
208
eap_sim_msg_add(msg, EAP_SIM_AT_RAND, 0, (u8 *) data->rand,
209
data->num_chal * GSM_RAND_LEN);
211
if (eap_sim_build_encr(sm, data, msg, 0, NULL)) {
212
eap_sim_msg_free(msg);
216
if (sm->eap_sim_aka_result_ind) {
217
wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
218
eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
221
wpa_printf(MSG_DEBUG, " AT_MAC");
222
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
223
return eap_sim_msg_finish(msg, data->k_aut, data->nonce_mt,
224
EAP_SIM_NONCE_MT_LEN);
228
static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm,
229
struct eap_sim_data *data, u8 id)
231
struct eap_sim_msg *msg;
233
wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Re-authentication");
235
if (os_get_random(data->nonce_s, EAP_SIM_NONCE_S_LEN))
237
wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: NONCE_S",
238
data->nonce_s, EAP_SIM_NONCE_S_LEN);
240
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
242
eap_sim_derive_keys_reauth(data->counter, sm->identity,
243
sm->identity_len, data->nonce_s, data->mk,
244
data->msk, data->emsk);
246
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
247
EAP_SIM_SUBTYPE_REAUTHENTICATION);
249
if (eap_sim_build_encr(sm, data, msg, data->counter, data->nonce_s)) {
250
eap_sim_msg_free(msg);
254
if (sm->eap_sim_aka_result_ind) {
255
wpa_printf(MSG_DEBUG, " AT_RESULT_IND");
256
eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
259
wpa_printf(MSG_DEBUG, " AT_MAC");
260
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
261
return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
265
static struct wpabuf * eap_sim_build_notification(struct eap_sm *sm,
266
struct eap_sim_data *data,
269
struct eap_sim_msg *msg;
271
wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Notification");
272
msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
273
EAP_SIM_SUBTYPE_NOTIFICATION);
274
wpa_printf(MSG_DEBUG, " AT_NOTIFICATION (%d)", data->notification);
275
eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification,
277
if (data->use_result_ind) {
279
wpa_printf(MSG_DEBUG, " AT_IV");
280
wpa_printf(MSG_DEBUG, " AT_ENCR_DATA");
281
eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
282
EAP_SIM_AT_ENCR_DATA);
283
wpa_printf(MSG_DEBUG, " *AT_COUNTER (%u)",
285
eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter,
288
if (eap_sim_msg_add_encr_end(msg, data->k_encr,
289
EAP_SIM_AT_PADDING)) {
290
wpa_printf(MSG_WARNING, "EAP-SIM: Failed to "
291
"encrypt AT_ENCR_DATA");
292
eap_sim_msg_free(msg);
297
wpa_printf(MSG_DEBUG, " AT_MAC");
298
eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
300
return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
304
static struct wpabuf * eap_sim_buildReq(struct eap_sm *sm, void *priv, u8 id)
306
struct eap_sim_data *data = priv;
308
switch (data->state) {
310
return eap_sim_build_start(sm, data, id);
312
return eap_sim_build_challenge(sm, data, id);
314
return eap_sim_build_reauth(sm, data, id);
316
return eap_sim_build_notification(sm, data, id);
318
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "
319
"buildReq", data->state);
326
static Boolean eap_sim_check(struct eap_sm *sm, void *priv,
327
struct wpabuf *respData)
329
struct eap_sim_data *data = priv;
334
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, respData, &len);
335
if (pos == NULL || len < 3) {
336
wpa_printf(MSG_INFO, "EAP-SIM: Invalid frame");
341
if (subtype == EAP_SIM_SUBTYPE_CLIENT_ERROR)
344
switch (data->state) {
346
if (subtype != EAP_SIM_SUBTYPE_START) {
347
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
348
"subtype %d", subtype);
353
if (subtype != EAP_SIM_SUBTYPE_CHALLENGE) {
354
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
355
"subtype %d", subtype);
360
if (subtype != EAP_SIM_SUBTYPE_REAUTHENTICATION) {
361
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
362
"subtype %d", subtype);
367
if (subtype != EAP_SIM_SUBTYPE_NOTIFICATION) {
368
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
369
"subtype %d", subtype);
374
wpa_printf(MSG_INFO, "EAP-SIM: Unexpected state (%d) for "
375
"processing a response", data->state);
383
static int eap_sim_supported_ver(struct eap_sim_data *data, int version)
385
return version == EAP_SIM_VERSION;
389
static void eap_sim_process_start(struct eap_sm *sm,
390
struct eap_sim_data *data,
391
struct wpabuf *respData,
392
struct eap_sim_attrs *attr)
398
wpa_printf(MSG_DEBUG, "EAP-SIM: Receive start response");
400
if (attr->identity) {
401
os_free(sm->identity);
402
sm->identity = os_malloc(attr->identity_len);
404
os_memcpy(sm->identity, attr->identity,
406
sm->identity_len = attr->identity_len;
413
if (sm->identity && sm->identity_len > 0 &&
414
sm->identity[0] == EAP_SIM_PERMANENT_PREFIX) {
415
identity = sm->identity;
416
identity_len = sm->identity_len;
418
identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv,
422
if (identity == NULL) {
423
data->reauth = eap_sim_db_get_reauth_entry(
424
sm->eap_sim_db_priv, sm->identity,
427
wpa_printf(MSG_DEBUG, "EAP-SIM: Using fast "
428
"re-authentication");
429
identity = data->reauth->identity;
430
identity_len = data->reauth->identity_len;
431
data->counter = data->reauth->counter;
432
os_memcpy(data->mk, data->reauth->mk,
438
if (identity == NULL) {
439
wpa_printf(MSG_DEBUG, "EAP-SIM: Could not get proper permanent"
441
eap_sim_state(data, FAILURE);
445
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity",
446
identity, identity_len);
449
eap_sim_state(data, REAUTH);
453
if (attr->nonce_mt == NULL || attr->selected_version < 0) {
454
wpa_printf(MSG_DEBUG, "EAP-SIM: Start/Response missing "
455
"required attributes");
456
eap_sim_state(data, FAILURE);
460
if (!eap_sim_supported_ver(data, attr->selected_version)) {
461
wpa_printf(MSG_DEBUG, "EAP-SIM: Peer selected unsupported "
462
"version %d", attr->selected_version);
463
eap_sim_state(data, FAILURE);
467
data->counter = 0; /* reset re-auth counter since this is full auth */
470
data->num_chal = eap_sim_db_get_gsm_triplets(
471
sm->eap_sim_db_priv, identity, identity_len,
473
(u8 *) data->rand, (u8 *) data->kc, (u8 *) data->sres, sm);
474
if (data->num_chal == EAP_SIM_DB_PENDING) {
475
wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication triplets "
476
"not yet available - pending request");
477
sm->method_pending = METHOD_PENDING_WAIT;
480
if (data->num_chal < 2) {
481
wpa_printf(MSG_INFO, "EAP-SIM: Failed to get GSM "
482
"authentication triplets for the peer");
483
eap_sim_state(data, FAILURE);
487
identity_len = sm->identity_len;
488
while (identity_len > 0 && sm->identity[identity_len - 1] == '\0') {
489
wpa_printf(MSG_DEBUG, "EAP-SIM: Workaround - drop last null "
490
"character from identity");
493
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity for MK derivation",
494
sm->identity, identity_len);
496
os_memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);
497
WPA_PUT_BE16(ver_list, EAP_SIM_VERSION);
498
eap_sim_derive_mk(sm->identity, identity_len, attr->nonce_mt,
499
attr->selected_version, ver_list, sizeof(ver_list),
500
data->num_chal, (const u8 *) data->kc, data->mk);
501
eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
504
eap_sim_state(data, CHALLENGE);
508
static void eap_sim_process_challenge(struct eap_sm *sm,
509
struct eap_sim_data *data,
510
struct wpabuf *respData,
511
struct eap_sim_attrs *attr)
516
if (attr->mac == NULL ||
517
eap_sim_verify_mac(data->k_aut, respData, attr->mac,
519
data->num_chal * EAP_SIM_SRES_LEN)) {
520
wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
521
"did not include valid AT_MAC");
522
eap_sim_state(data, FAILURE);
526
wpa_printf(MSG_DEBUG, "EAP-SIM: Challenge response includes the "
528
if (sm->eap_sim_aka_result_ind && attr->result_ind) {
529
data->use_result_ind = 1;
530
data->notification = EAP_SIM_SUCCESS;
531
eap_sim_state(data, NOTIFICATION);
533
eap_sim_state(data, SUCCESS);
535
identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,
536
sm->identity_len, &identity_len);
537
if (identity == NULL) {
538
identity = sm->identity;
539
identity_len = sm->identity_len;
542
if (data->next_pseudonym) {
543
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
545
data->next_pseudonym);
546
data->next_pseudonym = NULL;
548
if (data->next_reauth_id) {
549
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
551
data->next_reauth_id, data->counter + 1,
553
data->next_reauth_id = NULL;
558
static void eap_sim_process_reauth(struct eap_sm *sm,
559
struct eap_sim_data *data,
560
struct wpabuf *respData,
561
struct eap_sim_attrs *attr)
563
struct eap_sim_attrs eattr;
564
u8 *decrypted = NULL;
565
const u8 *identity, *id2;
566
size_t identity_len, id2_len;
568
if (attr->mac == NULL ||
569
eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
570
EAP_SIM_NONCE_S_LEN)) {
571
wpa_printf(MSG_WARNING, "EAP-SIM: Re-authentication message "
572
"did not include valid AT_MAC");
576
if (attr->encr_data == NULL || attr->iv == NULL) {
577
wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
578
"message did not include encrypted data");
582
decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data,
583
attr->encr_data_len, attr->iv, &eattr,
585
if (decrypted == NULL) {
586
wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
587
"data from reauthentication message");
591
if (eattr.counter != data->counter) {
592
wpa_printf(MSG_WARNING, "EAP-SIM: Re-authentication message "
593
"used incorrect counter %u, expected %u",
594
eattr.counter, data->counter);
600
wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes "
601
"the correct AT_MAC");
602
if (sm->eap_sim_aka_result_ind && attr->result_ind) {
603
data->use_result_ind = 1;
604
data->notification = EAP_SIM_SUCCESS;
605
eap_sim_state(data, NOTIFICATION);
607
eap_sim_state(data, SUCCESS);
610
identity = data->reauth->identity;
611
identity_len = data->reauth->identity_len;
613
identity = sm->identity;
614
identity_len = sm->identity_len;
617
id2 = eap_sim_db_get_permanent(sm->eap_sim_db_priv, identity,
618
identity_len, &id2_len);
621
identity_len = id2_len;
624
if (data->next_pseudonym) {
625
eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
626
identity_len, data->next_pseudonym);
627
data->next_pseudonym = NULL;
629
if (data->next_reauth_id) {
630
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
631
identity_len, data->next_reauth_id,
632
data->counter + 1, data->mk);
633
data->next_reauth_id = NULL;
635
eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
642
eap_sim_state(data, FAILURE);
643
eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
649
static void eap_sim_process_client_error(struct eap_sm *sm,
650
struct eap_sim_data *data,
651
struct wpabuf *respData,
652
struct eap_sim_attrs *attr)
654
wpa_printf(MSG_DEBUG, "EAP-SIM: Client reported error %d",
655
attr->client_error_code);
656
if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)
657
eap_sim_state(data, SUCCESS);
659
eap_sim_state(data, FAILURE);
663
static void eap_sim_process_notification(struct eap_sm *sm,
664
struct eap_sim_data *data,
665
struct wpabuf *respData,
666
struct eap_sim_attrs *attr)
668
wpa_printf(MSG_DEBUG, "EAP-SIM: Client replied to notification");
669
if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)
670
eap_sim_state(data, SUCCESS);
672
eap_sim_state(data, FAILURE);
676
static void eap_sim_process(struct eap_sm *sm, void *priv,
677
struct wpabuf *respData)
679
struct eap_sim_data *data = priv;
683
struct eap_sim_attrs attr;
685
pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, respData, &len);
686
if (pos == NULL || len < 3)
693
if (eap_sim_parse_attr(pos, end, &attr, 0, 0)) {
694
wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to parse attributes");
695
eap_sim_state(data, FAILURE);
699
if (subtype == EAP_SIM_SUBTYPE_CLIENT_ERROR) {
700
eap_sim_process_client_error(sm, data, respData, &attr);
704
switch (data->state) {
706
eap_sim_process_start(sm, data, respData, &attr);
709
eap_sim_process_challenge(sm, data, respData, &attr);
712
eap_sim_process_reauth(sm, data, respData, &attr);
715
eap_sim_process_notification(sm, data, respData, &attr);
718
wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "
719
"process", data->state);
725
static Boolean eap_sim_isDone(struct eap_sm *sm, void *priv)
727
struct eap_sim_data *data = priv;
728
return data->state == SUCCESS || data->state == FAILURE;
732
static u8 * eap_sim_getKey(struct eap_sm *sm, void *priv, size_t *len)
734
struct eap_sim_data *data = priv;
737
if (data->state != SUCCESS)
740
key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
743
os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
744
*len = EAP_SIM_KEYING_DATA_LEN;
749
static u8 * eap_sim_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
751
struct eap_sim_data *data = priv;
754
if (data->state != SUCCESS)
757
key = os_malloc(EAP_EMSK_LEN);
760
os_memcpy(key, data->emsk, EAP_EMSK_LEN);
766
static Boolean eap_sim_isSuccess(struct eap_sm *sm, void *priv)
768
struct eap_sim_data *data = priv;
769
return data->state == SUCCESS;
773
int eap_server_sim_register(void)
775
struct eap_method *eap;
778
eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
779
EAP_VENDOR_IETF, EAP_TYPE_SIM, "SIM");
783
eap->init = eap_sim_init;
784
eap->reset = eap_sim_reset;
785
eap->buildReq = eap_sim_buildReq;
786
eap->check = eap_sim_check;
787
eap->process = eap_sim_process;
788
eap->isDone = eap_sim_isDone;
789
eap->getKey = eap_sim_getKey;
790
eap->isSuccess = eap_sim_isSuccess;
791
eap->get_emsk = eap_sim_get_emsk;
793
ret = eap_server_method_register(eap);
795
eap_server_method_free(eap);