eapol_supp_sm.c 56 KB

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