2 * IEEE 802.1X-2010 Controlled Port of PAE state machine - CP state machine
3 * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "utils/eloop.h"
13 #include "common/defs.h"
14 #include "common/ieee802_1x_defs.h"
15 #include "utils/state_machine.h"
16 #include "ieee802_1x_kay.h"
17 #include "ieee802_1x_secy_ops.h"
18 #include "pae/ieee802_1x_cp.h"
20 #define STATE_MACHINE_DATA struct ieee802_1x_cp_sm
21 #define STATE_MACHINE_DEBUG_PREFIX "CP"
23 static u8 default_cs_id[] = CS_ID_GCM_AES_128;
25 /* The variable defined in clause 12 in IEEE Std 802.1X-2010 */
26 enum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE };
28 struct ieee802_1x_cp_sm {
30 CP_BEGIN, CP_INIT, CP_CHANGE, CP_ALLOWED, CP_AUTHENTICATED,
31 CP_SECURED, CP_RECEIVE, CP_RECEIVING, CP_READY, CP_TRANSMIT,
32 CP_TRANSMITTING, CP_ABANDON, CP_RETIRE
40 enum connect_type connect;
41 u8 *authorization_data;
44 Boolean chgd_server; /* clear by CP */
46 u8 *authorization_data1;
47 enum confidentiality_offset cipher_offset;
49 Boolean new_sak; /* clear by CP */
50 struct ieee802_1x_mka_ki distributed_ki;
52 Boolean using_receive_sas;
53 Boolean all_receiving;
54 Boolean server_transmitting;
55 Boolean using_transmit_sa;
58 struct ieee802_1x_mka_ki *lki;
62 struct ieee802_1x_mka_ki *oki;
68 Boolean protect_frames;
69 enum validate_frames validate_frames;
71 Boolean replay_protect;
74 u8 *current_cipher_suite;
75 enum confidentiality_offset confidentiality_offset;
76 Boolean controlled_port_enabled;
79 Boolean port_enabled; /* SecY->CP */
87 /* not defined IEEE Std 802.1X-2010 */
88 struct ieee802_1x_kay *kay;
91 static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
93 static void ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx,
97 static int changed_cipher(struct ieee802_1x_cp_sm *sm)
99 return sm->confidentiality_offset != sm->cipher_offset ||
100 os_memcmp(sm->current_cipher_suite, sm->cipher_suite,
105 static int changed_connect(struct ieee802_1x_cp_sm *sm)
107 return sm->connect != SECURE || sm->chgd_server || changed_cipher(sm);
115 sm->controlled_port_enabled = FALSE;
116 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
118 sm->port_valid = FALSE;
130 sm->port_enabled = TRUE;
131 sm->chgd_server = FALSE;
137 SM_ENTRY(CP, CHANGE);
139 sm->port_valid = FALSE;
140 sm->controlled_port_enabled = FALSE;
141 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
144 ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
146 ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
150 SM_STATE(CP, ALLOWED)
152 SM_ENTRY(CP, ALLOWED);
154 sm->protect_frames = FALSE;
155 sm->replay_protect = FALSE;
156 sm->validate_frames = Checked;
158 sm->port_valid = FALSE;
159 sm->controlled_port_enabled = TRUE;
161 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
162 secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
163 secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
164 secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
168 SM_STATE(CP, AUTHENTICATED)
170 SM_ENTRY(CP, AUTHENTICATED);
172 sm->protect_frames = FALSE;
173 sm->replay_protect = FALSE;
174 sm->validate_frames = Checked;
176 sm->port_valid = FALSE;
177 sm->controlled_port_enabled = TRUE;
179 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
180 secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
181 secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
182 secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
186 SM_STATE(CP, SECURED)
188 struct ieee802_1x_cp_conf conf;
190 SM_ENTRY(CP, SECURED);
192 sm->chgd_server = FALSE;
194 ieee802_1x_kay_cp_conf(sm->kay, &conf);
195 sm->protect_frames = conf.protect;
196 sm->replay_protect = conf.replay_protect;
197 sm->validate_frames = conf.validate;
199 /* NOTE: now no other than default cipher suiter(AES-GCM-128) */
200 os_memcpy(sm->current_cipher_suite, sm->cipher_suite, CS_ID_LEN);
201 secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite);
203 sm->confidentiality_offset = sm->cipher_offset;
205 sm->port_valid = TRUE;
207 secy_cp_control_confidentiality_offset(sm->kay,
208 sm->confidentiality_offset);
209 secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
210 secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
211 secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
215 SM_STATE(CP, RECEIVE)
217 SM_ENTRY(CP, RECEIVE);
218 /* RECEIVE state machine not keep with Figure 12-2 in
219 * IEEE Std 802.1X-2010 */
224 ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
227 sm->lki = os_malloc(sizeof(*sm->lki));
229 wpa_printf(MSG_ERROR, "CP-%s: Out of memory", __func__);
232 os_memcpy(sm->lki, &sm->distributed_ki, sizeof(*sm->lki));
233 sm->lan = sm->distributed_an;
236 ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
238 ieee802_1x_kay_create_sas(sm->kay, sm->lki);
239 ieee802_1x_kay_enable_rx_sas(sm->kay, sm->lki);
241 sm->all_receiving = FALSE;
245 SM_STATE(CP, RECEIVING)
247 SM_ENTRY(CP, RECEIVING);
250 ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
252 sm->transmit_when = sm->transmit_delay;
253 eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
254 eloop_register_timeout(sm->transmit_when / 1000, 0,
255 ieee802_1x_cp_transmit_when_timeout, sm, NULL);
256 /* the electedSelf have been set before CP entering to RECEIVING
257 * but the CP will transmit from RECEIVING to READY under
258 * the !electedSelf when KaY is not key server */
259 ieee802_1x_cp_sm_step(sm);
260 sm->using_receive_sas = FALSE;
261 sm->server_transmitting = FALSE;
269 ieee802_1x_kay_enable_new_info(sm->kay);
273 SM_STATE(CP, TRANSMIT)
275 SM_ENTRY(CP, TRANSMIT);
277 sm->controlled_port_enabled = TRUE;
278 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
280 ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
282 ieee802_1x_kay_enable_tx_sas(sm->kay, sm->lki);
283 sm->all_receiving = FALSE;
284 sm->server_transmitting = FALSE;
288 SM_STATE(CP, TRANSMITTING)
290 SM_ENTRY(CP, TRANSMITTING);
291 sm->retire_when = sm->orx ? sm->retire_delay : 0;
293 ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
295 ieee802_1x_kay_enable_new_info(sm->kay);
296 eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
297 eloop_register_timeout(sm->retire_when / 1000, 0,
298 ieee802_1x_cp_retire_when_timeout, sm, NULL);
299 sm->using_transmit_sa = FALSE;
303 SM_STATE(CP, ABANDON)
305 SM_ENTRY(CP, ABANDON);
307 ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
309 ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
313 ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
321 SM_ENTRY(CP, RETIRE);
322 /* RETIRE state machine not keep with Figure 12-2 in
323 * IEEE Std 802.1X-2010 */
328 ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
334 * CP state machine handler entry
338 if (!sm->port_enabled)
341 switch (sm->CP_state) {
347 SM_ENTER(CP, CHANGE);
351 if (sm->connect == UNAUTHENTICATED)
352 SM_ENTER(CP, ALLOWED);
353 else if (sm->connect == AUTHENTICATED)
354 SM_ENTER(CP, AUTHENTICATED);
355 else if (sm->connect == SECURE)
356 SM_ENTER(CP, SECURED);
360 if (sm->connect != UNAUTHENTICATED)
361 SM_ENTER(CP, CHANGE);
364 case CP_AUTHENTICATED:
365 if (sm->connect != AUTHENTICATED)
366 SM_ENTER(CP, CHANGE);
370 if (changed_connect(sm))
371 SM_ENTER(CP, CHANGE);
372 else if (sm->new_sak)
373 SM_ENTER(CP, RECEIVE);
377 if (sm->using_receive_sas)
378 SM_ENTER(CP, RECEIVING);
382 if (sm->new_sak || changed_connect(sm))
383 SM_ENTER(CP, ABANDON);
384 if (!sm->elected_self)
386 if (sm->elected_self &&
387 (sm->all_receiving || !sm->transmit_when))
388 SM_ENTER(CP, TRANSMIT);
392 if (sm->using_transmit_sa)
393 SM_ENTER(CP, TRANSMITTING);
396 case CP_TRANSMITTING:
397 if (!sm->retire_when || changed_connect(sm))
398 SM_ENTER(CP, RETIRE);
402 if (changed_connect(sm))
403 SM_ENTER(CP, CHANGE);
404 else if (sm->new_sak)
405 SM_ENTER(CP, RECEIVE);
409 if (sm->new_sak || changed_connect(sm))
410 SM_ENTER(CP, RECEIVE);
411 if (sm->server_transmitting)
412 SM_ENTER(CP, TRANSMIT);
415 if (changed_connect(sm))
416 SM_ENTER(CP, RETIRE);
417 else if (sm->new_sak)
418 SM_ENTER(CP, RECEIVE);
421 wpa_printf(MSG_ERROR, "CP: the state machine is not defined");
428 * ieee802_1x_cp_sm_init -
430 struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(
431 struct ieee802_1x_kay *kay,
432 struct ieee802_1x_cp_conf *pcp_conf)
434 struct ieee802_1x_cp_sm *sm;
436 sm = os_zalloc(sizeof(*sm));
438 wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
444 sm->port_valid = FALSE;
446 sm->chgd_server = FALSE;
448 sm->protect_frames = pcp_conf->protect;
449 sm->validate_frames = pcp_conf->validate;
450 sm->replay_protect = pcp_conf->replay_protect;
451 sm->replay_window = pcp_conf->replay_window;
453 sm->controlled_port_enabled = FALSE;
462 sm->cipher_suite = os_zalloc(CS_ID_LEN);
463 sm->current_cipher_suite = os_zalloc(CS_ID_LEN);
464 if (!sm->cipher_suite || !sm->current_cipher_suite) {
465 wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
466 os_free(sm->cipher_suite);
467 os_free(sm->current_cipher_suite);
471 os_memcpy(sm->current_cipher_suite, default_cs_id, CS_ID_LEN);
472 os_memcpy(sm->cipher_suite, default_cs_id, CS_ID_LEN);
473 sm->cipher_offset = CONFIDENTIALITY_OFFSET_0;
474 sm->confidentiality_offset = sm->cipher_offset;
475 sm->transmit_delay = MKA_LIFE_TIME;
476 sm->retire_delay = MKA_SAK_RETIRE_TIME;
477 sm->CP_state = CP_BEGIN;
479 sm->authorization_data = NULL;
481 wpa_printf(MSG_DEBUG, "CP: state machine created");
483 secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
484 secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
485 secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
486 secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
487 secy_cp_control_confidentiality_offset(sm->kay,
488 sm->confidentiality_offset);
497 static void ieee802_1x_cp_step_run(struct ieee802_1x_cp_sm *sm)
499 enum cp_states prev_state;
502 for (i = 0; i < 100; i++) {
503 prev_state = sm->CP_state;
505 if (prev_state == sm->CP_state)
511 static void ieee802_1x_cp_step_cb(void *eloop_ctx, void *timeout_ctx)
513 struct ieee802_1x_cp_sm *sm = eloop_ctx;
514 ieee802_1x_cp_step_run(sm);
519 * ieee802_1x_cp_sm_deinit -
521 void ieee802_1x_cp_sm_deinit(struct ieee802_1x_cp_sm *sm)
523 wpa_printf(MSG_DEBUG, "CP: state machine removed");
527 eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
528 eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
529 eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
532 os_free(sm->cipher_suite);
533 os_free(sm->current_cipher_suite);
534 os_free(sm->authorization_data);
540 * ieee802_1x_cp_connect_pending
542 void ieee802_1x_cp_connect_pending(void *cp_ctx)
544 struct ieee802_1x_cp_sm *sm = cp_ctx;
546 sm->connect = PENDING;
551 * ieee802_1x_cp_connect_unauthenticated
553 void ieee802_1x_cp_connect_unauthenticated(void *cp_ctx)
555 struct ieee802_1x_cp_sm *sm = (struct ieee802_1x_cp_sm *)cp_ctx;
557 sm->connect = UNAUTHENTICATED;
562 * ieee802_1x_cp_connect_authenticated
564 void ieee802_1x_cp_connect_authenticated(void *cp_ctx)
566 struct ieee802_1x_cp_sm *sm = cp_ctx;
568 sm->connect = AUTHENTICATED;
573 * ieee802_1x_cp_connect_secure
575 void ieee802_1x_cp_connect_secure(void *cp_ctx)
577 struct ieee802_1x_cp_sm *sm = cp_ctx;
579 sm->connect = SECURE;
584 * ieee802_1x_cp_set_chgdserver -
586 void ieee802_1x_cp_signal_chgdserver(void *cp_ctx)
588 struct ieee802_1x_cp_sm *sm = cp_ctx;
590 sm->chgd_server = TRUE;
595 * ieee802_1x_cp_set_electedself -
597 void ieee802_1x_cp_set_electedself(void *cp_ctx, Boolean status)
599 struct ieee802_1x_cp_sm *sm = cp_ctx;
600 sm->elected_self = status;
605 * ieee802_1x_cp_set_authorizationdata -
607 void ieee802_1x_cp_set_authorizationdata(void *cp_ctx, u8 *pdata, int len)
609 struct ieee802_1x_cp_sm *sm = cp_ctx;
610 os_free(sm->authorization_data);
611 sm->authorization_data = os_zalloc(len);
612 if (sm->authorization_data)
613 os_memcpy(sm->authorization_data, pdata, len);
618 * ieee802_1x_cp_set_ciphersuite -
620 void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, void *pid)
622 struct ieee802_1x_cp_sm *sm = cp_ctx;
623 os_memcpy(sm->cipher_suite, pid, CS_ID_LEN);
628 * ieee802_1x_cp_set_offset -
630 void ieee802_1x_cp_set_offset(void *cp_ctx, enum confidentiality_offset offset)
632 struct ieee802_1x_cp_sm *sm = cp_ctx;
633 sm->cipher_offset = offset;
638 * ieee802_1x_cp_signal_newsak -
640 void ieee802_1x_cp_signal_newsak(void *cp_ctx)
642 struct ieee802_1x_cp_sm *sm = cp_ctx;
648 * ieee802_1x_cp_set_distributedki -
650 void ieee802_1x_cp_set_distributedki(void *cp_ctx,
651 const struct ieee802_1x_mka_ki *dki)
653 struct ieee802_1x_cp_sm *sm = cp_ctx;
654 os_memcpy(&sm->distributed_ki, dki, sizeof(struct ieee802_1x_mka_ki));
659 * ieee802_1x_cp_set_distributedan -
661 void ieee802_1x_cp_set_distributedan(void *cp_ctx, u8 an)
663 struct ieee802_1x_cp_sm *sm = cp_ctx;
664 sm->distributed_an = an;
669 * ieee802_1x_cp_set_usingreceivesas -
671 void ieee802_1x_cp_set_usingreceivesas(void *cp_ctx, Boolean status)
673 struct ieee802_1x_cp_sm *sm = cp_ctx;
674 sm->using_receive_sas = status;
679 * ieee802_1x_cp_set_allreceiving -
681 void ieee802_1x_cp_set_allreceiving(void *cp_ctx, Boolean status)
683 struct ieee802_1x_cp_sm *sm = cp_ctx;
684 sm->all_receiving = status;
689 * ieee802_1x_cp_set_servertransmitting -
691 void ieee802_1x_cp_set_servertransmitting(void *cp_ctx, Boolean status)
693 struct ieee802_1x_cp_sm *sm = cp_ctx;
694 sm->server_transmitting = status;
699 * ieee802_1x_cp_set_usingtransmitsas -
701 void ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, Boolean status)
703 struct ieee802_1x_cp_sm *sm = cp_ctx;
704 sm->using_transmit_sa = status;
709 * ieee802_1x_cp_sm_step - Advance EAPOL state machines
710 * @sm: EAPOL state machine
712 * This function is called to advance CP state machines after any change
713 * that could affect their state.
715 void ieee802_1x_cp_sm_step(void *cp_ctx)
718 * Run ieee802_1x_cp_step_run from a registered timeout
719 * to make sure that other possible timeouts/events are processed
720 * and to avoid long function call chains.
722 struct ieee802_1x_cp_sm *sm = cp_ctx;
723 eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
724 eloop_register_timeout(0, 0, ieee802_1x_cp_step_cb, sm, NULL);
728 static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
731 struct ieee802_1x_cp_sm *sm = eloop_ctx;
733 ieee802_1x_cp_step_run(sm);
738 ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx, void *timeout_ctx)
740 struct ieee802_1x_cp_sm *sm = eloop_ctx;
741 sm->transmit_when = 0;
742 ieee802_1x_cp_step_run(sm);