Updated to hostap_2_6
[mech_eap.git] / libeap / src / eapol_supp / eapol_supp_sm.c
1 /*
2  * EAPOL supplicant state machines
3  * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "state_machine.h"
13 #include "wpabuf.h"
14 #include "eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/md5.h"
17 #include "common/eapol_common.h"
18 #include "eap_peer/eap.h"
19 #include "eap_peer/eap_proxy.h"
20 #include "eapol_supp_sm.h"
21
22 #define STATE_MACHINE_DATA struct eapol_sm
23 #define STATE_MACHINE_DEBUG_PREFIX "EAPOL"
24
25
26 /* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */
27
28 /**
29  * struct eapol_sm - Internal data for EAPOL state machines
30  */
31 struct eapol_sm {
32         /* Timers */
33         unsigned int authWhile;
34         unsigned int heldWhile;
35         unsigned int startWhen;
36         unsigned int idleWhile; /* for EAP state machine */
37         int timer_tick_enabled;
38
39         /* Global variables */
40         Boolean eapFail;
41         Boolean eapolEap;
42         Boolean eapSuccess;
43         Boolean initialize;
44         Boolean keyDone;
45         Boolean keyRun;
46         PortControl portControl;
47         Boolean portEnabled;
48         PortStatus suppPortStatus;  /* dot1xSuppControlledPortStatus */
49         Boolean portValid;
50         Boolean suppAbort;
51         Boolean suppFail;
52         Boolean suppStart;
53         Boolean suppSuccess;
54         Boolean suppTimeout;
55
56         /* Supplicant PAE state machine */
57         enum {
58                 SUPP_PAE_UNKNOWN = 0,
59                 SUPP_PAE_DISCONNECTED = 1,
60                 SUPP_PAE_LOGOFF = 2,
61                 SUPP_PAE_CONNECTING = 3,
62                 SUPP_PAE_AUTHENTICATING = 4,
63                 SUPP_PAE_AUTHENTICATED = 5,
64                 /* unused(6) */
65                 SUPP_PAE_HELD = 7,
66                 SUPP_PAE_RESTART = 8,
67                 SUPP_PAE_S_FORCE_AUTH = 9,
68                 SUPP_PAE_S_FORCE_UNAUTH = 10
69         } SUPP_PAE_state; /* dot1xSuppPaeState */
70         /* Variables */
71         Boolean userLogoff;
72         Boolean logoffSent;
73         unsigned int startCount;
74         Boolean eapRestart;
75         PortControl sPortMode;
76         /* Constants */
77         unsigned int heldPeriod; /* dot1xSuppHeldPeriod */
78         unsigned int startPeriod; /* dot1xSuppStartPeriod */
79         unsigned int maxStart; /* dot1xSuppMaxStart */
80
81         /* Key Receive state machine */
82         enum {
83                 KEY_RX_UNKNOWN = 0,
84                 KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE
85         } KEY_RX_state;
86         /* Variables */
87         Boolean rxKey;
88
89         /* Supplicant Backend state machine */
90         enum {
91                 SUPP_BE_UNKNOWN = 0,
92                 SUPP_BE_INITIALIZE = 1,
93                 SUPP_BE_IDLE = 2,
94                 SUPP_BE_REQUEST = 3,
95                 SUPP_BE_RECEIVE = 4,
96                 SUPP_BE_RESPONSE = 5,
97                 SUPP_BE_FAIL = 6,
98                 SUPP_BE_TIMEOUT = 7, 
99                 SUPP_BE_SUCCESS = 8
100         } SUPP_BE_state; /* dot1xSuppBackendPaeState */
101         /* Variables */
102         Boolean eapNoResp;
103         Boolean eapReq;
104         Boolean eapResp;
105         /* Constants */
106         unsigned int authPeriod; /* dot1xSuppAuthPeriod */
107
108         /* Statistics */
109         unsigned int dot1xSuppEapolFramesRx;
110         unsigned int dot1xSuppEapolFramesTx;
111         unsigned int dot1xSuppEapolStartFramesTx;
112         unsigned int dot1xSuppEapolLogoffFramesTx;
113         unsigned int dot1xSuppEapolRespFramesTx;
114         unsigned int dot1xSuppEapolReqIdFramesRx;
115         unsigned int dot1xSuppEapolReqFramesRx;
116         unsigned int dot1xSuppInvalidEapolFramesRx;
117         unsigned int dot1xSuppEapLengthErrorFramesRx;
118         unsigned int dot1xSuppLastEapolFrameVersion;
119         unsigned char dot1xSuppLastEapolFrameSource[6];
120
121         /* Miscellaneous variables (not defined in IEEE 802.1X-2004) */
122         Boolean changed;
123         struct eap_sm *eap;
124         struct eap_peer_config *config;
125         Boolean initial_req;
126         u8 *last_rx_key;
127         size_t last_rx_key_len;
128         struct wpabuf *eapReqData; /* for EAP */
129         Boolean altAccept; /* for EAP */
130         Boolean altReject; /* for EAP */
131         Boolean eapTriggerStart;
132         Boolean replay_counter_valid;
133         u8 last_replay_counter[16];
134         struct eapol_config conf;
135         struct eapol_ctx *ctx;
136         enum { EAPOL_CB_IN_PROGRESS = 0, EAPOL_CB_SUCCESS, EAPOL_CB_FAILURE }
137                 cb_status;
138         Boolean cached_pmk;
139
140         Boolean unicast_key_received, broadcast_key_received;
141
142         Boolean force_authorized_update;
143
144 #ifdef CONFIG_EAP_PROXY
145         Boolean use_eap_proxy;
146         struct eap_proxy_sm *eap_proxy;
147 #endif /* CONFIG_EAP_PROXY */
148 };
149
150
151 static void eapol_sm_txLogoff(struct eapol_sm *sm);
152 static void eapol_sm_txStart(struct eapol_sm *sm);
153 static void eapol_sm_processKey(struct eapol_sm *sm);
154 static void eapol_sm_getSuppRsp(struct eapol_sm *sm);
155 static void eapol_sm_txSuppRsp(struct eapol_sm *sm);
156 static void eapol_sm_abortSupp(struct eapol_sm *sm);
157 static void eapol_sm_abort_cached(struct eapol_sm *sm);
158 static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx);
159 static void eapol_sm_set_port_authorized(struct eapol_sm *sm);
160 static void eapol_sm_set_port_unauthorized(struct eapol_sm *sm);
161
162
163 /* Port Timers state machine - implemented as a function that will be called
164  * once a second as a registered event loop timeout */
165 static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
166 {
167         struct eapol_sm *sm = timeout_ctx;
168
169         if (sm->authWhile > 0) {
170                 sm->authWhile--;
171                 if (sm->authWhile == 0)
172                         wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0");
173         }
174         if (sm->heldWhile > 0) {
175                 sm->heldWhile--;
176                 if (sm->heldWhile == 0)
177                         wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0");
178         }
179         if (sm->startWhen > 0) {
180                 sm->startWhen--;
181                 if (sm->startWhen == 0)
182                         wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0");
183         }
184         if (sm->idleWhile > 0) {
185                 sm->idleWhile--;
186                 if (sm->idleWhile == 0)
187                         wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0");
188         }
189
190         if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) {
191                 eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx,
192                                        sm);
193         } else {
194                 wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick");
195                 sm->timer_tick_enabled = 0;
196         }
197         eapol_sm_step(sm);
198 }
199
200
201 static void eapol_enable_timer_tick(struct eapol_sm *sm)
202 {
203         if (sm->timer_tick_enabled)
204                 return;
205         wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick");
206         sm->timer_tick_enabled = 1;
207         eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
208         eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
209 }
210
211
212 SM_STATE(SUPP_PAE, LOGOFF)
213 {
214         SM_ENTRY(SUPP_PAE, LOGOFF);
215         eapol_sm_txLogoff(sm);
216         sm->logoffSent = TRUE;
217         eapol_sm_set_port_unauthorized(sm);
218 }
219
220
221 SM_STATE(SUPP_PAE, DISCONNECTED)
222 {
223         SM_ENTRY(SUPP_PAE, DISCONNECTED);
224         sm->sPortMode = Auto;
225         sm->startCount = 0;
226         sm->eapTriggerStart = FALSE;
227         sm->logoffSent = FALSE;
228         eapol_sm_set_port_unauthorized(sm);
229         sm->suppAbort = TRUE;
230
231         sm->unicast_key_received = FALSE;
232         sm->broadcast_key_received = FALSE;
233
234         /*
235          * IEEE Std 802.1X-2004 does not clear heldWhile here, but doing so
236          * allows the timer tick to be stopped more quickly when the port is
237          * not enabled. Since this variable is used only within HELD state,
238          * clearing it on initialization does not change actual state machine
239          * behavior.
240          */
241         sm->heldWhile = 0;
242 }
243
244
245 SM_STATE(SUPP_PAE, CONNECTING)
246 {
247         int send_start = sm->SUPP_PAE_state == SUPP_PAE_CONNECTING ||
248                 sm->SUPP_PAE_state == SUPP_PAE_HELD;
249         SM_ENTRY(SUPP_PAE, CONNECTING);
250
251         if (sm->eapTriggerStart)
252                 send_start = 1;
253         sm->eapTriggerStart = FALSE;
254
255         if (send_start) {
256                 sm->startWhen = sm->startPeriod;
257                 sm->startCount++;
258         } else {
259                 /*
260                  * Do not send EAPOL-Start immediately since in most cases,
261                  * Authenticator is going to start authentication immediately
262                  * after association and an extra EAPOL-Start is just going to
263                  * delay authentication. Use a short timeout to send the first
264                  * EAPOL-Start if Authenticator does not start authentication.
265                  */
266                 if (sm->conf.wps && !(sm->conf.wps & EAPOL_PEER_IS_WPS20_AP)) {
267                         /* Reduce latency on starting WPS negotiation. */
268                         wpa_printf(MSG_DEBUG,
269                                    "EAPOL: Using shorter startWhen for WPS");
270                         sm->startWhen = 1;
271                 } else {
272                         sm->startWhen = 2;
273                 }
274         }
275         eapol_enable_timer_tick(sm);
276         sm->eapolEap = FALSE;
277         if (send_start)
278                 eapol_sm_txStart(sm);
279 }
280
281
282 SM_STATE(SUPP_PAE, AUTHENTICATING)
283 {
284         SM_ENTRY(SUPP_PAE, AUTHENTICATING);
285         sm->startCount = 0;
286         sm->suppSuccess = FALSE;
287         sm->suppFail = FALSE;
288         sm->suppTimeout = FALSE;
289         sm->keyRun = FALSE;
290         sm->keyDone = FALSE;
291         sm->suppStart = TRUE;
292 }
293
294
295 SM_STATE(SUPP_PAE, HELD)
296 {
297         SM_ENTRY(SUPP_PAE, HELD);
298         sm->heldWhile = sm->heldPeriod;
299         eapol_enable_timer_tick(sm);
300         eapol_sm_set_port_unauthorized(sm);
301         sm->cb_status = EAPOL_CB_FAILURE;
302 }
303
304
305 SM_STATE(SUPP_PAE, AUTHENTICATED)
306 {
307         SM_ENTRY(SUPP_PAE, AUTHENTICATED);
308         eapol_sm_set_port_authorized(sm);
309         sm->cb_status = EAPOL_CB_SUCCESS;
310 }
311
312
313 SM_STATE(SUPP_PAE, RESTART)
314 {
315         SM_ENTRY(SUPP_PAE, RESTART);
316         sm->eapRestart = TRUE;
317         if (sm->altAccept) {
318                 /*
319                  * Prevent EAP peer state machine from failing due to prior
320                  * external EAP success notification (altSuccess=TRUE in the
321                  * IDLE state could result in a transition to the FAILURE state.
322                  */
323                 wpa_printf(MSG_DEBUG, "EAPOL: Clearing prior altAccept TRUE");
324                 sm->eapSuccess = FALSE;
325                 sm->altAccept = FALSE;
326         }
327 }
328
329
330 SM_STATE(SUPP_PAE, S_FORCE_AUTH)
331 {
332         SM_ENTRY(SUPP_PAE, S_FORCE_AUTH);
333         eapol_sm_set_port_authorized(sm);
334         sm->sPortMode = ForceAuthorized;
335 }
336
337
338 SM_STATE(SUPP_PAE, S_FORCE_UNAUTH)
339 {
340         SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH);
341         eapol_sm_set_port_unauthorized(sm);
342         sm->sPortMode = ForceUnauthorized;
343         eapol_sm_txLogoff(sm);
344 }
345
346
347 SM_STEP(SUPP_PAE)
348 {
349         if ((sm->userLogoff && !sm->logoffSent) &&
350             !(sm->initialize || !sm->portEnabled))
351                 SM_ENTER_GLOBAL(SUPP_PAE, LOGOFF);
352         else if (((sm->portControl == Auto) &&
353                   (sm->sPortMode != sm->portControl)) ||
354                  sm->initialize || !sm->portEnabled)
355                 SM_ENTER_GLOBAL(SUPP_PAE, DISCONNECTED);
356         else if ((sm->portControl == ForceAuthorized) &&
357                  (sm->sPortMode != sm->portControl) &&
358                  !(sm->initialize || !sm->portEnabled))
359                 SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_AUTH);
360         else if ((sm->portControl == ForceUnauthorized) &&
361                  (sm->sPortMode != sm->portControl) &&
362                  !(sm->initialize || !sm->portEnabled))
363                 SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_UNAUTH);
364         else switch (sm->SUPP_PAE_state) {
365         case SUPP_PAE_UNKNOWN:
366                 break;
367         case SUPP_PAE_LOGOFF:
368                 if (!sm->userLogoff)
369                         SM_ENTER(SUPP_PAE, DISCONNECTED);
370                 break;
371         case SUPP_PAE_DISCONNECTED:
372                 SM_ENTER(SUPP_PAE, CONNECTING);
373                 break;
374         case SUPP_PAE_CONNECTING:
375                 if (sm->startWhen == 0 && sm->startCount < sm->maxStart)
376                         SM_ENTER(SUPP_PAE, CONNECTING);
377                 else if (sm->startWhen == 0 &&
378                          sm->startCount >= sm->maxStart &&
379                          sm->portValid)
380                         SM_ENTER(SUPP_PAE, AUTHENTICATED);
381                 else if (sm->eapSuccess || sm->eapFail)
382                         SM_ENTER(SUPP_PAE, AUTHENTICATING);
383                 else if (sm->eapolEap)
384                         SM_ENTER(SUPP_PAE, RESTART);
385                 else if (sm->startWhen == 0 &&
386                          sm->startCount >= sm->maxStart &&
387                          !sm->portValid)
388                         SM_ENTER(SUPP_PAE, HELD);
389                 break;
390         case SUPP_PAE_AUTHENTICATING:
391                 if (sm->eapSuccess && !sm->portValid &&
392                     sm->conf.accept_802_1x_keys &&
393                     sm->conf.required_keys == 0) {
394                         wpa_printf(MSG_DEBUG, "EAPOL: IEEE 802.1X for "
395                                    "plaintext connection; no EAPOL-Key frames "
396                                    "required");
397                         sm->portValid = TRUE;
398                         if (sm->ctx->eapol_done_cb)
399                                 sm->ctx->eapol_done_cb(sm->ctx->ctx);
400                 }
401                 if (sm->eapSuccess && sm->portValid)
402                         SM_ENTER(SUPP_PAE, AUTHENTICATED);
403                 else if (sm->eapFail || (sm->keyDone && !sm->portValid))
404                         SM_ENTER(SUPP_PAE, HELD);
405                 else if (sm->suppTimeout)
406                         SM_ENTER(SUPP_PAE, CONNECTING);
407                 else if (sm->eapTriggerStart)
408                         SM_ENTER(SUPP_PAE, CONNECTING);
409                 break;
410         case SUPP_PAE_HELD:
411                 if (sm->heldWhile == 0)
412                         SM_ENTER(SUPP_PAE, CONNECTING);
413                 else if (sm->eapolEap)
414                         SM_ENTER(SUPP_PAE, RESTART);
415                 break;
416         case SUPP_PAE_AUTHENTICATED:
417                 if (sm->eapolEap && sm->portValid)
418                         SM_ENTER(SUPP_PAE, RESTART);
419                 else if (!sm->portValid)
420                         SM_ENTER(SUPP_PAE, DISCONNECTED);
421                 break;
422         case SUPP_PAE_RESTART:
423                 if (!sm->eapRestart)
424                         SM_ENTER(SUPP_PAE, AUTHENTICATING);
425                 break;
426         case SUPP_PAE_S_FORCE_AUTH:
427                 break;
428         case SUPP_PAE_S_FORCE_UNAUTH:
429                 break;
430         }
431 }
432
433
434 SM_STATE(KEY_RX, NO_KEY_RECEIVE)
435 {
436         SM_ENTRY(KEY_RX, NO_KEY_RECEIVE);
437 }
438
439
440 SM_STATE(KEY_RX, KEY_RECEIVE)
441 {
442         SM_ENTRY(KEY_RX, KEY_RECEIVE);
443         eapol_sm_processKey(sm);
444         sm->rxKey = FALSE;
445 }
446
447
448 SM_STEP(KEY_RX)
449 {
450         if (sm->initialize || !sm->portEnabled)
451                 SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE);
452         switch (sm->KEY_RX_state) {
453         case KEY_RX_UNKNOWN:
454                 break;
455         case KEY_RX_NO_KEY_RECEIVE:
456                 if (sm->rxKey)
457                         SM_ENTER(KEY_RX, KEY_RECEIVE);
458                 break;
459         case KEY_RX_KEY_RECEIVE:
460                 if (sm->rxKey)
461                         SM_ENTER(KEY_RX, KEY_RECEIVE);
462                 break;
463         }
464 }
465
466
467 SM_STATE(SUPP_BE, REQUEST)
468 {
469         SM_ENTRY(SUPP_BE, REQUEST);
470         sm->authWhile = 0;
471         sm->eapReq = TRUE;
472         eapol_sm_getSuppRsp(sm);
473 }
474
475
476 SM_STATE(SUPP_BE, RESPONSE)
477 {
478         SM_ENTRY(SUPP_BE, RESPONSE);
479         eapol_sm_txSuppRsp(sm);
480         sm->eapResp = FALSE;
481 }
482
483
484 SM_STATE(SUPP_BE, SUCCESS)
485 {
486         SM_ENTRY(SUPP_BE, SUCCESS);
487         sm->keyRun = TRUE;
488         sm->suppSuccess = TRUE;
489
490 #ifdef CONFIG_EAP_PROXY
491         if (sm->use_eap_proxy) {
492                 if (eap_proxy_key_available(sm->eap_proxy)) {
493                         /* New key received - clear IEEE 802.1X EAPOL-Key replay
494                          * counter */
495                         sm->replay_counter_valid = FALSE;
496                 }
497                 return;
498         }
499 #endif /* CONFIG_EAP_PROXY */
500
501         if (eap_key_available(sm->eap)) {
502                 /* New key received - clear IEEE 802.1X EAPOL-Key replay
503                  * counter */
504                 sm->replay_counter_valid = FALSE;
505         }
506 }
507
508
509 SM_STATE(SUPP_BE, FAIL)
510 {
511         SM_ENTRY(SUPP_BE, FAIL);
512         sm->suppFail = TRUE;
513 }
514
515
516 SM_STATE(SUPP_BE, TIMEOUT)
517 {
518         SM_ENTRY(SUPP_BE, TIMEOUT);
519         sm->suppTimeout = TRUE;
520 }
521
522
523 SM_STATE(SUPP_BE, IDLE)
524 {
525         SM_ENTRY(SUPP_BE, IDLE);
526         sm->suppStart = FALSE;
527         sm->initial_req = TRUE;
528 }
529
530
531 SM_STATE(SUPP_BE, INITIALIZE)
532 {
533         SM_ENTRY(SUPP_BE, INITIALIZE);
534         eapol_sm_abortSupp(sm);
535         sm->suppAbort = FALSE;
536
537         /*
538          * IEEE Std 802.1X-2004 does not clear authWhile here, but doing so
539          * allows the timer tick to be stopped more quickly when the port is
540          * not enabled. Since this variable is used only within RECEIVE state,
541          * clearing it on initialization does not change actual state machine
542          * behavior.
543          */
544         sm->authWhile = 0;
545 }
546
547
548 SM_STATE(SUPP_BE, RECEIVE)
549 {
550         SM_ENTRY(SUPP_BE, RECEIVE);
551         sm->authWhile = sm->authPeriod;
552         eapol_enable_timer_tick(sm);
553         sm->eapolEap = FALSE;
554         sm->eapNoResp = FALSE;
555         sm->initial_req = FALSE;
556 }
557
558
559 SM_STEP(SUPP_BE)
560 {
561         if (sm->initialize || sm->suppAbort)
562                 SM_ENTER_GLOBAL(SUPP_BE, INITIALIZE);
563         else switch (sm->SUPP_BE_state) {
564         case SUPP_BE_UNKNOWN:
565                 break;
566         case SUPP_BE_REQUEST:
567                 /*
568                  * IEEE Std 802.1X-2004 has transitions from REQUEST to FAIL
569                  * and SUCCESS based on eapFail and eapSuccess, respectively.
570                  * However, IEEE Std 802.1X-2004 is also specifying that
571                  * eapNoResp should be set in conjunction with eapSuccess and
572                  * eapFail which would mean that more than one of the
573                  * transitions here would be activated at the same time.
574                  * Skipping RESPONSE and/or RECEIVE states in these cases can
575                  * cause problems and the direct transitions to do not seem
576                  * correct. Because of this, the conditions for these
577                  * transitions are verified only after eapNoResp. They are
578                  * unlikely to be used since eapNoResp should always be set if
579                  * either of eapSuccess or eapFail is set.
580                  */
581                 if (sm->eapResp && sm->eapNoResp) {
582                         wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both "
583                                    "eapResp and eapNoResp set?!");
584                 }
585                 if (sm->eapResp)
586                         SM_ENTER(SUPP_BE, RESPONSE);
587                 else if (sm->eapNoResp)
588                         SM_ENTER(SUPP_BE, RECEIVE);
589                 else if (sm->eapFail)
590                         SM_ENTER(SUPP_BE, FAIL);
591                 else if (sm->eapSuccess)
592                         SM_ENTER(SUPP_BE, SUCCESS);
593                 break;
594         case SUPP_BE_RESPONSE:
595                 SM_ENTER(SUPP_BE, RECEIVE);
596                 break;
597         case SUPP_BE_SUCCESS:
598                 SM_ENTER(SUPP_BE, IDLE);
599                 break;
600         case SUPP_BE_FAIL:
601                 SM_ENTER(SUPP_BE, IDLE);
602                 break;
603         case SUPP_BE_TIMEOUT:
604                 SM_ENTER(SUPP_BE, IDLE);
605                 break;
606         case SUPP_BE_IDLE:
607                 if (sm->eapFail && sm->suppStart)
608                         SM_ENTER(SUPP_BE, FAIL);
609                 else if (sm->eapolEap && sm->suppStart)
610                         SM_ENTER(SUPP_BE, REQUEST);
611                 else if (sm->eapSuccess && sm->suppStart)
612                         SM_ENTER(SUPP_BE, SUCCESS);
613                 break;
614         case SUPP_BE_INITIALIZE:
615                 SM_ENTER(SUPP_BE, IDLE);
616                 break;
617         case SUPP_BE_RECEIVE:
618                 if (sm->eapolEap)
619                         SM_ENTER(SUPP_BE, REQUEST);
620                 else if (sm->eapFail)
621                         SM_ENTER(SUPP_BE, FAIL);
622                 else if (sm->authWhile == 0)
623                         SM_ENTER(SUPP_BE, TIMEOUT);
624                 else if (sm->eapSuccess)
625                         SM_ENTER(SUPP_BE, SUCCESS);
626                 break;
627         }
628 }
629
630
631 static void eapol_sm_txLogoff(struct eapol_sm *sm)
632 {
633         wpa_printf(MSG_DEBUG, "EAPOL: txLogoff");
634         sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
635                             IEEE802_1X_TYPE_EAPOL_LOGOFF, (u8 *) "", 0);
636         sm->dot1xSuppEapolLogoffFramesTx++;
637         sm->dot1xSuppEapolFramesTx++;
638 }
639
640
641 static void eapol_sm_txStart(struct eapol_sm *sm)
642 {
643         wpa_printf(MSG_DEBUG, "EAPOL: txStart");
644         sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
645                             IEEE802_1X_TYPE_EAPOL_START, (u8 *) "", 0);
646         sm->dot1xSuppEapolStartFramesTx++;
647         sm->dot1xSuppEapolFramesTx++;
648 }
649
650
651 #define IEEE8021X_ENCR_KEY_LEN 32
652 #define IEEE8021X_SIGN_KEY_LEN 32
653
654 struct eap_key_data {
655         u8 encr_key[IEEE8021X_ENCR_KEY_LEN];
656         u8 sign_key[IEEE8021X_SIGN_KEY_LEN];
657 };
658
659
660 static void eapol_sm_processKey(struct eapol_sm *sm)
661 {
662 #ifndef CONFIG_FIPS
663         struct ieee802_1x_hdr *hdr;
664         struct ieee802_1x_eapol_key *key;
665         struct eap_key_data keydata;
666         u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32];
667 #ifndef CONFIG_NO_RC4
668         u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN];
669 #endif /* CONFIG_NO_RC4 */
670         int key_len, res, sign_key_len, encr_key_len;
671         u16 rx_key_length;
672         size_t plen;
673
674         wpa_printf(MSG_DEBUG, "EAPOL: processKey");
675         if (sm->last_rx_key == NULL)
676                 return;
677
678         if (!sm->conf.accept_802_1x_keys) {
679                 wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key"
680                            " even though this was not accepted - "
681                            "ignoring this packet");
682                 return;
683         }
684
685         if (sm->last_rx_key_len < sizeof(*hdr) + sizeof(*key))
686                 return;
687         hdr = (struct ieee802_1x_hdr *) sm->last_rx_key;
688         key = (struct ieee802_1x_eapol_key *) (hdr + 1);
689         plen = be_to_host16(hdr->length);
690         if (sizeof(*hdr) + plen > sm->last_rx_key_len || plen < sizeof(*key)) {
691                 wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame");
692                 return;
693         }
694         rx_key_length = WPA_GET_BE16(key->key_length);
695         wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d "
696                    "EAPOL-Key: type=%d key_length=%d key_index=0x%x",
697                    hdr->version, hdr->type, be_to_host16(hdr->length),
698                    key->type, rx_key_length, key->key_index);
699
700         eapol_sm_notify_lower_layer_success(sm, 1);
701         sign_key_len = IEEE8021X_SIGN_KEY_LEN;
702         encr_key_len = IEEE8021X_ENCR_KEY_LEN;
703         res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata));
704         if (res < 0) {
705                 wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for "
706                            "decrypting EAPOL-Key keys");
707                 return;
708         }
709         if (res == 16) {
710                 /* LEAP derives only 16 bytes of keying material. */
711                 res = eapol_sm_get_key(sm, (u8 *) &keydata, 16);
712                 if (res) {
713                         wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP "
714                                    "master key for decrypting EAPOL-Key keys");
715                         return;
716                 }
717                 sign_key_len = 16;
718                 encr_key_len = 16;
719                 os_memcpy(keydata.sign_key, keydata.encr_key, 16);
720         } else if (res) {
721                 wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key "
722                            "data for decrypting EAPOL-Key keys (res=%d)", res);
723                 return;
724         }
725
726         /* The key replay_counter must increase when same master key */
727         if (sm->replay_counter_valid &&
728             os_memcmp(sm->last_replay_counter, key->replay_counter,
729                       IEEE8021X_REPLAY_COUNTER_LEN) >= 0) {
730                 wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did "
731                            "not increase - ignoring key");
732                 wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter",
733                             sm->last_replay_counter,
734                             IEEE8021X_REPLAY_COUNTER_LEN);
735                 wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter",
736                             key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN);
737                 return;
738         }
739
740         /* Verify key signature (HMAC-MD5) */
741         os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN);
742         os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN);
743         hmac_md5(keydata.sign_key, sign_key_len,
744                  sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length),
745                  key->key_signature);
746         if (os_memcmp_const(orig_key_sign, key->key_signature,
747                             IEEE8021X_KEY_SIGN_LEN) != 0) {
748                 wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in "
749                            "EAPOL-Key packet");
750                 os_memcpy(key->key_signature, orig_key_sign,
751                           IEEE8021X_KEY_SIGN_LEN);
752                 return;
753         }
754         wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified");
755
756         key_len = plen - sizeof(*key);
757         if (key_len > 32 || rx_key_length > 32) {
758                 wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d",
759                            key_len ? key_len : rx_key_length);
760                 return;
761         }
762         if (key_len == rx_key_length) {
763 #ifdef CONFIG_NO_RC4
764                 if (encr_key_len) {
765                         /* otherwise unused */
766                 }
767                 wpa_printf(MSG_ERROR, "EAPOL: RC4 not supported in the build");
768                 return;
769 #else /* CONFIG_NO_RC4 */
770                 os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN);
771                 os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key,
772                           encr_key_len);
773                 os_memcpy(datakey, key + 1, key_len);
774                 rc4_skip(ekey, IEEE8021X_KEY_IV_LEN + encr_key_len, 0,
775                          datakey, key_len);
776                 wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
777                                 datakey, key_len);
778 #endif /* CONFIG_NO_RC4 */
779         } else if (key_len == 0) {
780                 /*
781                  * IEEE 802.1X-2004 specifies that least significant Key Length
782                  * octets from MS-MPPE-Send-Key are used as the key if the key
783                  * data is not present. This seems to be meaning the beginning
784                  * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in
785                  * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator.
786                  * Anyway, taking the beginning of the keying material from EAP
787                  * seems to interoperate with Authenticators.
788                  */
789                 key_len = rx_key_length;
790                 os_memcpy(datakey, keydata.encr_key, key_len);
791                 wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying "
792                                 "material data encryption key",
793                                 datakey, key_len);
794         } else {
795                 wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d "
796                            "(key_length=%d)", key_len, rx_key_length);
797                 return;
798         }
799
800         sm->replay_counter_valid = TRUE;
801         os_memcpy(sm->last_replay_counter, key->replay_counter,
802                   IEEE8021X_REPLAY_COUNTER_LEN);
803
804         wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d "
805                    "len %d",
806                    key->key_index & IEEE8021X_KEY_INDEX_FLAG ?
807                    "unicast" : "broadcast",
808                    key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len);
809
810         if (sm->ctx->set_wep_key &&
811             sm->ctx->set_wep_key(sm->ctx->ctx,
812                                  key->key_index & IEEE8021X_KEY_INDEX_FLAG,
813                                  key->key_index & IEEE8021X_KEY_INDEX_MASK,
814                                  datakey, key_len) < 0) {
815                 wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the "
816                            " driver.");
817         } else {
818                 if (key->key_index & IEEE8021X_KEY_INDEX_FLAG)
819                         sm->unicast_key_received = TRUE;
820                 else
821                         sm->broadcast_key_received = TRUE;
822
823                 if ((sm->unicast_key_received ||
824                      !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) &&
825                     (sm->broadcast_key_received ||
826                      !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST)))
827                 {
828                         wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key "
829                                    "frames received");
830                         sm->portValid = TRUE;
831                         if (sm->ctx->eapol_done_cb)
832                                 sm->ctx->eapol_done_cb(sm->ctx->ctx);
833                 }
834         }
835 #endif /* CONFIG_FIPS */
836 }
837
838
839 static void eapol_sm_getSuppRsp(struct eapol_sm *sm)
840 {
841         wpa_printf(MSG_DEBUG, "EAPOL: getSuppRsp");
842         /* EAP layer processing; no special code is needed, since Supplicant
843          * Backend state machine is waiting for eapNoResp or eapResp to be set
844          * and these are only set in the EAP state machine when the processing
845          * has finished. */
846 }
847
848
849 static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
850 {
851         struct wpabuf *resp;
852
853         wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
854
855 #ifdef CONFIG_EAP_PROXY
856         if (sm->use_eap_proxy) {
857                 /* Get EAP Response from EAP Proxy */
858                 resp = eap_proxy_get_eapRespData(sm->eap_proxy);
859                 if (resp == NULL) {
860                         wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP Proxy "
861                                    "response data not available");
862                         return;
863                 }
864         } else
865 #endif /* CONFIG_EAP_PROXY */
866
867         resp = eap_get_eapRespData(sm->eap);
868         if (resp == NULL) {
869                 wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
870                            "not available");
871                 return;
872         }
873
874         /* Send EAP-Packet from the EAP layer to the Authenticator */
875         sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
876                             IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head(resp),
877                             wpabuf_len(resp));
878
879         /* eapRespData is not used anymore, so free it here */
880         wpabuf_free(resp);
881
882         if (sm->initial_req)
883                 sm->dot1xSuppEapolReqIdFramesRx++;
884         else
885                 sm->dot1xSuppEapolReqFramesRx++;
886         sm->dot1xSuppEapolRespFramesTx++;
887         sm->dot1xSuppEapolFramesTx++;
888 }
889
890
891 static void eapol_sm_abortSupp(struct eapol_sm *sm)
892 {
893         /* release system resources that may have been allocated for the
894          * authentication session */
895         os_free(sm->last_rx_key);
896         sm->last_rx_key = NULL;
897         wpabuf_free(sm->eapReqData);
898         sm->eapReqData = NULL;
899         eap_sm_abort(sm->eap);
900 }
901
902
903 static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx)
904 {
905         eapol_sm_step(timeout_ctx);
906 }
907
908
909 static void eapol_sm_set_port_authorized(struct eapol_sm *sm)
910 {
911         int cb;
912
913         cb = sm->suppPortStatus != Authorized || sm->force_authorized_update;
914         sm->force_authorized_update = FALSE;
915         sm->suppPortStatus = Authorized;
916         if (cb && sm->ctx->port_cb)
917                 sm->ctx->port_cb(sm->ctx->ctx, 1);
918 }
919
920
921 static void eapol_sm_set_port_unauthorized(struct eapol_sm *sm)
922 {
923         int cb;
924
925         cb = sm->suppPortStatus != Unauthorized || sm->force_authorized_update;
926         sm->force_authorized_update = FALSE;
927         sm->suppPortStatus = Unauthorized;
928         if (cb && sm->ctx->port_cb)
929                 sm->ctx->port_cb(sm->ctx->ctx, 0);
930 }
931
932
933 /**
934  * eapol_sm_step - EAPOL state machine step function
935  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
936  *
937  * This function is called to notify the state machine about changed external
938  * variables. It will step through the EAPOL state machines in loop to process
939  * all triggered state changes.
940  */
941 void eapol_sm_step(struct eapol_sm *sm)
942 {
943         int i;
944
945         /* In theory, it should be ok to run this in loop until !changed.
946          * However, it is better to use a limit on number of iterations to
947          * allow events (e.g., SIGTERM) to stop the program cleanly if the
948          * state machine were to generate a busy loop. */
949         for (i = 0; i < 100; i++) {
950                 sm->changed = FALSE;
951                 SM_STEP_RUN(SUPP_PAE);
952                 SM_STEP_RUN(KEY_RX);
953                 SM_STEP_RUN(SUPP_BE);
954 #ifdef CONFIG_EAP_PROXY
955                 if (sm->use_eap_proxy) {
956                         /* Drive the EAP proxy state machine */
957                         if (eap_proxy_sm_step(sm->eap_proxy, sm->eap))
958                                 sm->changed = TRUE;
959                 } else
960 #endif /* CONFIG_EAP_PROXY */
961                 if (eap_peer_sm_step(sm->eap))
962                         sm->changed = TRUE;
963                 if (!sm->changed)
964                         break;
965         }
966
967         if (sm->changed) {
968                 /* restart EAPOL state machine step from timeout call in order
969                  * to allow other events to be processed. */
970                 eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
971                 eloop_register_timeout(0, 0, eapol_sm_step_timeout, NULL, sm);
972         }
973
974         if (sm->ctx->cb && sm->cb_status != EAPOL_CB_IN_PROGRESS) {
975                 enum eapol_supp_result result;
976                 if (sm->cb_status == EAPOL_CB_SUCCESS)
977                         result = EAPOL_SUPP_RESULT_SUCCESS;
978                 else if (eap_peer_was_failure_expected(sm->eap))
979                         result = EAPOL_SUPP_RESULT_EXPECTED_FAILURE;
980                 else
981                         result = EAPOL_SUPP_RESULT_FAILURE;
982                 sm->cb_status = EAPOL_CB_IN_PROGRESS;
983                 sm->ctx->cb(sm, result, sm->ctx->cb_ctx);
984         }
985 }
986
987
988 #ifdef CONFIG_CTRL_IFACE
989 static const char *eapol_supp_pae_state(int state)
990 {
991         switch (state) {
992         case SUPP_PAE_LOGOFF:
993                 return "LOGOFF";
994         case SUPP_PAE_DISCONNECTED:
995                 return "DISCONNECTED";
996         case SUPP_PAE_CONNECTING:
997                 return "CONNECTING";
998         case SUPP_PAE_AUTHENTICATING:
999                 return "AUTHENTICATING";
1000         case SUPP_PAE_HELD:
1001                 return "HELD";
1002         case SUPP_PAE_AUTHENTICATED:
1003                 return "AUTHENTICATED";
1004         case SUPP_PAE_RESTART:
1005                 return "RESTART";
1006         default:
1007                 return "UNKNOWN";
1008         }
1009 }
1010
1011
1012 static const char *eapol_supp_be_state(int state)
1013 {
1014         switch (state) {
1015         case SUPP_BE_REQUEST:
1016                 return "REQUEST";
1017         case SUPP_BE_RESPONSE:
1018                 return "RESPONSE";
1019         case SUPP_BE_SUCCESS:
1020                 return "SUCCESS";
1021         case SUPP_BE_FAIL:
1022                 return "FAIL";
1023         case SUPP_BE_TIMEOUT:
1024                 return "TIMEOUT";
1025         case SUPP_BE_IDLE:
1026                 return "IDLE";
1027         case SUPP_BE_INITIALIZE:
1028                 return "INITIALIZE";
1029         case SUPP_BE_RECEIVE:
1030                 return "RECEIVE";
1031         default:
1032                 return "UNKNOWN";
1033         }
1034 }
1035
1036
1037 static const char * eapol_port_status(PortStatus status)
1038 {
1039         if (status == Authorized)
1040                 return "Authorized";
1041         else
1042                 return "Unauthorized";
1043 }
1044 #endif /* CONFIG_CTRL_IFACE */
1045
1046
1047 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1048 static const char * eapol_port_control(PortControl ctrl)
1049 {
1050         switch (ctrl) {
1051         case Auto:
1052                 return "Auto";
1053         case ForceUnauthorized:
1054                 return "ForceUnauthorized";
1055         case ForceAuthorized:
1056                 return "ForceAuthorized";
1057         default:
1058                 return "Unknown";
1059         }
1060 }
1061 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1062
1063
1064 /**
1065  * eapol_sm_configure - Set EAPOL variables
1066  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1067  * @heldPeriod: dot1xSuppHeldPeriod
1068  * @authPeriod: dot1xSuppAuthPeriod
1069  * @startPeriod: dot1xSuppStartPeriod
1070  * @maxStart: dot1xSuppMaxStart
1071  *
1072  * Set configurable EAPOL state machine variables. Each variable can be set to
1073  * the given value or ignored if set to -1 (to set only some of the variables).
1074  */
1075 void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
1076                         int startPeriod, int maxStart)
1077 {
1078         if (sm == NULL)
1079                 return;
1080         if (heldPeriod >= 0)
1081                 sm->heldPeriod = heldPeriod;
1082         if (authPeriod >= 0)
1083                 sm->authPeriod = authPeriod;
1084         if (startPeriod >= 0)
1085                 sm->startPeriod = startPeriod;
1086         if (maxStart >= 0)
1087                 sm->maxStart = maxStart;
1088 }
1089
1090
1091 /**
1092  * eapol_sm_get_method_name - Get EAPOL method name
1093  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1094  * Returns: Static string containing name of current eap method or NULL
1095  */
1096 const char * eapol_sm_get_method_name(struct eapol_sm *sm)
1097 {
1098         if (sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED ||
1099             sm->suppPortStatus != Authorized)
1100                 return NULL;
1101
1102         return eap_sm_get_method_name(sm->eap);
1103 }
1104
1105
1106 #ifdef CONFIG_CTRL_IFACE
1107 /**
1108  * eapol_sm_get_status - Get EAPOL state machine status
1109  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1110  * @buf: Buffer for status information
1111  * @buflen: Maximum buffer length
1112  * @verbose: Whether to include verbose status information
1113  * Returns: Number of bytes written to buf.
1114  *
1115  * Query EAPOL state machine for status information. This function fills in a
1116  * text area with current status information from the EAPOL state machine. If
1117  * the buffer (buf) is not large enough, status information will be truncated
1118  * to fit the buffer.
1119  */
1120 int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
1121                         int verbose)
1122 {
1123         int len, ret;
1124         if (sm == NULL)
1125                 return 0;
1126
1127         len = os_snprintf(buf, buflen,
1128                           "Supplicant PAE state=%s\n"
1129                           "suppPortStatus=%s\n",
1130                           eapol_supp_pae_state(sm->SUPP_PAE_state),
1131                           eapol_port_status(sm->suppPortStatus));
1132         if (os_snprintf_error(buflen, len))
1133                 return 0;
1134
1135         if (verbose) {
1136                 ret = os_snprintf(buf + len, buflen - len,
1137                                   "heldPeriod=%u\n"
1138                                   "authPeriod=%u\n"
1139                                   "startPeriod=%u\n"
1140                                   "maxStart=%u\n"
1141                                   "portControl=%s\n"
1142                                   "Supplicant Backend state=%s\n",
1143                                   sm->heldPeriod,
1144                                   sm->authPeriod,
1145                                   sm->startPeriod,
1146                                   sm->maxStart,
1147                                   eapol_port_control(sm->portControl),
1148                                   eapol_supp_be_state(sm->SUPP_BE_state));
1149                 if (os_snprintf_error(buflen - len, ret))
1150                         return len;
1151                 len += ret;
1152         }
1153
1154 #ifdef CONFIG_EAP_PROXY
1155         if (sm->use_eap_proxy)
1156                 len += eap_proxy_sm_get_status(sm->eap_proxy,
1157                                                buf + len, buflen - len,
1158                                                verbose);
1159         else
1160 #endif /* CONFIG_EAP_PROXY */
1161         len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
1162
1163         return len;
1164 }
1165
1166
1167 /**
1168  * eapol_sm_get_mib - Get EAPOL state machine MIBs
1169  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1170  * @buf: Buffer for MIB information
1171  * @buflen: Maximum buffer length
1172  * Returns: Number of bytes written to buf.
1173  *
1174  * Query EAPOL state machine for MIB information. This function fills in a
1175  * text area with current MIB information from the EAPOL state machine. If
1176  * the buffer (buf) is not large enough, MIB information will be truncated to
1177  * fit the buffer.
1178  */
1179 int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen)
1180 {
1181         size_t len;
1182         int ret;
1183
1184         if (sm == NULL)
1185                 return 0;
1186         ret = os_snprintf(buf, buflen,
1187                           "dot1xSuppPaeState=%d\n"
1188                           "dot1xSuppHeldPeriod=%u\n"
1189                           "dot1xSuppAuthPeriod=%u\n"
1190                           "dot1xSuppStartPeriod=%u\n"
1191                           "dot1xSuppMaxStart=%u\n"
1192                           "dot1xSuppSuppControlledPortStatus=%s\n"
1193                           "dot1xSuppBackendPaeState=%d\n",
1194                           sm->SUPP_PAE_state,
1195                           sm->heldPeriod,
1196                           sm->authPeriod,
1197                           sm->startPeriod,
1198                           sm->maxStart,
1199                           sm->suppPortStatus == Authorized ?
1200                           "Authorized" : "Unauthorized",
1201                           sm->SUPP_BE_state);
1202
1203         if (os_snprintf_error(buflen, ret))
1204                 return 0;
1205         len = ret;
1206
1207         ret = os_snprintf(buf + len, buflen - len,
1208                           "dot1xSuppEapolFramesRx=%u\n"
1209                           "dot1xSuppEapolFramesTx=%u\n"
1210                           "dot1xSuppEapolStartFramesTx=%u\n"
1211                           "dot1xSuppEapolLogoffFramesTx=%u\n"
1212                           "dot1xSuppEapolRespFramesTx=%u\n"
1213                           "dot1xSuppEapolReqIdFramesRx=%u\n"
1214                           "dot1xSuppEapolReqFramesRx=%u\n"
1215                           "dot1xSuppInvalidEapolFramesRx=%u\n"
1216                           "dot1xSuppEapLengthErrorFramesRx=%u\n"
1217                           "dot1xSuppLastEapolFrameVersion=%u\n"
1218                           "dot1xSuppLastEapolFrameSource=" MACSTR "\n",
1219                           sm->dot1xSuppEapolFramesRx,
1220                           sm->dot1xSuppEapolFramesTx,
1221                           sm->dot1xSuppEapolStartFramesTx,
1222                           sm->dot1xSuppEapolLogoffFramesTx,
1223                           sm->dot1xSuppEapolRespFramesTx,
1224                           sm->dot1xSuppEapolReqIdFramesRx,
1225                           sm->dot1xSuppEapolReqFramesRx,
1226                           sm->dot1xSuppInvalidEapolFramesRx,
1227                           sm->dot1xSuppEapLengthErrorFramesRx,
1228                           sm->dot1xSuppLastEapolFrameVersion,
1229                           MAC2STR(sm->dot1xSuppLastEapolFrameSource));
1230
1231         if (os_snprintf_error(buflen - len, ret))
1232                 return len;
1233         len += ret;
1234
1235         return len;
1236 }
1237 #endif /* CONFIG_CTRL_IFACE */
1238
1239
1240 /**
1241  * eapol_sm_rx_eapol - Process received EAPOL frames
1242  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1243  * @src: Source MAC address of the EAPOL packet
1244  * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
1245  * @len: Length of the EAPOL frame
1246  * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine,
1247  * -1 failure
1248  */
1249 int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
1250                       size_t len)
1251 {
1252         const struct ieee802_1x_hdr *hdr;
1253         const struct ieee802_1x_eapol_key *key;
1254         int data_len;
1255         int res = 1;
1256         size_t plen;
1257
1258         if (sm == NULL)
1259                 return 0;
1260         sm->dot1xSuppEapolFramesRx++;
1261         if (len < sizeof(*hdr)) {
1262                 sm->dot1xSuppInvalidEapolFramesRx++;
1263                 return 0;
1264         }
1265         hdr = (const struct ieee802_1x_hdr *) buf;
1266         sm->dot1xSuppLastEapolFrameVersion = hdr->version;
1267         os_memcpy(sm->dot1xSuppLastEapolFrameSource, src, ETH_ALEN);
1268         if (hdr->version < EAPOL_VERSION) {
1269                 /* TODO: backwards compatibility */
1270         }
1271         plen = be_to_host16(hdr->length);
1272         if (plen > len - sizeof(*hdr)) {
1273                 sm->dot1xSuppEapLengthErrorFramesRx++;
1274                 return 0;
1275         }
1276 #ifdef CONFIG_WPS
1277         if (sm->conf.wps && sm->conf.workaround &&
1278             plen < len - sizeof(*hdr) &&
1279             hdr->type == IEEE802_1X_TYPE_EAP_PACKET &&
1280             len - sizeof(*hdr) > sizeof(struct eap_hdr)) {
1281                 const struct eap_hdr *ehdr =
1282                         (const struct eap_hdr *) (hdr + 1);
1283                 u16 elen;
1284
1285                 elen = be_to_host16(ehdr->length);
1286                 if (elen > plen && elen <= len - sizeof(*hdr)) {
1287                         /*
1288                          * Buffalo WHR-G125 Ver.1.47 seems to send EAP-WPS
1289                          * packets with too short EAPOL header length field
1290                          * (14 octets). This is fixed in firmware Ver.1.49.
1291                          * As a workaround, fix the EAPOL header based on the
1292                          * correct length in the EAP packet.
1293                          */
1294                         wpa_printf(MSG_DEBUG, "EAPOL: Workaround - fix EAPOL "
1295                                    "payload length based on EAP header: "
1296                                    "%d -> %d", (int) plen, elen);
1297                         plen = elen;
1298                 }
1299         }
1300 #endif /* CONFIG_WPS */
1301         data_len = plen + sizeof(*hdr);
1302
1303         switch (hdr->type) {
1304         case IEEE802_1X_TYPE_EAP_PACKET:
1305                 if (sm->conf.workaround) {
1306                         /*
1307                          * An AP has been reported to send out EAP message with
1308                          * undocumented code 10 at some point near the
1309                          * completion of EAP authentication. This can result in
1310                          * issues with the unexpected EAP message triggering
1311                          * restart of EAPOL authentication. Avoid this by
1312                          * skipping the message without advancing the state
1313                          * machine.
1314                          */
1315                         const struct eap_hdr *ehdr =
1316                                 (const struct eap_hdr *) (hdr + 1);
1317                         if (plen >= sizeof(*ehdr) && ehdr->code == 10) {
1318                                 wpa_printf(MSG_DEBUG, "EAPOL: Ignore EAP packet with unknown code 10");
1319                                 break;
1320                         }
1321                 }
1322
1323                 if (sm->cached_pmk) {
1324                         /* Trying to use PMKSA caching, but Authenticator did
1325                          * not seem to have a matching entry. Need to restart
1326                          * EAPOL state machines.
1327                          */
1328                         eapol_sm_abort_cached(sm);
1329                 }
1330                 wpabuf_free(sm->eapReqData);
1331                 sm->eapReqData = wpabuf_alloc_copy(hdr + 1, plen);
1332                 if (sm->eapReqData) {
1333                         wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet "
1334                                    "frame");
1335                         sm->eapolEap = TRUE;
1336 #ifdef CONFIG_EAP_PROXY
1337                         if (sm->use_eap_proxy) {
1338                                 eap_proxy_packet_update(
1339                                         sm->eap_proxy,
1340                                         wpabuf_mhead_u8(sm->eapReqData),
1341                                         wpabuf_len(sm->eapReqData));
1342                                 wpa_printf(MSG_DEBUG, "EAPOL: eap_proxy "
1343                                            "EAP Req updated");
1344                         }
1345 #endif /* CONFIG_EAP_PROXY */
1346                         eapol_sm_step(sm);
1347                 }
1348                 break;
1349         case IEEE802_1X_TYPE_EAPOL_KEY:
1350                 if (plen < sizeof(*key)) {
1351                         wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key "
1352                                    "frame received");
1353                         break;
1354                 }
1355                 key = (const struct ieee802_1x_eapol_key *) (hdr + 1);
1356                 if (key->type == EAPOL_KEY_TYPE_WPA ||
1357                     key->type == EAPOL_KEY_TYPE_RSN) {
1358                         /* WPA Supplicant takes care of this frame. */
1359                         wpa_printf(MSG_DEBUG, "EAPOL: Ignoring WPA EAPOL-Key "
1360                                    "frame in EAPOL state machines");
1361                         res = 0;
1362                         break;
1363                 }
1364                 if (key->type != EAPOL_KEY_TYPE_RC4) {
1365                         wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown "
1366                                    "EAPOL-Key type %d", key->type);
1367                         break;
1368                 }
1369                 os_free(sm->last_rx_key);
1370                 sm->last_rx_key = os_malloc(data_len);
1371                 if (sm->last_rx_key) {
1372                         wpa_printf(MSG_DEBUG, "EAPOL: Received EAPOL-Key "
1373                                    "frame");
1374                         os_memcpy(sm->last_rx_key, buf, data_len);
1375                         sm->last_rx_key_len = data_len;
1376                         sm->rxKey = TRUE;
1377                         eapol_sm_step(sm);
1378                 }
1379                 break;
1380 #ifdef CONFIG_MACSEC
1381         case IEEE802_1X_TYPE_EAPOL_MKA:
1382                 wpa_printf(MSG_EXCESSIVE,
1383                            "EAPOL type %d will be handled by MKA",
1384                            hdr->type);
1385                 break;
1386 #endif /* CONFIG_MACSEC */
1387         default:
1388                 wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d",
1389                            hdr->type);
1390                 sm->dot1xSuppInvalidEapolFramesRx++;
1391                 break;
1392         }
1393
1394         return res;
1395 }
1396
1397
1398 /**
1399  * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet
1400  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1401  *
1402  * Notify EAPOL state machine about transmitted EAPOL packet from an external
1403  * component, e.g., WPA. This will update the statistics.
1404  */
1405 void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
1406 {
1407         if (sm)
1408                 sm->dot1xSuppEapolFramesTx++;
1409 }
1410
1411
1412 /**
1413  * eapol_sm_notify_portEnabled - Notification about portEnabled change
1414  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1415  * @enabled: New portEnabled value
1416  *
1417  * Notify EAPOL state machine about new portEnabled value.
1418  */
1419 void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
1420 {
1421         if (sm == NULL)
1422                 return;
1423         wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1424                    "portEnabled=%d", enabled);
1425         if (sm->portEnabled != enabled)
1426                 sm->force_authorized_update = TRUE;
1427         sm->portEnabled = enabled;
1428         eapol_sm_step(sm);
1429 }
1430
1431
1432 /**
1433  * eapol_sm_notify_portValid - Notification about portValid change
1434  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1435  * @valid: New portValid value
1436  *
1437  * Notify EAPOL state machine about new portValid value.
1438  */
1439 void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
1440 {
1441         if (sm == NULL)
1442                 return;
1443         wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1444                    "portValid=%d", valid);
1445         sm->portValid = valid;
1446         eapol_sm_step(sm);
1447 }
1448
1449
1450 /**
1451  * eapol_sm_notify_eap_success - Notification of external EAP success trigger
1452  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1453  * @success: %TRUE = set success, %FALSE = clear success
1454  *
1455  * Notify the EAPOL state machine that external event has forced EAP state to
1456  * success (success = %TRUE). This can be cleared by setting success = %FALSE.
1457  *
1458  * This function is called to update EAP state when WPA-PSK key handshake has
1459  * been completed successfully since WPA-PSK does not use EAP state machine.
1460  */
1461 void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success)
1462 {
1463         if (sm == NULL)
1464                 return;
1465         wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1466                    "EAP success=%d", success);
1467         sm->eapSuccess = success;
1468         sm->altAccept = success;
1469         if (success)
1470                 eap_notify_success(sm->eap);
1471         eapol_sm_step(sm);
1472 }
1473
1474
1475 /**
1476  * eapol_sm_notify_eap_fail - Notification of external EAP failure trigger
1477  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1478  * @fail: %TRUE = set failure, %FALSE = clear failure
1479  *
1480  * Notify EAPOL state machine that external event has forced EAP state to
1481  * failure (fail = %TRUE). This can be cleared by setting fail = %FALSE.
1482  */
1483 void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
1484 {
1485         if (sm == NULL)
1486                 return;
1487         wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1488                    "EAP fail=%d", fail);
1489         sm->eapFail = fail;
1490         sm->altReject = fail;
1491         eapol_sm_step(sm);
1492 }
1493
1494
1495 /**
1496  * eapol_sm_notify_config - Notification of EAPOL configuration change
1497  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1498  * @config: Pointer to current network EAP configuration
1499  * @conf: Pointer to EAPOL configuration data
1500  *
1501  * Notify EAPOL state machine that configuration has changed. config will be
1502  * stored as a backpointer to network configuration. This can be %NULL to clear
1503  * the stored pointed. conf will be copied to local EAPOL/EAP configuration
1504  * data. If conf is %NULL, this part of the configuration change will be
1505  * skipped.
1506  */
1507 void eapol_sm_notify_config(struct eapol_sm *sm,
1508                             struct eap_peer_config *config,
1509                             const struct eapol_config *conf)
1510 {
1511         if (sm == NULL)
1512                 return;
1513
1514         sm->config = config;
1515 #ifdef CONFIG_EAP_PROXY
1516         sm->use_eap_proxy = eap_proxy_notify_config(sm->eap_proxy, config) > 0;
1517 #endif /* CONFIG_EAP_PROXY */
1518
1519         if (conf == NULL)
1520                 return;
1521
1522         sm->conf.accept_802_1x_keys = conf->accept_802_1x_keys;
1523         sm->conf.required_keys = conf->required_keys;
1524         sm->conf.fast_reauth = conf->fast_reauth;
1525         sm->conf.workaround = conf->workaround;
1526         sm->conf.wps = conf->wps;
1527 #ifdef CONFIG_EAP_PROXY
1528         if (sm->use_eap_proxy) {
1529                 /* Using EAP Proxy, so skip EAP state machine update */
1530                 return;
1531         }
1532 #endif /* CONFIG_EAP_PROXY */
1533         if (sm->eap) {
1534                 eap_set_fast_reauth(sm->eap, conf->fast_reauth);
1535                 eap_set_workaround(sm->eap, conf->workaround);
1536                 eap_set_force_disabled(sm->eap, conf->eap_disabled);
1537                 eap_set_external_sim(sm->eap, conf->external_sim);
1538         }
1539 }
1540
1541
1542 /**
1543  * eapol_sm_get_key - Get master session key (MSK) from EAP
1544  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1545  * @key: Pointer for key buffer
1546  * @len: Number of bytes to copy to key
1547  * Returns: 0 on success (len of key available), maximum available key len
1548  * (>0) if key is available but it is shorter than len, or -1 on failure.
1549  *
1550  * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key
1551  * is available only after a successful authentication.
1552  */
1553 int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
1554 {
1555         const u8 *eap_key;
1556         size_t eap_len;
1557
1558 #ifdef CONFIG_EAP_PROXY
1559         if (sm && sm->use_eap_proxy) {
1560                 /* Get key from EAP proxy */
1561                 if (sm == NULL || !eap_proxy_key_available(sm->eap_proxy)) {
1562                         wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
1563                         return -1;
1564                 }
1565                 eap_key = eap_proxy_get_eapKeyData(sm->eap_proxy, &eap_len);
1566                 if (eap_key == NULL) {
1567                         wpa_printf(MSG_DEBUG, "EAPOL: Failed to get "
1568                                    "eapKeyData");
1569                         return -1;
1570                 }
1571                 goto key_fetched;
1572         }
1573 #endif /* CONFIG_EAP_PROXY */
1574         if (sm == NULL || !eap_key_available(sm->eap)) {
1575                 wpa_printf(MSG_DEBUG, "EAPOL: EAP key not available");
1576                 return -1;
1577         }
1578         eap_key = eap_get_eapKeyData(sm->eap, &eap_len);
1579         if (eap_key == NULL) {
1580                 wpa_printf(MSG_DEBUG, "EAPOL: Failed to get eapKeyData");
1581                 return -1;
1582         }
1583 #ifdef CONFIG_EAP_PROXY
1584 key_fetched:
1585 #endif /* CONFIG_EAP_PROXY */
1586         if (len > eap_len) {
1587                 wpa_printf(MSG_DEBUG, "EAPOL: Requested key length (%lu) not "
1588                            "available (len=%lu)",
1589                            (unsigned long) len, (unsigned long) eap_len);
1590                 return eap_len;
1591         }
1592         os_memcpy(key, eap_key, len);
1593         wpa_printf(MSG_DEBUG, "EAPOL: Successfully fetched key (len=%lu)",
1594                    (unsigned long) len);
1595         return 0;
1596 }
1597
1598
1599 /**
1600  * eapol_sm_get_session_id - Get EAP Session-Id
1601  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1602  * @len: Pointer to variable that will be set to number of bytes in the session
1603  * Returns: Pointer to the EAP Session-Id or %NULL on failure
1604  *
1605  * The Session-Id is available only after a successful authentication.
1606  */
1607 const u8 * eapol_sm_get_session_id(struct eapol_sm *sm, size_t *len)
1608 {
1609         if (sm == NULL || !eap_key_available(sm->eap)) {
1610                 wpa_printf(MSG_DEBUG, "EAPOL: EAP Session-Id not available");
1611                 return NULL;
1612         }
1613         return eap_get_eapSessionId(sm->eap, len);
1614 }
1615
1616
1617 /**
1618  * eapol_sm_notify_logoff - Notification of logon/logoff commands
1619  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1620  * @logoff: Whether command was logoff
1621  *
1622  * Notify EAPOL state machines that user requested logon/logoff.
1623  */
1624 void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff)
1625 {
1626         if (sm) {
1627                 sm->userLogoff = logoff;
1628                 if (!logoff) {
1629                         /* If there is a delayed txStart queued, start now. */
1630                         sm->startWhen = 0;
1631                 }
1632                 eapol_sm_step(sm);
1633         }
1634 }
1635
1636
1637 /**
1638  * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching
1639  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1640  *
1641  * Notify EAPOL state machines that PMKSA caching was successful. This is used
1642  * to move EAPOL and EAP state machines into authenticated/successful state.
1643  */
1644 void eapol_sm_notify_cached(struct eapol_sm *sm)
1645 {
1646         if (sm == NULL)
1647                 return;
1648         wpa_printf(MSG_DEBUG, "EAPOL: PMKSA caching was used - skip EAPOL");
1649         sm->eapSuccess = TRUE;
1650         eap_notify_success(sm->eap);
1651         eapol_sm_step(sm);
1652 }
1653
1654
1655 /**
1656  * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching
1657  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1658  *
1659  * Notify EAPOL state machines if PMKSA caching is used.
1660  */
1661 void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm)
1662 {
1663         if (sm == NULL)
1664                 return;
1665         wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA");
1666         sm->cached_pmk = TRUE;
1667 }
1668
1669
1670 static void eapol_sm_abort_cached(struct eapol_sm *sm)
1671 {
1672         wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, "
1673                    "doing full EAP authentication");
1674         if (sm == NULL)
1675                 return;
1676         sm->cached_pmk = FALSE;
1677         sm->SUPP_PAE_state = SUPP_PAE_CONNECTING;
1678         eapol_sm_set_port_unauthorized(sm);
1679
1680         /* Make sure we do not start sending EAPOL-Start frames first, but
1681          * instead move to RESTART state to start EAPOL authentication. */
1682         sm->startWhen = 3;
1683         eapol_enable_timer_tick(sm);
1684
1685         if (sm->ctx->aborted_cached)
1686                 sm->ctx->aborted_cached(sm->ctx->ctx);
1687 }
1688
1689
1690 /**
1691  * eapol_sm_register_scard_ctx - Notification of smart card context
1692  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1693  * @ctx: Context data for smart card operations
1694  *
1695  * Notify EAPOL state machines of context data for smart card operations. This
1696  * context data will be used as a parameter for scard_*() functions.
1697  */
1698 void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx)
1699 {
1700         if (sm) {
1701                 sm->ctx->scard_ctx = ctx;
1702                 eap_register_scard_ctx(sm->eap, ctx);
1703         }
1704 }
1705
1706
1707 /**
1708  * eapol_sm_notify_portControl - Notification of portControl changes
1709  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1710  * @portControl: New value for portControl variable
1711  *
1712  * Notify EAPOL state machines that portControl variable has changed.
1713  */
1714 void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl)
1715 {
1716         if (sm == NULL)
1717                 return;
1718         wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
1719                    "portControl=%s", eapol_port_control(portControl));
1720         sm->portControl = portControl;
1721         eapol_sm_step(sm);
1722 }
1723
1724
1725 /**
1726  * eapol_sm_notify_ctrl_attached - Notification of attached monitor
1727  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1728  *
1729  * Notify EAPOL state machines that a monitor was attached to the control
1730  * interface to trigger re-sending of pending requests for user input.
1731  */
1732 void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm)
1733 {
1734         if (sm == NULL)
1735                 return;
1736         eap_sm_notify_ctrl_attached(sm->eap);
1737 }
1738
1739
1740 /**
1741  * eapol_sm_notify_ctrl_response - Notification of received user input
1742  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1743  *
1744  * Notify EAPOL state machines that a control response, i.e., user
1745  * input, was received in order to trigger retrying of a pending EAP request.
1746  */
1747 void eapol_sm_notify_ctrl_response(struct eapol_sm *sm)
1748 {
1749         if (sm == NULL)
1750                 return;
1751         if (sm->eapReqData && !sm->eapReq) {
1752                 wpa_printf(MSG_DEBUG, "EAPOL: received control response (user "
1753                            "input) notification - retrying pending EAP "
1754                            "Request");
1755                 sm->eapolEap = TRUE;
1756                 sm->eapReq = TRUE;
1757                 eapol_sm_step(sm);
1758         }
1759 }
1760
1761
1762 /**
1763  * eapol_sm_request_reauth - Request reauthentication
1764  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1765  *
1766  * This function can be used to request EAPOL reauthentication, e.g., when the
1767  * current PMKSA entry is nearing expiration.
1768  */
1769 void eapol_sm_request_reauth(struct eapol_sm *sm)
1770 {
1771         if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED)
1772                 return;
1773         eapol_sm_txStart(sm);
1774 }
1775
1776
1777 /**
1778  * eapol_sm_notify_lower_layer_success - Notification of lower layer success
1779  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1780  * @in_eapol_sm: Whether the caller is already running inside EAPOL state
1781  * machine loop (eapol_sm_step())
1782  *
1783  * Notify EAPOL (and EAP) state machines that a lower layer has detected a
1784  * successful authentication. This is used to recover from dropped EAP-Success
1785  * messages.
1786  */
1787 void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm)
1788 {
1789         if (sm == NULL)
1790                 return;
1791         eap_notify_lower_layer_success(sm->eap);
1792         if (!in_eapol_sm)
1793                 eapol_sm_step(sm);
1794 }
1795
1796
1797 /**
1798  * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid
1799  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
1800  */
1801 void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
1802 {
1803         if (sm)
1804                 eap_invalidate_cached_session(sm->eap);
1805 }
1806
1807
1808 static struct eap_peer_config * eapol_sm_get_config(void *ctx)
1809 {
1810         struct eapol_sm *sm = ctx;
1811         return sm ? sm->config : NULL;
1812 }
1813
1814
1815 static struct wpabuf * eapol_sm_get_eapReqData(void *ctx)
1816 {
1817         struct eapol_sm *sm = ctx;
1818         if (sm == NULL || sm->eapReqData == NULL)
1819                 return NULL;
1820
1821         return sm->eapReqData;
1822 }
1823
1824
1825 static Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable)
1826 {
1827         struct eapol_sm *sm = ctx;
1828         if (sm == NULL)
1829                 return FALSE;
1830         switch (variable) {
1831         case EAPOL_eapSuccess:
1832                 return sm->eapSuccess;
1833         case EAPOL_eapRestart:
1834                 return sm->eapRestart;
1835         case EAPOL_eapFail:
1836                 return sm->eapFail;
1837         case EAPOL_eapResp:
1838                 return sm->eapResp;
1839         case EAPOL_eapNoResp:
1840                 return sm->eapNoResp;
1841         case EAPOL_eapReq:
1842                 return sm->eapReq;
1843         case EAPOL_portEnabled:
1844                 return sm->portEnabled;
1845         case EAPOL_altAccept:
1846                 return sm->altAccept;
1847         case EAPOL_altReject:
1848                 return sm->altReject;
1849         case EAPOL_eapTriggerStart:
1850                 return sm->eapTriggerStart;
1851         }
1852         return FALSE;
1853 }
1854
1855
1856 static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable,
1857                               Boolean value)
1858 {
1859         struct eapol_sm *sm = ctx;
1860         if (sm == NULL)
1861                 return;
1862         switch (variable) {
1863         case EAPOL_eapSuccess:
1864                 sm->eapSuccess = value;
1865                 break;
1866         case EAPOL_eapRestart:
1867                 sm->eapRestart = value;
1868                 break;
1869         case EAPOL_eapFail:
1870                 sm->eapFail = value;
1871                 break;
1872         case EAPOL_eapResp:
1873                 sm->eapResp = value;
1874                 break;
1875         case EAPOL_eapNoResp:
1876                 sm->eapNoResp = value;
1877                 break;
1878         case EAPOL_eapReq:
1879                 sm->eapReq = value;
1880                 break;
1881         case EAPOL_portEnabled:
1882                 sm->portEnabled = value;
1883                 break;
1884         case EAPOL_altAccept:
1885                 sm->altAccept = value;
1886                 break;
1887         case EAPOL_altReject:
1888                 sm->altReject = value;
1889                 break;
1890         case EAPOL_eapTriggerStart:
1891                 sm->eapTriggerStart = value;
1892                 break;
1893         }
1894 }
1895
1896
1897 static unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable)
1898 {
1899         struct eapol_sm *sm = ctx;
1900         if (sm == NULL)
1901                 return 0;
1902         switch (variable) {
1903         case EAPOL_idleWhile:
1904                 return sm->idleWhile;
1905         }
1906         return 0;
1907 }
1908
1909
1910 static void eapol_sm_set_int(void *ctx, enum eapol_int_var variable,
1911                              unsigned int value)
1912 {
1913         struct eapol_sm *sm = ctx;
1914         if (sm == NULL)
1915                 return;
1916         switch (variable) {
1917         case EAPOL_idleWhile:
1918                 sm->idleWhile = value;
1919                 if (sm->idleWhile > 0)
1920                         eapol_enable_timer_tick(sm);
1921                 break;
1922         }
1923 }
1924
1925
1926 static void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob)
1927 {
1928 #ifndef CONFIG_NO_CONFIG_BLOBS
1929         struct eapol_sm *sm = ctx;
1930         if (sm && sm->ctx && sm->ctx->set_config_blob)
1931                 sm->ctx->set_config_blob(sm->ctx->ctx, blob);
1932 #endif /* CONFIG_NO_CONFIG_BLOBS */
1933 }
1934
1935
1936 static const struct wpa_config_blob *
1937 eapol_sm_get_config_blob(void *ctx, const char *name)
1938 {
1939 #ifndef CONFIG_NO_CONFIG_BLOBS
1940         struct eapol_sm *sm = ctx;
1941         if (sm && sm->ctx && sm->ctx->get_config_blob)
1942                 return sm->ctx->get_config_blob(sm->ctx->ctx, name);
1943         else
1944                 return NULL;
1945 #else /* CONFIG_NO_CONFIG_BLOBS */
1946         return NULL;
1947 #endif /* CONFIG_NO_CONFIG_BLOBS */
1948 }
1949
1950
1951 static void eapol_sm_notify_pending(void *ctx)
1952 {
1953         struct eapol_sm *sm = ctx;
1954         if (sm == NULL)
1955                 return;
1956         if (sm->eapReqData && !sm->eapReq) {
1957                 wpa_printf(MSG_DEBUG, "EAPOL: received notification from EAP "
1958                            "state machine - retrying pending EAP Request");
1959                 sm->eapolEap = TRUE;
1960                 sm->eapReq = TRUE;
1961                 eapol_sm_step(sm);
1962         }
1963 }
1964
1965
1966 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
1967 static void eapol_sm_eap_param_needed(void *ctx, enum wpa_ctrl_req_type field,
1968                                       const char *txt)
1969 {
1970         struct eapol_sm *sm = ctx;
1971         wpa_printf(MSG_DEBUG, "EAPOL: EAP parameter needed");
1972         if (sm->ctx->eap_param_needed)
1973                 sm->ctx->eap_param_needed(sm->ctx->ctx, field, txt);
1974 }
1975 #else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1976 #define eapol_sm_eap_param_needed NULL
1977 #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
1978
1979 static void eapol_sm_notify_cert(void *ctx, int depth, const char *subject,
1980                                  const char *altsubject[],
1981                                  int num_altsubject, const char *cert_hash,
1982                                  const struct wpabuf *cert)
1983 {
1984         struct eapol_sm *sm = ctx;
1985         if (sm->ctx->cert_cb)
1986                 sm->ctx->cert_cb(sm->ctx->ctx, depth, subject, altsubject,
1987                                  num_altsubject, cert_hash, cert);
1988 }
1989
1990
1991 static void eapol_sm_notify_status(void *ctx, const char *status,
1992                                    const char *parameter)
1993 {
1994         struct eapol_sm *sm = ctx;
1995
1996         if (sm->ctx->status_cb)
1997                 sm->ctx->status_cb(sm->ctx->ctx, status, parameter);
1998 }
1999
2000
2001 #ifdef CONFIG_EAP_PROXY
2002 static void eapol_sm_eap_proxy_cb(void *ctx)
2003 {
2004         struct eapol_sm *sm = ctx;
2005
2006         if (sm->ctx->eap_proxy_cb)
2007                 sm->ctx->eap_proxy_cb(sm->ctx->ctx);
2008 }
2009 #endif /* CONFIG_EAP_PROXY */
2010
2011
2012 static void eapol_sm_set_anon_id(void *ctx, const u8 *id, size_t len)
2013 {
2014         struct eapol_sm *sm = ctx;
2015
2016         if (sm->ctx->set_anon_id)
2017                 sm->ctx->set_anon_id(sm->ctx->ctx, id, len);
2018 }
2019
2020
2021 static const struct eapol_callbacks eapol_cb =
2022 {
2023         eapol_sm_get_config,
2024         eapol_sm_get_bool,
2025         eapol_sm_set_bool,
2026         eapol_sm_get_int,
2027         eapol_sm_set_int,
2028         eapol_sm_get_eapReqData,
2029         eapol_sm_set_config_blob,
2030         eapol_sm_get_config_blob,
2031         eapol_sm_notify_pending,
2032         eapol_sm_eap_param_needed,
2033         eapol_sm_notify_cert,
2034         eapol_sm_notify_status,
2035 #ifdef CONFIG_EAP_PROXY
2036         eapol_sm_eap_proxy_cb,
2037 #endif /* CONFIG_EAP_PROXY */
2038         eapol_sm_set_anon_id
2039 };
2040
2041
2042 /**
2043  * eapol_sm_init - Initialize EAPOL state machine
2044  * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer
2045  * and EAPOL state machine will free it in eapol_sm_deinit()
2046  * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure
2047  *
2048  * Allocate and initialize an EAPOL state machine.
2049  */
2050 struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
2051 {
2052         struct eapol_sm *sm;
2053         struct eap_config conf;
2054         sm = os_zalloc(sizeof(*sm));
2055         if (sm == NULL)
2056                 return NULL;
2057         sm->ctx = ctx;
2058
2059         sm->portControl = Auto;
2060
2061         /* Supplicant PAE state machine */
2062         sm->heldPeriod = 60;
2063         sm->startPeriod = 30;
2064         sm->maxStart = 3;
2065
2066         /* Supplicant Backend state machine */
2067         sm->authPeriod = 30;
2068
2069         os_memset(&conf, 0, sizeof(conf));
2070         conf.opensc_engine_path = ctx->opensc_engine_path;
2071         conf.pkcs11_engine_path = ctx->pkcs11_engine_path;
2072         conf.pkcs11_module_path = ctx->pkcs11_module_path;
2073         conf.openssl_ciphers = ctx->openssl_ciphers;
2074         conf.wps = ctx->wps;
2075         conf.cert_in_cb = ctx->cert_in_cb;
2076
2077         sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf);
2078         if (sm->eap == NULL) {
2079                 os_free(sm);
2080                 return NULL;
2081         }
2082
2083 #ifdef CONFIG_EAP_PROXY
2084         sm->use_eap_proxy = FALSE;
2085         sm->eap_proxy = eap_proxy_init(sm, &eapol_cb, sm->ctx->msg_ctx);
2086         if (sm->eap_proxy == NULL) {
2087                 wpa_printf(MSG_ERROR, "Unable to initialize EAP Proxy");
2088         }
2089 #endif /* CONFIG_EAP_PROXY */
2090
2091         /* Initialize EAPOL state machines */
2092         sm->force_authorized_update = TRUE;
2093         sm->initialize = TRUE;
2094         eapol_sm_step(sm);
2095         sm->initialize = FALSE;
2096         eapol_sm_step(sm);
2097
2098         sm->timer_tick_enabled = 1;
2099         eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
2100
2101         return sm;
2102 }
2103
2104
2105 /**
2106  * eapol_sm_deinit - Deinitialize EAPOL state machine
2107  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
2108  *
2109  * Deinitialize and free EAPOL state machine.
2110  */
2111 void eapol_sm_deinit(struct eapol_sm *sm)
2112 {
2113         if (sm == NULL)
2114                 return;
2115         eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
2116         eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
2117         eap_peer_sm_deinit(sm->eap);
2118 #ifdef CONFIG_EAP_PROXY
2119         eap_proxy_deinit(sm->eap_proxy);
2120 #endif /* CONFIG_EAP_PROXY */
2121         os_free(sm->last_rx_key);
2122         wpabuf_free(sm->eapReqData);
2123         os_free(sm->ctx);
2124         os_free(sm);
2125 }
2126
2127
2128 void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm,
2129                              struct ext_password_data *ext)
2130 {
2131         if (sm && sm->eap)
2132                 eap_sm_set_ext_pw_ctx(sm->eap, ext);
2133 }
2134
2135
2136 int eapol_sm_failed(struct eapol_sm *sm)
2137 {
2138         if (sm == NULL)
2139                 return 0;
2140         return !sm->eapSuccess && sm->eapFail;
2141 }
2142
2143
2144 int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len)
2145 {
2146 #ifdef CONFIG_EAP_PROXY
2147         if (sm->eap_proxy == NULL)
2148                 return -1;
2149         return eap_proxy_get_imsi(sm->eap_proxy, imsi, len);
2150 #else /* CONFIG_EAP_PROXY */
2151         return -1;
2152 #endif /* CONFIG_EAP_PROXY */
2153 }
2154
2155
2156 void eapol_sm_erp_flush(struct eapol_sm *sm)
2157 {
2158         if (sm)
2159                 eap_peer_erp_free_keys(sm->eap);
2160 }