ieee802_1x_cp.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744
  1. /*
  2. * IEEE 802.1X-2010 Controlled Port of PAE state machine - CP state machine
  3. * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "common/defs.h"
  12. #include "common/ieee802_1x_defs.h"
  13. #include "utils/state_machine.h"
  14. #include "ieee802_1x_kay.h"
  15. #include "ieee802_1x_secy_ops.h"
  16. #include "pae/ieee802_1x_cp.h"
  17. #define STATE_MACHINE_DATA struct ieee802_1x_cp_sm
  18. #define STATE_MACHINE_DEBUG_PREFIX "CP"
  19. static u8 default_cs_id[] = CS_ID_GCM_AES_128;
  20. /* The variable defined in clause 12 in IEEE Std 802.1X-2010 */
  21. enum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE };
  22. struct ieee802_1x_cp_sm {
  23. enum cp_states {
  24. CP_BEGIN, CP_INIT, CP_CHANGE, CP_ALLOWED, CP_AUTHENTICATED,
  25. CP_SECURED, CP_RECEIVE, CP_RECEIVING, CP_READY, CP_TRANSMIT,
  26. CP_TRANSMITTING, CP_ABANDON, CP_RETIRE
  27. } CP_state;
  28. Boolean changed;
  29. /* CP -> Client */
  30. Boolean port_valid;
  31. /* Logon -> CP */
  32. enum connect_type connect;
  33. u8 *authorization_data;
  34. /* KaY -> CP */
  35. Boolean chgd_server; /* clear by CP */
  36. Boolean elected_self;
  37. u8 *authorization_data1;
  38. enum confidentiality_offset cipher_offset;
  39. u8 *cipher_suite;
  40. Boolean new_sak; /* clear by CP */
  41. struct ieee802_1x_mka_ki distributed_ki;
  42. u8 distributed_an;
  43. Boolean using_receive_sas;
  44. Boolean all_receiving;
  45. Boolean server_transmitting;
  46. Boolean using_transmit_sa;
  47. /* CP -> KaY */
  48. struct ieee802_1x_mka_ki *lki;
  49. u8 lan;
  50. Boolean ltx;
  51. Boolean lrx;
  52. struct ieee802_1x_mka_ki *oki;
  53. u8 oan;
  54. Boolean otx;
  55. Boolean orx;
  56. /* CP -> SecY */
  57. Boolean protect_frames;
  58. enum validate_frames validate_frames;
  59. Boolean replay_protect;
  60. u32 replay_window;
  61. u8 *current_cipher_suite;
  62. enum confidentiality_offset confidentiality_offset;
  63. Boolean controlled_port_enabled;
  64. /* SecY -> CP */
  65. Boolean port_enabled; /* SecY->CP */
  66. /* private */
  67. u32 transmit_when;
  68. u32 transmit_delay;
  69. u32 retire_when;
  70. u32 retire_delay;
  71. /* not defined IEEE Std 802.1X-2010 */
  72. struct ieee802_1x_kay *kay;
  73. };
  74. static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
  75. void *timeout_ctx);
  76. static void ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx,
  77. void *timeout_ctx);
  78. static int changed_cipher(struct ieee802_1x_cp_sm *sm)
  79. {
  80. return sm->confidentiality_offset != sm->cipher_offset ||
  81. os_memcmp(sm->current_cipher_suite, sm->cipher_suite,
  82. CS_ID_LEN) != 0;
  83. }
  84. static int changed_connect(struct ieee802_1x_cp_sm *sm)
  85. {
  86. return sm->connect != SECURE || sm->chgd_server || changed_cipher(sm);
  87. }
  88. SM_STATE(CP, INIT)
  89. {
  90. SM_ENTRY(CP, INIT);
  91. sm->controlled_port_enabled = FALSE;
  92. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  93. sm->port_valid = FALSE;
  94. os_free(sm->lki);
  95. sm->lki = NULL;
  96. sm->ltx = FALSE;
  97. sm->lrx = FALSE;
  98. os_free(sm->oki);
  99. sm->oki = NULL;
  100. sm->otx = FALSE;
  101. sm->orx = FALSE;
  102. sm->port_enabled = TRUE;
  103. sm->chgd_server = FALSE;
  104. }
  105. SM_STATE(CP, CHANGE)
  106. {
  107. SM_ENTRY(CP, CHANGE);
  108. sm->port_valid = FALSE;
  109. sm->controlled_port_enabled = FALSE;
  110. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  111. if (sm->lki)
  112. ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
  113. if (sm->oki)
  114. ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
  115. }
  116. SM_STATE(CP, ALLOWED)
  117. {
  118. SM_ENTRY(CP, ALLOWED);
  119. sm->protect_frames = FALSE;
  120. sm->replay_protect = FALSE;
  121. sm->validate_frames = Checked;
  122. sm->port_valid = FALSE;
  123. sm->controlled_port_enabled = TRUE;
  124. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  125. secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
  126. secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
  127. secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
  128. }
  129. SM_STATE(CP, AUTHENTICATED)
  130. {
  131. SM_ENTRY(CP, AUTHENTICATED);
  132. sm->protect_frames = FALSE;
  133. sm->replay_protect = FALSE;
  134. sm->validate_frames = Checked;
  135. sm->port_valid = FALSE;
  136. sm->controlled_port_enabled = TRUE;
  137. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  138. secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
  139. secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
  140. secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
  141. }
  142. SM_STATE(CP, SECURED)
  143. {
  144. struct ieee802_1x_cp_conf conf;
  145. SM_ENTRY(CP, SECURED);
  146. sm->chgd_server = FALSE;
  147. ieee802_1x_kay_cp_conf(sm->kay, &conf);
  148. sm->protect_frames = conf.protect;
  149. sm->replay_protect = conf.replay_protect;
  150. sm->validate_frames = conf.validate;
  151. /* NOTE: now no other than default cipher suiter(AES-GCM-128) */
  152. os_memcpy(sm->current_cipher_suite, sm->cipher_suite, CS_ID_LEN);
  153. secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite,
  154. CS_ID_LEN);
  155. sm->confidentiality_offset = sm->cipher_offset;
  156. sm->port_valid = TRUE;
  157. secy_cp_control_confidentiality_offset(sm->kay,
  158. sm->confidentiality_offset);
  159. secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
  160. secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
  161. secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
  162. }
  163. SM_STATE(CP, RECEIVE)
  164. {
  165. SM_ENTRY(CP, RECEIVE);
  166. /* RECEIVE state machine not keep with Figure 12-2 in
  167. * IEEE Std 802.1X-2010 */
  168. sm->oki = sm->lki;
  169. sm->oan = sm->lan;
  170. sm->otx = sm->ltx;
  171. sm->orx = sm->lrx;
  172. ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
  173. sm->otx, sm->orx);
  174. sm->lki = os_malloc(sizeof(*sm->lki));
  175. if (!sm->lki) {
  176. wpa_printf(MSG_ERROR, "CP-%s: Out of memory", __func__);
  177. return;
  178. }
  179. os_memcpy(sm->lki, &sm->distributed_ki, sizeof(*sm->lki));
  180. sm->lan = sm->distributed_an;
  181. sm->ltx = FALSE;
  182. sm->lrx = FALSE;
  183. ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
  184. sm->ltx, sm->lrx);
  185. ieee802_1x_kay_create_sas(sm->kay, sm->lki);
  186. ieee802_1x_kay_enable_rx_sas(sm->kay, sm->lki);
  187. sm->new_sak = FALSE;
  188. sm->all_receiving = FALSE;
  189. }
  190. SM_STATE(CP, RECEIVING)
  191. {
  192. SM_ENTRY(CP, RECEIVING);
  193. sm->lrx = TRUE;
  194. ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
  195. sm->ltx, sm->lrx);
  196. sm->transmit_when = sm->transmit_delay;
  197. eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
  198. eloop_register_timeout(sm->transmit_when / 1000, 0,
  199. ieee802_1x_cp_transmit_when_timeout, sm, NULL);
  200. /* the electedSelf have been set before CP entering to RECEIVING
  201. * but the CP will transmit from RECEIVING to READY under
  202. * the !electedSelf when KaY is not key server */
  203. ieee802_1x_cp_sm_step(sm);
  204. sm->using_receive_sas = FALSE;
  205. sm->server_transmitting = FALSE;
  206. }
  207. SM_STATE(CP, READY)
  208. {
  209. SM_ENTRY(CP, READY);
  210. ieee802_1x_kay_enable_new_info(sm->kay);
  211. }
  212. SM_STATE(CP, TRANSMIT)
  213. {
  214. SM_ENTRY(CP, TRANSMIT);
  215. sm->controlled_port_enabled = TRUE;
  216. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  217. sm->ltx = TRUE;
  218. ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
  219. sm->ltx, sm->lrx);
  220. ieee802_1x_kay_enable_tx_sas(sm->kay, sm->lki);
  221. sm->all_receiving = FALSE;
  222. sm->server_transmitting = FALSE;
  223. }
  224. SM_STATE(CP, TRANSMITTING)
  225. {
  226. SM_ENTRY(CP, TRANSMITTING);
  227. sm->retire_when = sm->orx ? sm->retire_delay : 0;
  228. sm->otx = FALSE;
  229. ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
  230. sm->otx, sm->orx);
  231. ieee802_1x_kay_enable_new_info(sm->kay);
  232. eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
  233. eloop_register_timeout(sm->retire_when / 1000, 0,
  234. ieee802_1x_cp_retire_when_timeout, sm, NULL);
  235. sm->using_transmit_sa = FALSE;
  236. }
  237. SM_STATE(CP, ABANDON)
  238. {
  239. SM_ENTRY(CP, ABANDON);
  240. sm->lrx = FALSE;
  241. ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
  242. sm->ltx, sm->lrx);
  243. ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
  244. os_free(sm->lki);
  245. sm->lki = NULL;
  246. ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
  247. sm->ltx, sm->lrx);
  248. sm->new_sak = FALSE;
  249. }
  250. SM_STATE(CP, RETIRE)
  251. {
  252. SM_ENTRY(CP, RETIRE);
  253. /* RETIRE state machine not keep with Figure 12-2 in
  254. * IEEE Std 802.1X-2010 */
  255. os_free(sm->oki);
  256. sm->oki = NULL;
  257. sm->orx = FALSE;
  258. sm->otx = FALSE;
  259. ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
  260. sm->otx, sm->orx);
  261. }
  262. /**
  263. * CP state machine handler entry
  264. */
  265. SM_STEP(CP)
  266. {
  267. if (!sm->port_enabled)
  268. SM_ENTER(CP, INIT);
  269. switch (sm->CP_state) {
  270. case CP_BEGIN:
  271. SM_ENTER(CP, INIT);
  272. break;
  273. case CP_INIT:
  274. SM_ENTER(CP, CHANGE);
  275. break;
  276. case CP_CHANGE:
  277. if (sm->connect == UNAUTHENTICATED)
  278. SM_ENTER(CP, ALLOWED);
  279. else if (sm->connect == AUTHENTICATED)
  280. SM_ENTER(CP, AUTHENTICATED);
  281. else if (sm->connect == SECURE)
  282. SM_ENTER(CP, SECURED);
  283. break;
  284. case CP_ALLOWED:
  285. if (sm->connect != UNAUTHENTICATED)
  286. SM_ENTER(CP, CHANGE);
  287. break;
  288. case CP_AUTHENTICATED:
  289. if (sm->connect != AUTHENTICATED)
  290. SM_ENTER(CP, CHANGE);
  291. break;
  292. case CP_SECURED:
  293. if (changed_connect(sm))
  294. SM_ENTER(CP, CHANGE);
  295. else if (sm->new_sak)
  296. SM_ENTER(CP, RECEIVE);
  297. break;
  298. case CP_RECEIVE:
  299. if (sm->using_receive_sas)
  300. SM_ENTER(CP, RECEIVING);
  301. break;
  302. case CP_RECEIVING:
  303. if (sm->new_sak || changed_connect(sm))
  304. SM_ENTER(CP, ABANDON);
  305. if (!sm->elected_self)
  306. SM_ENTER(CP, READY);
  307. if (sm->elected_self &&
  308. (sm->all_receiving || !sm->transmit_when))
  309. SM_ENTER(CP, TRANSMIT);
  310. break;
  311. case CP_TRANSMIT:
  312. if (sm->using_transmit_sa)
  313. SM_ENTER(CP, TRANSMITTING);
  314. break;
  315. case CP_TRANSMITTING:
  316. if (!sm->retire_when || changed_connect(sm))
  317. SM_ENTER(CP, RETIRE);
  318. break;
  319. case CP_RETIRE:
  320. if (changed_connect(sm))
  321. SM_ENTER(CP, CHANGE);
  322. else if (sm->new_sak)
  323. SM_ENTER(CP, RECEIVE);
  324. break;
  325. case CP_READY:
  326. if (sm->new_sak || changed_connect(sm))
  327. SM_ENTER(CP, RECEIVE);
  328. if (sm->server_transmitting)
  329. SM_ENTER(CP, TRANSMIT);
  330. break;
  331. case CP_ABANDON:
  332. if (changed_connect(sm))
  333. SM_ENTER(CP, RETIRE);
  334. else if (sm->new_sak)
  335. SM_ENTER(CP, RECEIVE);
  336. break;
  337. default:
  338. wpa_printf(MSG_ERROR, "CP: the state machine is not defined");
  339. break;
  340. }
  341. }
  342. /**
  343. * ieee802_1x_cp_sm_init -
  344. */
  345. struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(
  346. struct ieee802_1x_kay *kay,
  347. struct ieee802_1x_cp_conf *pcp_conf)
  348. {
  349. struct ieee802_1x_cp_sm *sm;
  350. sm = os_zalloc(sizeof(*sm));
  351. if (sm == NULL) {
  352. wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
  353. return NULL;
  354. }
  355. sm->kay = kay;
  356. sm->port_valid = FALSE;
  357. sm->chgd_server = FALSE;
  358. sm->protect_frames = pcp_conf->protect;
  359. sm->validate_frames = pcp_conf->validate;
  360. sm->replay_protect = pcp_conf->replay_protect;
  361. sm->replay_window = pcp_conf->replay_window;
  362. sm->controlled_port_enabled = FALSE;
  363. sm->lki = NULL;
  364. sm->lrx = FALSE;
  365. sm->ltx = FALSE;
  366. sm->oki = NULL;
  367. sm->orx = FALSE;
  368. sm->otx = FALSE;
  369. sm->cipher_suite = os_zalloc(CS_ID_LEN);
  370. sm->current_cipher_suite = os_zalloc(CS_ID_LEN);
  371. if (!sm->cipher_suite || !sm->current_cipher_suite) {
  372. wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
  373. os_free(sm->cipher_suite);
  374. os_free(sm->current_cipher_suite);
  375. os_free(sm);
  376. return NULL;
  377. }
  378. os_memcpy(sm->current_cipher_suite, default_cs_id, CS_ID_LEN);
  379. os_memcpy(sm->cipher_suite, default_cs_id, CS_ID_LEN);
  380. sm->cipher_offset = CONFIDENTIALITY_OFFSET_0;
  381. sm->confidentiality_offset = sm->cipher_offset;
  382. sm->transmit_delay = MKA_LIFE_TIME;
  383. sm->retire_delay = MKA_SAK_RETIRE_TIME;
  384. sm->CP_state = CP_BEGIN;
  385. sm->changed = FALSE;
  386. sm->authorization_data = NULL;
  387. wpa_printf(MSG_DEBUG, "CP: state machine created");
  388. secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
  389. secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
  390. secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
  391. secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
  392. secy_cp_control_confidentiality_offset(sm->kay,
  393. sm->confidentiality_offset);
  394. SM_ENTER(CP, INIT);
  395. SM_STEP_RUN(CP);
  396. return sm;
  397. }
  398. static void ieee802_1x_cp_step_run(struct ieee802_1x_cp_sm *sm)
  399. {
  400. enum cp_states prev_state;
  401. int i;
  402. for (i = 0; i < 100; i++) {
  403. prev_state = sm->CP_state;
  404. SM_STEP_RUN(CP);
  405. if (prev_state == sm->CP_state)
  406. break;
  407. }
  408. }
  409. static void ieee802_1x_cp_step_cb(void *eloop_ctx, void *timeout_ctx)
  410. {
  411. struct ieee802_1x_cp_sm *sm = eloop_ctx;
  412. ieee802_1x_cp_step_run(sm);
  413. }
  414. /**
  415. * ieee802_1x_cp_sm_deinit -
  416. */
  417. void ieee802_1x_cp_sm_deinit(struct ieee802_1x_cp_sm *sm)
  418. {
  419. wpa_printf(MSG_DEBUG, "CP: state machine removed");
  420. if (!sm)
  421. return;
  422. eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
  423. eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
  424. eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
  425. os_free(sm->lki);
  426. os_free(sm->oki);
  427. os_free(sm->cipher_suite);
  428. os_free(sm->current_cipher_suite);
  429. os_free(sm->authorization_data);
  430. os_free(sm);
  431. }
  432. /**
  433. * ieee802_1x_cp_connect_pending
  434. */
  435. void ieee802_1x_cp_connect_pending(void *cp_ctx)
  436. {
  437. struct ieee802_1x_cp_sm *sm = cp_ctx;
  438. sm->connect = PENDING;
  439. }
  440. /**
  441. * ieee802_1x_cp_connect_unauthenticated
  442. */
  443. void ieee802_1x_cp_connect_unauthenticated(void *cp_ctx)
  444. {
  445. struct ieee802_1x_cp_sm *sm = (struct ieee802_1x_cp_sm *)cp_ctx;
  446. sm->connect = UNAUTHENTICATED;
  447. }
  448. /**
  449. * ieee802_1x_cp_connect_authenticated
  450. */
  451. void ieee802_1x_cp_connect_authenticated(void *cp_ctx)
  452. {
  453. struct ieee802_1x_cp_sm *sm = cp_ctx;
  454. sm->connect = AUTHENTICATED;
  455. }
  456. /**
  457. * ieee802_1x_cp_connect_secure
  458. */
  459. void ieee802_1x_cp_connect_secure(void *cp_ctx)
  460. {
  461. struct ieee802_1x_cp_sm *sm = cp_ctx;
  462. sm->connect = SECURE;
  463. }
  464. /**
  465. * ieee802_1x_cp_set_chgdserver -
  466. */
  467. void ieee802_1x_cp_signal_chgdserver(void *cp_ctx)
  468. {
  469. struct ieee802_1x_cp_sm *sm = cp_ctx;
  470. sm->chgd_server = TRUE;
  471. }
  472. /**
  473. * ieee802_1x_cp_set_electedself -
  474. */
  475. void ieee802_1x_cp_set_electedself(void *cp_ctx, Boolean status)
  476. {
  477. struct ieee802_1x_cp_sm *sm = cp_ctx;
  478. sm->elected_self = status;
  479. }
  480. /**
  481. * ieee802_1x_cp_set_authorizationdata -
  482. */
  483. void ieee802_1x_cp_set_authorizationdata(void *cp_ctx, u8 *pdata, int len)
  484. {
  485. struct ieee802_1x_cp_sm *sm = cp_ctx;
  486. os_free(sm->authorization_data);
  487. sm->authorization_data = os_zalloc(len);
  488. if (sm->authorization_data)
  489. os_memcpy(sm->authorization_data, pdata, len);
  490. }
  491. /**
  492. * ieee802_1x_cp_set_ciphersuite -
  493. */
  494. void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, void *pid)
  495. {
  496. struct ieee802_1x_cp_sm *sm = cp_ctx;
  497. os_memcpy(sm->cipher_suite, pid, CS_ID_LEN);
  498. }
  499. /**
  500. * ieee802_1x_cp_set_offset -
  501. */
  502. void ieee802_1x_cp_set_offset(void *cp_ctx, enum confidentiality_offset offset)
  503. {
  504. struct ieee802_1x_cp_sm *sm = cp_ctx;
  505. sm->cipher_offset = offset;
  506. }
  507. /**
  508. * ieee802_1x_cp_signal_newsak -
  509. */
  510. void ieee802_1x_cp_signal_newsak(void *cp_ctx)
  511. {
  512. struct ieee802_1x_cp_sm *sm = cp_ctx;
  513. sm->new_sak = TRUE;
  514. }
  515. /**
  516. * ieee802_1x_cp_set_distributedki -
  517. */
  518. void ieee802_1x_cp_set_distributedki(void *cp_ctx,
  519. const struct ieee802_1x_mka_ki *dki)
  520. {
  521. struct ieee802_1x_cp_sm *sm = cp_ctx;
  522. os_memcpy(&sm->distributed_ki, dki, sizeof(struct ieee802_1x_mka_ki));
  523. }
  524. /**
  525. * ieee802_1x_cp_set_distributedan -
  526. */
  527. void ieee802_1x_cp_set_distributedan(void *cp_ctx, u8 an)
  528. {
  529. struct ieee802_1x_cp_sm *sm = cp_ctx;
  530. sm->distributed_an = an;
  531. }
  532. /**
  533. * ieee802_1x_cp_set_usingreceivesas -
  534. */
  535. void ieee802_1x_cp_set_usingreceivesas(void *cp_ctx, Boolean status)
  536. {
  537. struct ieee802_1x_cp_sm *sm = cp_ctx;
  538. sm->using_receive_sas = status;
  539. }
  540. /**
  541. * ieee802_1x_cp_set_allreceiving -
  542. */
  543. void ieee802_1x_cp_set_allreceiving(void *cp_ctx, Boolean status)
  544. {
  545. struct ieee802_1x_cp_sm *sm = cp_ctx;
  546. sm->all_receiving = status;
  547. }
  548. /**
  549. * ieee802_1x_cp_set_servertransmitting -
  550. */
  551. void ieee802_1x_cp_set_servertransmitting(void *cp_ctx, Boolean status)
  552. {
  553. struct ieee802_1x_cp_sm *sm = cp_ctx;
  554. sm->server_transmitting = status;
  555. }
  556. /**
  557. * ieee802_1x_cp_set_usingtransmitsas -
  558. */
  559. void ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, Boolean status)
  560. {
  561. struct ieee802_1x_cp_sm *sm = cp_ctx;
  562. sm->using_transmit_sa = status;
  563. }
  564. /**
  565. * ieee802_1x_cp_sm_step - Advance EAPOL state machines
  566. * @sm: EAPOL state machine
  567. *
  568. * This function is called to advance CP state machines after any change
  569. * that could affect their state.
  570. */
  571. void ieee802_1x_cp_sm_step(void *cp_ctx)
  572. {
  573. /*
  574. * Run ieee802_1x_cp_step_run from a registered timeout
  575. * to make sure that other possible timeouts/events are processed
  576. * and to avoid long function call chains.
  577. */
  578. struct ieee802_1x_cp_sm *sm = cp_ctx;
  579. eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
  580. eloop_register_timeout(0, 0, ieee802_1x_cp_step_cb, sm, NULL);
  581. }
  582. static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
  583. void *timeout_ctx)
  584. {
  585. struct ieee802_1x_cp_sm *sm = eloop_ctx;
  586. sm->retire_when = 0;
  587. ieee802_1x_cp_step_run(sm);
  588. }
  589. static void
  590. ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx, void *timeout_ctx)
  591. {
  592. struct ieee802_1x_cp_sm *sm = eloop_ctx;
  593. sm->transmit_when = 0;
  594. ieee802_1x_cp_step_run(sm);
  595. }