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
9#include "utils/includes.h"
10
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"
19
20#define STATE_MACHINE_DATA struct ieee802_1x_cp_sm
21#define STATE_MACHINE_DEBUG_PREFIX "CP"
22
23static u64 default_cs_id = CS_ID_GCM_AES_128;
24
25/* The variable defined in clause 12 in IEEE Std 802.1X-2010 */
26enum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE };
27
28struct ieee802_1x_cp_sm {
29	enum cp_states {
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
33	} CP_state;
34	bool changed;
35
36	/* CP -> Client */
37	bool port_valid;
38
39	/* Logon -> CP */
40	enum connect_type connect;
41
42	/* KaY -> CP */
43	bool chgd_server; /* clear by CP */
44	bool elected_self;
45	enum confidentiality_offset cipher_offset;
46	u64 cipher_suite;
47	bool new_sak; /* clear by CP */
48	struct ieee802_1x_mka_ki distributed_ki;
49	u8 distributed_an;
50	bool using_receive_sas;
51	bool all_receiving;
52	bool server_transmitting;
53	bool using_transmit_sa;
54
55	/* CP -> KaY */
56	struct ieee802_1x_mka_ki *lki;
57	u8 lan;
58	bool ltx;
59	bool lrx;
60	struct ieee802_1x_mka_ki *oki;
61	u8 oan;
62	bool otx;
63	bool orx;
64
65	/* CP -> SecY */
66	bool protect_frames;
67	enum validate_frames validate_frames;
68
69	bool replay_protect;
70	u32 replay_window;
71
72	u64 current_cipher_suite;
73	enum confidentiality_offset confidentiality_offset;
74	bool controlled_port_enabled;
75
76	/* SecY -> CP */
77	bool port_enabled; /* SecY->CP */
78
79	/* private */
80	u32 transmit_when;
81	u32 transmit_delay;
82	u32 retire_when;
83	u32 retire_delay;
84
85	/* not defined IEEE Std 802.1X-2010 */
86	struct ieee802_1x_kay *kay;
87};
88
89static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
90					      void *timeout_ctx);
91static void ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx,
92						void *timeout_ctx);
93
94
95static int changed_cipher(struct ieee802_1x_cp_sm *sm)
96{
97	return sm->confidentiality_offset != sm->cipher_offset ||
98		sm->current_cipher_suite != sm->cipher_suite;
99}
100
101
102static int changed_connect(struct ieee802_1x_cp_sm *sm)
103{
104	return sm->connect != SECURE || sm->chgd_server || changed_cipher(sm);
105}
106
107
108SM_STATE(CP, INIT)
109{
110	SM_ENTRY(CP, INIT);
111
112	sm->controlled_port_enabled = false;
113	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
114
115	sm->port_valid = false;
116
117	os_free(sm->lki);
118	sm->lki = NULL;
119	sm->ltx = false;
120	sm->lrx = false;
121
122	os_free(sm->oki);
123	sm->oki = NULL;
124	sm->otx = false;
125	sm->orx = false;
126
127	sm->port_enabled = true;
128	sm->chgd_server = false;
129}
130
131
132SM_STATE(CP, CHANGE)
133{
134	SM_ENTRY(CP, CHANGE);
135
136	sm->port_valid = false;
137	sm->controlled_port_enabled = false;
138	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
139
140	if (sm->lki)
141		ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
142	if (sm->oki)
143		ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
144	/* The standard doesn't say it but we should clear out the latest
145	 * and old key values. Why would we keep advertising them if
146	 * they've been deleted and the key server has been changed?
147	 */
148	os_free(sm->oki);
149	sm->oki = NULL;
150	sm->otx = false;
151	sm->orx = false;
152	sm->oan = 0;
153	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
154				       sm->otx, sm->orx);
155	os_free(sm->lki);
156	sm->lki = NULL;
157	sm->lrx = false;
158	sm->ltx = false;
159	sm->lan = 0;
160	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
161					  sm->ltx, sm->lrx);
162}
163
164
165SM_STATE(CP, ALLOWED)
166{
167	SM_ENTRY(CP, ALLOWED);
168
169	sm->protect_frames = false;
170	sm->replay_protect = false;
171	sm->validate_frames = Checked;
172
173	sm->port_valid = false;
174	sm->controlled_port_enabled = true;
175
176	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
177	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
178	secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt);
179	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
180	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
181}
182
183
184SM_STATE(CP, AUTHENTICATED)
185{
186	SM_ENTRY(CP, AUTHENTICATED);
187
188	sm->protect_frames = false;
189	sm->replay_protect = false;
190	sm->validate_frames = Checked;
191
192	sm->port_valid = false;
193	sm->controlled_port_enabled = true;
194
195	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
196	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
197	secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt);
198	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
199	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
200}
201
202
203SM_STATE(CP, SECURED)
204{
205	SM_ENTRY(CP, SECURED);
206
207	sm->chgd_server = false;
208
209	sm->protect_frames = sm->kay->macsec_protect;
210	sm->replay_protect = sm->kay->macsec_replay_protect;
211	sm->validate_frames = sm->kay->macsec_validate;
212
213	/* NOTE: now no other than default cipher suite (AES-GCM-128) */
214	sm->current_cipher_suite = sm->cipher_suite;
215	secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite);
216
217	sm->confidentiality_offset = sm->cipher_offset;
218
219	sm->port_valid = true;
220
221	secy_cp_control_confidentiality_offset(sm->kay,
222					       sm->confidentiality_offset);
223	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
224	secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt);
225	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
226	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
227}
228
229
230SM_STATE(CP, RECEIVE)
231{
232	SM_ENTRY(CP, RECEIVE);
233
234	sm->lki = os_malloc(sizeof(*sm->lki));
235	if (!sm->lki) {
236		wpa_printf(MSG_ERROR, "CP-%s: Out of memory", __func__);
237		return;
238	}
239	os_memcpy(sm->lki, &sm->distributed_ki, sizeof(*sm->lki));
240	sm->lan = sm->distributed_an;
241	sm->ltx = false;
242	sm->lrx = false;
243	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
244					  sm->ltx, sm->lrx);
245	ieee802_1x_kay_create_sas(sm->kay, sm->lki);
246	ieee802_1x_kay_enable_rx_sas(sm->kay, sm->lki);
247	sm->new_sak = false;
248	sm->all_receiving = false;
249}
250
251
252SM_STATE(CP, RECEIVING)
253{
254	SM_ENTRY(CP, RECEIVING);
255
256	sm->lrx = true;
257	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
258					  sm->ltx, sm->lrx);
259	sm->transmit_when = sm->transmit_delay;
260	eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
261	eloop_register_timeout(sm->transmit_when / 1000, 0,
262			       ieee802_1x_cp_transmit_when_timeout, sm, NULL);
263	/* the electedSelf have been set before CP entering to RECEIVING
264	 * but the CP will transmit from RECEIVING to READY under
265	 * the !electedSelf when KaY is not key server */
266	ieee802_1x_cp_sm_step(sm);
267	sm->using_receive_sas = false;
268	sm->server_transmitting = false;
269}
270
271
272SM_STATE(CP, READY)
273{
274	SM_ENTRY(CP, READY);
275
276	ieee802_1x_kay_enable_new_info(sm->kay);
277}
278
279
280SM_STATE(CP, TRANSMIT)
281{
282	SM_ENTRY(CP, TRANSMIT);
283
284	sm->controlled_port_enabled = true;
285	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
286	sm->ltx = true;
287	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
288					  sm->ltx, sm->lrx);
289	ieee802_1x_kay_enable_tx_sas(sm->kay,  sm->lki);
290	sm->all_receiving = false;
291	sm->server_transmitting = false;
292}
293
294
295SM_STATE(CP, TRANSMITTING)
296{
297	SM_ENTRY(CP, TRANSMITTING);
298	sm->retire_when = sm->orx ? sm->retire_delay : 0;
299	sm->otx = false;
300	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
301				       sm->otx, sm->orx);
302	ieee802_1x_kay_enable_new_info(sm->kay);
303	eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
304	eloop_register_timeout(sm->retire_when / 1000, 0,
305			       ieee802_1x_cp_retire_when_timeout, sm, NULL);
306	sm->using_transmit_sa = false;
307}
308
309
310SM_STATE(CP, ABANDON)
311{
312	SM_ENTRY(CP, ABANDON);
313	sm->lrx = false;
314	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
315					  sm->ltx, sm->lrx);
316	ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
317
318	os_free(sm->lki);
319	sm->lki = NULL;
320	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
321					  sm->ltx, sm->lrx);
322}
323
324
325SM_STATE(CP, RETIRE)
326{
327	SM_ENTRY(CP, RETIRE);
328	if (sm->oki) {
329		ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
330		os_free(sm->oki);
331		sm->oki = NULL;
332	}
333	sm->oki = sm->lki;
334	sm->otx = sm->ltx;
335	sm->orx = sm->lrx;
336	sm->oan = sm->lan;
337	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
338				       sm->otx, sm->orx);
339	sm->lki = NULL;
340	sm->ltx = false;
341	sm->lrx = false;
342	sm->lan = 0;
343	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
344					  sm->ltx, sm->lrx);
345}
346
347
348/**
349 * CP state machine handler entry
350 */
351SM_STEP(CP)
352{
353	if (!sm->port_enabled)
354		SM_ENTER(CP, INIT);
355
356	switch (sm->CP_state) {
357	case CP_BEGIN:
358		SM_ENTER(CP, INIT);
359		break;
360
361	case CP_INIT:
362		SM_ENTER(CP, CHANGE);
363		break;
364
365	case CP_CHANGE:
366		if (sm->connect == UNAUTHENTICATED)
367			SM_ENTER(CP, ALLOWED);
368		else if (sm->connect == AUTHENTICATED)
369			SM_ENTER(CP, AUTHENTICATED);
370		else if (sm->connect == SECURE)
371			SM_ENTER(CP, SECURED);
372		break;
373
374	case CP_ALLOWED:
375		if (sm->connect != UNAUTHENTICATED)
376			SM_ENTER(CP, CHANGE);
377		break;
378
379	case CP_AUTHENTICATED:
380		if (sm->connect != AUTHENTICATED)
381			SM_ENTER(CP, CHANGE);
382		break;
383
384	case CP_SECURED:
385		if (changed_connect(sm))
386			SM_ENTER(CP, CHANGE);
387		else if (sm->new_sak)
388			SM_ENTER(CP, RECEIVE);
389		break;
390
391	case CP_RECEIVE:
392		if (sm->using_receive_sas)
393			SM_ENTER(CP, RECEIVING);
394		break;
395
396	case CP_RECEIVING:
397		if (sm->new_sak || changed_connect(sm))
398			SM_ENTER(CP, ABANDON);
399		if (!sm->elected_self)
400			SM_ENTER(CP, READY);
401		if (sm->elected_self &&
402		    (sm->all_receiving || !sm->controlled_port_enabled ||
403		     !sm->transmit_when))
404			SM_ENTER(CP, TRANSMIT);
405		break;
406
407	case CP_TRANSMIT:
408		if (sm->using_transmit_sa)
409			SM_ENTER(CP, TRANSMITTING);
410		break;
411
412	case CP_TRANSMITTING:
413		if (!sm->retire_when || changed_connect(sm))
414			SM_ENTER(CP, RETIRE);
415		break;
416
417	case CP_RETIRE:
418		if (changed_connect(sm))
419			SM_ENTER(CP, CHANGE);
420		else if (sm->new_sak)
421			SM_ENTER(CP, RECEIVE);
422		break;
423
424	case CP_READY:
425		if (sm->new_sak || changed_connect(sm))
426			SM_ENTER(CP, ABANDON);
427		if (sm->server_transmitting || !sm->controlled_port_enabled)
428			SM_ENTER(CP, TRANSMIT);
429		break;
430	case CP_ABANDON:
431		if (changed_connect(sm))
432			SM_ENTER(CP, RETIRE);
433		else if (sm->new_sak)
434			SM_ENTER(CP, RECEIVE);
435		break;
436	default:
437		wpa_printf(MSG_ERROR, "CP: the state machine is not defined");
438		break;
439	}
440}
441
442
443/**
444 * ieee802_1x_cp_sm_init -
445 */
446struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay)
447{
448	struct ieee802_1x_cp_sm *sm;
449
450	sm = os_zalloc(sizeof(*sm));
451	if (sm == NULL) {
452		wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
453		return NULL;
454	}
455
456	sm->kay = kay;
457
458	sm->port_valid = false;
459
460	sm->chgd_server = false;
461
462	sm->protect_frames = kay->macsec_protect;
463	sm->validate_frames = kay->macsec_validate;
464	sm->replay_protect = kay->macsec_replay_protect;
465	sm->replay_window = kay->macsec_replay_window;
466
467	sm->controlled_port_enabled = false;
468
469	sm->lki = NULL;
470	sm->lrx = false;
471	sm->ltx = false;
472	sm->oki = NULL;
473	sm->orx = false;
474	sm->otx = false;
475
476	sm->current_cipher_suite = default_cs_id;
477	sm->cipher_suite = default_cs_id;
478	sm->cipher_offset = CONFIDENTIALITY_OFFSET_0;
479	sm->confidentiality_offset = sm->cipher_offset;
480	sm->transmit_delay = MKA_LIFE_TIME;
481	sm->retire_delay = MKA_SAK_RETIRE_TIME;
482	sm->CP_state = CP_BEGIN;
483	sm->changed = false;
484
485	wpa_printf(MSG_DEBUG, "CP: state machine created");
486
487	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
488	secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt);
489	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
490	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
491	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
492	secy_cp_control_confidentiality_offset(sm->kay,
493					       sm->confidentiality_offset);
494
495	SM_STEP_RUN(CP);
496
497	return sm;
498}
499
500
501static void ieee802_1x_cp_step_run(struct ieee802_1x_cp_sm *sm)
502{
503	enum cp_states prev_state;
504	int i;
505
506	for (i = 0; i < 100; i++) {
507		prev_state = sm->CP_state;
508		SM_STEP_RUN(CP);
509		if (prev_state == sm->CP_state)
510			break;
511	}
512}
513
514
515static void ieee802_1x_cp_step_cb(void *eloop_ctx, void *timeout_ctx)
516{
517	struct ieee802_1x_cp_sm *sm = eloop_ctx;
518	ieee802_1x_cp_step_run(sm);
519}
520
521
522/**
523 * ieee802_1x_cp_sm_deinit -
524 */
525void ieee802_1x_cp_sm_deinit(struct ieee802_1x_cp_sm *sm)
526{
527	wpa_printf(MSG_DEBUG, "CP: state machine removed");
528	if (!sm)
529		return;
530
531	eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
532	eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
533	eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
534	os_free(sm->lki);
535	os_free(sm->oki);
536	os_free(sm);
537}
538
539
540/**
541 * ieee802_1x_cp_connect_pending
542 */
543void ieee802_1x_cp_connect_pending(void *cp_ctx)
544{
545	struct ieee802_1x_cp_sm *sm = cp_ctx;
546
547	sm->connect = PENDING;
548}
549
550
551/**
552 * ieee802_1x_cp_connect_unauthenticated
553 */
554void ieee802_1x_cp_connect_unauthenticated(void *cp_ctx)
555{
556	struct ieee802_1x_cp_sm *sm = (struct ieee802_1x_cp_sm *)cp_ctx;
557
558	sm->connect = UNAUTHENTICATED;
559}
560
561
562/**
563 * ieee802_1x_cp_connect_authenticated
564 */
565void ieee802_1x_cp_connect_authenticated(void *cp_ctx)
566{
567	struct ieee802_1x_cp_sm *sm = cp_ctx;
568
569	sm->connect = AUTHENTICATED;
570}
571
572
573/**
574 * ieee802_1x_cp_connect_secure
575 */
576void ieee802_1x_cp_connect_secure(void *cp_ctx)
577{
578	struct ieee802_1x_cp_sm *sm = cp_ctx;
579
580	sm->connect = SECURE;
581}
582
583
584/**
585 * ieee802_1x_cp_set_chgdserver -
586 */
587void ieee802_1x_cp_signal_chgdserver(void *cp_ctx)
588{
589	struct ieee802_1x_cp_sm *sm = cp_ctx;
590
591	sm->chgd_server = true;
592}
593
594
595/**
596 * ieee802_1x_cp_set_electedself -
597 */
598void ieee802_1x_cp_set_electedself(void *cp_ctx, bool status)
599{
600	struct ieee802_1x_cp_sm *sm = cp_ctx;
601	sm->elected_self = status;
602}
603
604
605/**
606 * ieee802_1x_cp_set_ciphersuite -
607 */
608void ieee802_1x_cp_set_ciphersuite(void *cp_ctx, u64 cs)
609{
610	struct ieee802_1x_cp_sm *sm = cp_ctx;
611	sm->cipher_suite = cs;
612}
613
614
615/**
616 * ieee802_1x_cp_set_offset -
617 */
618void ieee802_1x_cp_set_offset(void *cp_ctx, enum confidentiality_offset offset)
619{
620	struct ieee802_1x_cp_sm *sm = cp_ctx;
621	sm->cipher_offset = offset;
622}
623
624
625/**
626 * ieee802_1x_cp_signal_newsak -
627 */
628void ieee802_1x_cp_signal_newsak(void *cp_ctx)
629{
630	struct ieee802_1x_cp_sm *sm = cp_ctx;
631	sm->new_sak = true;
632}
633
634
635/**
636 * ieee802_1x_cp_set_distributedki -
637 */
638void ieee802_1x_cp_set_distributedki(void *cp_ctx,
639				     const struct ieee802_1x_mka_ki *dki)
640{
641	struct ieee802_1x_cp_sm *sm = cp_ctx;
642	os_memcpy(&sm->distributed_ki, dki, sizeof(struct ieee802_1x_mka_ki));
643}
644
645
646/**
647 * ieee802_1x_cp_set_distributedan -
648 */
649void ieee802_1x_cp_set_distributedan(void *cp_ctx, u8 an)
650{
651	struct ieee802_1x_cp_sm *sm = cp_ctx;
652	sm->distributed_an = an;
653}
654
655
656/**
657 * ieee802_1x_cp_set_usingreceivesas -
658 */
659void ieee802_1x_cp_set_usingreceivesas(void *cp_ctx, bool status)
660{
661	struct ieee802_1x_cp_sm *sm = cp_ctx;
662	sm->using_receive_sas = status;
663}
664
665
666/**
667 * ieee802_1x_cp_set_allreceiving -
668 */
669void ieee802_1x_cp_set_allreceiving(void *cp_ctx, bool status)
670{
671	struct ieee802_1x_cp_sm *sm = cp_ctx;
672	sm->all_receiving = status;
673}
674
675
676/**
677 * ieee802_1x_cp_set_servertransmitting -
678 */
679void ieee802_1x_cp_set_servertransmitting(void *cp_ctx, bool status)
680{
681	struct ieee802_1x_cp_sm *sm = cp_ctx;
682	sm->server_transmitting = status;
683}
684
685
686/**
687 * ieee802_1x_cp_set_usingtransmitsas -
688 */
689void ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, bool status)
690{
691	struct ieee802_1x_cp_sm *sm = cp_ctx;
692	sm->using_transmit_sa = status;
693}
694
695
696/**
697 * ieee802_1x_cp_sm_step - Advance EAPOL state machines
698 * @sm: EAPOL state machine
699 *
700 * This function is called to advance CP state machines after any change
701 * that could affect their state.
702 */
703void ieee802_1x_cp_sm_step(void *cp_ctx)
704{
705	/*
706	 * Run ieee802_1x_cp_step_run from a registered timeout
707	 * to make sure that other possible timeouts/events are processed
708	 * and to avoid long function call chains.
709	 */
710	struct ieee802_1x_cp_sm *sm = cp_ctx;
711	eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
712	eloop_register_timeout(0, 0, ieee802_1x_cp_step_cb, sm, NULL);
713}
714
715
716static void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
717					      void *timeout_ctx)
718{
719	struct ieee802_1x_cp_sm *sm = eloop_ctx;
720	sm->retire_when = 0;
721	ieee802_1x_cp_step_run(sm);
722}
723
724
725static void
726ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx, void *timeout_ctx)
727{
728	struct ieee802_1x_cp_sm *sm = eloop_ctx;
729	sm->transmit_when = 0;
730	ieee802_1x_cp_step_run(sm);
731}
732