15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/*
25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * IEEE 802.1X-2010 Controlled Port of PAE state machine - CP state machine
35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt *
55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * This software may be distributed under the terms of the BSD license.
65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * See README for more details.
75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
95a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/includes.h"
105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/common.h"
125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/eloop.h"
135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/defs.h"
145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/ieee802_1x_defs.h"
155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/state_machine.h"
165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_kay.h"
175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "ieee802_1x_secy_ops.h"
185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "pae/ieee802_1x_cp.h"
195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define STATE_MACHINE_DATA struct ieee802_1x_cp_sm
215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define STATE_MACHINE_DEBUG_PREFIX "CP"
225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic u8 default_cs_id[] = CS_ID_GCM_AES_128;
245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* The variable defined in clause 12 in IEEE Std 802.1X-2010 */
265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtenum connect_type { PENDING, UNAUTHENTICATED, AUTHENTICATED, SECURE };
275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_cp_sm {
295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum cp_states {
305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		CP_BEGIN, CP_INIT, CP_CHANGE, CP_ALLOWED, CP_AUTHENTICATED,
315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		CP_SECURED, CP_RECEIVE, CP_RECEIVING, CP_READY, CP_TRANSMIT,
325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		CP_TRANSMITTING, CP_ABANDON, CP_RETIRE
335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	} CP_state;
345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean changed;
355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* CP -> Client */
375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean port_valid;
385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* Logon -> CP */
405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum connect_type connect;
415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 *authorization_data;
425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* KaY -> CP */
445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean chgd_server; /* clear by CP */
455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean elected_self;
465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 *authorization_data1;
475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum confidentiality_offset cipher_offset;
485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 *cipher_suite;
495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean new_sak; /* clear by CP */
505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_mka_ki distributed_ki;
515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 distributed_an;
525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean using_receive_sas;
535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean all_receiving;
545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean server_transmitting;
555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean using_transmit_sa;
565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* CP -> KaY */
585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_mka_ki *lki;
595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 lan;
605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean ltx;
615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean lrx;
625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_mka_ki *oki;
635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 oan;
645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean otx;
655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean orx;
665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* CP -> SecY */
685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean protect_frames;
695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum validate_frames validate_frames;
705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean replay_protect;
725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 replay_window;
735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 *current_cipher_suite;
755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum confidentiality_offset confidentiality_offset;
765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean controlled_port_enabled;
775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* SecY -> CP */
795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean port_enabled; /* SecY->CP */
805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* private */
825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 transmit_when;
835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 transmit_delay;
845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 retire_when;
855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 retire_delay;
865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* not defined IEEE Std 802.1X-2010 */
885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_kay *kay;
895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					      void *timeout_ctx);
935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_cp_transmit_when_timeout(void *eloop_ctx,
945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt						void *timeout_ctx);
955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int changed_cipher(struct ieee802_1x_cp_sm *sm)
985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return sm->confidentiality_offset != sm->cipher_offset ||
1005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_memcmp(sm->current_cipher_suite, sm->cipher_suite,
1015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			  CS_ID_LEN) != 0;
1025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic int changed_connect(struct ieee802_1x_cp_sm *sm)
1065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return sm->connect != SECURE || sm->chgd_server || changed_cipher(sm);
1085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1115a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, INIT)
1125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, INIT);
1145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = FALSE;
1165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
1175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = FALSE;
1195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->lki);
1215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lki = NULL;
1225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->ltx = FALSE;
1235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lrx = FALSE;
1245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->oki);
1265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->oki = NULL;
1275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->otx = FALSE;
1285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->orx = FALSE;
1295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_enabled = TRUE;
1315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->chgd_server = FALSE;
1325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1355a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, CHANGE)
1365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, CHANGE);
1385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = FALSE;
1405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = FALSE;
1415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
1425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (sm->lki)
1445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
1455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (sm->oki)
1465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
1475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1505a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, ALLOWED)
1515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, ALLOWED);
1535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->protect_frames = FALSE;
1555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->replay_protect = FALSE;
1565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->validate_frames = Checked;
1575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = FALSE;
1595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = TRUE;
1605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
1625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
1635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
1645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
1655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1685a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, AUTHENTICATED)
1695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, AUTHENTICATED);
1715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->protect_frames = FALSE;
1735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->replay_protect = FALSE;
1745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->validate_frames = Checked;
1755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = FALSE;
1775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = TRUE;
1785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
1805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
1815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
1825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
1835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1865a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, SECURED)
1875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
1885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_conf conf;
1895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, SECURED);
1915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->chgd_server = FALSE;
1935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_cp_conf(sm->kay, &conf);
1955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->protect_frames = conf.protect;
1965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->replay_protect = conf.replay_protect;
1975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->validate_frames = conf.validate;
1985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* NOTE: now no other than default cipher suiter(AES-GCM-128) */
2005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(sm->current_cipher_suite, sm->cipher_suite, CS_ID_LEN);
2015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_current_cipher_suite(sm->kay, sm->current_cipher_suite,
2025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					     CS_ID_LEN);
2035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->confidentiality_offset = sm->cipher_offset;
2055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = TRUE;
2075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_confidentiality_offset(sm->kay,
2095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					       sm->confidentiality_offset);
2105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
2115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
2125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
2135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2165a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, RECEIVE)
2175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, RECEIVE);
2195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* RECEIVE state machine not keep with Figure 12-2 in
2205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * IEEE Std 802.1X-2010 */
2215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->oki = sm->lki;
2225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->oan = sm->lan;
2235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->otx = sm->ltx;
2245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->orx = sm->lrx;
2255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
2265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				       sm->otx, sm->orx);
2275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lki = os_malloc(sizeof(*sm->lki));
2295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (!sm->lki) {
2305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "CP-%s: Out of memory", __func__);
2315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return;
2325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
2335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(sm->lki, &sm->distributed_ki, sizeof(*sm->lki));
2345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lan = sm->distributed_an;
2355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->ltx = FALSE;
2365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lrx = FALSE;
2375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
2385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					  sm->ltx, sm->lrx);
2395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_create_sas(sm->kay, sm->lki);
2405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_enable_rx_sas(sm->kay, sm->lki);
2415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->new_sak = FALSE;
2425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->all_receiving = FALSE;
2435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2465a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, RECEIVING)
2475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, RECEIVING);
2495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lrx = TRUE;
2515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
2525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					  sm->ltx, sm->lrx);
2535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->transmit_when = sm->transmit_delay;
2545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
2555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_register_timeout(sm->transmit_when / 1000, 0,
2565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			       ieee802_1x_cp_transmit_when_timeout, sm, NULL);
2575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* the electedSelf have been set before CP entering to RECEIVING
2585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * but the CP will transmit from RECEIVING to READY under
2595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * the !electedSelf when KaY is not key server */
2605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_cp_sm_step(sm);
2615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->using_receive_sas = FALSE;
2625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->server_transmitting = FALSE;
2635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2665a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, READY)
2675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, READY);
2695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_enable_new_info(sm->kay);
2715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2745a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, TRANSMIT)
2755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, TRANSMIT);
2775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = TRUE;
2795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
2805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->ltx = TRUE;
2815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
2825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					  sm->ltx, sm->lrx);
2835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_enable_tx_sas(sm->kay,  sm->lki);
2845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->all_receiving = FALSE;
2855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->server_transmitting = FALSE;
2865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
2875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
2895a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, TRANSMITTING)
2905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
2915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, TRANSMITTING);
2925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->retire_when = sm->orx ? sm->retire_delay : 0;
2935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->otx = FALSE;
2945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
2955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				       sm->otx, sm->orx);
2965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_enable_new_info(sm->kay);
2975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
2985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_register_timeout(sm->retire_when / 1000, 0,
2995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			       ieee802_1x_cp_retire_when_timeout, sm, NULL);
3005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->using_transmit_sa = FALSE;
3015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3045a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, ABANDON)
3055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, ABANDON);
3075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lrx = FALSE;
3085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
3095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					  sm->ltx, sm->lrx);
3105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_delete_sas(sm->kay, sm->lki);
3115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->lki);
3135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lki = NULL;
3145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_latest_sa_attr(sm->kay, sm->lki, sm->lan,
3155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					  sm->ltx, sm->lrx);
3165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->new_sak = FALSE;
3175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3205a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STATE(CP, RETIRE)
3215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTRY(CP, RETIRE);
3235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* RETIRE state machine not keep with Figure 12-2 in
3245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * IEEE Std 802.1X-2010 */
3255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->oki);
3265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->oki = NULL;
3275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->orx = FALSE;
3285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->otx = FALSE;
3295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
3305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				       sm->otx, sm->orx);
3315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
3325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
3355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * CP state machine handler entry
3365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
3375a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtSM_STEP(CP)
3385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
3395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (!sm->port_enabled)
3405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		SM_ENTER(CP, INIT);
3415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	switch (sm->CP_state) {
3435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_BEGIN:
3445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		SM_ENTER(CP, INIT);
3455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_INIT:
3485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		SM_ENTER(CP, CHANGE);
3495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_CHANGE:
3525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->connect == UNAUTHENTICATED)
3535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, ALLOWED);
3545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		else if (sm->connect == AUTHENTICATED)
3555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, AUTHENTICATED);
3565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		else if (sm->connect == SECURE)
3575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, SECURED);
3585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_ALLOWED:
3615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->connect != UNAUTHENTICATED)
3625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, CHANGE);
3635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_AUTHENTICATED:
3665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->connect != AUTHENTICATED)
3675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, CHANGE);
3685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_SECURED:
3715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (changed_connect(sm))
3725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, CHANGE);
3735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		else if (sm->new_sak)
3745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RECEIVE);
3755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_RECEIVE:
3785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->using_receive_sas)
3795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RECEIVING);
3805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_RECEIVING:
3835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->new_sak || changed_connect(sm))
3845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, ABANDON);
3855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (!sm->elected_self)
3865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, READY);
3875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->elected_self &&
3885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		    (sm->all_receiving || !sm->transmit_when))
3895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, TRANSMIT);
3905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_TRANSMIT:
3935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->using_transmit_sa)
3945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, TRANSMITTING);
3955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
3965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
3975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_TRANSMITTING:
3985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (!sm->retire_when || changed_connect(sm))
3995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RETIRE);
4005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
4015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_RETIRE:
4035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (changed_connect(sm))
4045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, CHANGE);
4055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		else if (sm->new_sak)
4065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RECEIVE);
4075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
4085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_READY:
4105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->new_sak || changed_connect(sm))
4115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RECEIVE);
4125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (sm->server_transmitting)
4135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, TRANSMIT);
4145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
4155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	case CP_ABANDON:
4165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (changed_connect(sm))
4175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RETIRE);
4185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		else if (sm->new_sak)
4195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			SM_ENTER(CP, RECEIVE);
4205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
4215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	default:
4225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "CP: the state machine is not defined");
4235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		break;
4245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
4255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
4265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
4295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_sm_init -
4305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
4315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(
4325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_kay *kay,
4335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_conf *pcp_conf)
4345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
4355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm;
4365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm = os_zalloc(sizeof(*sm));
4385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (sm == NULL) {
4395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
4405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return NULL;
4415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
4425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->kay = kay;
4445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->port_valid = FALSE;
4465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->chgd_server = FALSE;
4485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->protect_frames = pcp_conf->protect;
4505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->validate_frames = pcp_conf->validate;
4515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->replay_protect = pcp_conf->replay_protect;
4525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->replay_window = pcp_conf->replay_window;
4535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->controlled_port_enabled = FALSE;
4555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lki = NULL;
4575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->lrx = FALSE;
4585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->ltx = FALSE;
4595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->oki = NULL;
4605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->orx = FALSE;
4615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->otx = FALSE;
4625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->cipher_suite = os_zalloc(CS_ID_LEN);
4645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->current_cipher_suite = os_zalloc(CS_ID_LEN);
4655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (!sm->cipher_suite || !sm->current_cipher_suite) {
4665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		wpa_printf(MSG_ERROR, "CP-%s: out of memory", __func__);
4675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_free(sm->cipher_suite);
4685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_free(sm->current_cipher_suite);
4695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_free(sm);
4705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return NULL;
4715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
4725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(sm->current_cipher_suite, default_cs_id, CS_ID_LEN);
4735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(sm->cipher_suite, default_cs_id, CS_ID_LEN);
4745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->cipher_offset = CONFIDENTIALITY_OFFSET_0;
4755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->confidentiality_offset = sm->cipher_offset;
4765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->transmit_delay = MKA_LIFE_TIME;
4775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->retire_delay = MKA_SAK_RETIRE_TIME;
4785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->CP_state = CP_BEGIN;
4795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->changed = FALSE;
4805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->authorization_data = NULL;
4815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "CP: state machine created");
4835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_protect_frames(sm->kay, sm->protect_frames);
4855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_validate_frames(sm->kay, sm->validate_frames);
4865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window);
4875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled);
4885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	secy_cp_control_confidentiality_offset(sm->kay,
4895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					       sm->confidentiality_offset);
4905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_ENTER(CP, INIT);
4925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	SM_STEP_RUN(CP);
4935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	return sm;
4955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
4965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
4985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_cp_step_run(struct ieee802_1x_cp_sm *sm)
4995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum cp_states prev_state;
5015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int i;
5025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	for (i = 0; i < 100; i++) {
5045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		prev_state = sm->CP_state;
5055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		SM_STEP_RUN(CP);
5065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		if (prev_state == sm->CP_state)
5075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			break;
5085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	}
5095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_cp_step_cb(void *eloop_ctx, void *timeout_ctx)
5135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = eloop_ctx;
5155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_cp_step_run(sm);
5165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_sm_deinit -
5215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_sm_deinit(struct ieee802_1x_cp_sm *sm)
5235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	wpa_printf(MSG_DEBUG, "CP: state machine removed");
5255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (!sm)
5265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		return;
5275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_retire_when_timeout, sm, NULL);
5295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_transmit_when_timeout, sm, NULL);
5305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
5315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->lki);
5325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->oki);
5335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->cipher_suite);
5345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->current_cipher_suite);
5355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->authorization_data);
5365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm);
5375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_connect_pending
5425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_connect_pending(void *cp_ctx)
5445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
5465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->connect = PENDING;
5485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_connect_unauthenticated
5535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_connect_unauthenticated(void *cp_ctx)
5555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = (struct ieee802_1x_cp_sm *)cp_ctx;
5575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->connect = UNAUTHENTICATED;
5595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_connect_authenticated
5645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_connect_authenticated(void *cp_ctx)
5665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
5685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->connect = AUTHENTICATED;
5705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_connect_secure
5755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_connect_secure(void *cp_ctx)
5775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
5795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->connect = SECURE;
5815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_chgdserver -
5865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_signal_chgdserver(void *cp_ctx)
5885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
5895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
5905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->chgd_server = TRUE;
5925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
5935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
5955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
5965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_electedself -
5975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
5985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_electedself(void *cp_ctx, Boolean status)
5995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->elected_self = status;
6025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_authorizationdata -
6075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_authorizationdata(void *cp_ctx, u8 *pdata, int len)
6095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_free(sm->authorization_data);
6125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->authorization_data = os_zalloc(len);
6135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	if (sm->authorization_data)
6145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		os_memcpy(sm->authorization_data, pdata, len);
6155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_ciphersuite -
6205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_ciphersuite(void *cp_ctx, void *pid)
6225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(sm->cipher_suite, pid, CS_ID_LEN);
6255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_offset -
6305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_offset(void *cp_ctx, enum confidentiality_offset offset)
6325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->cipher_offset = offset;
6355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_signal_newsak -
6405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_signal_newsak(void *cp_ctx)
6425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->new_sak = TRUE;
6455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_distributedki -
6505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_distributedki(void *cp_ctx,
6525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				     const struct ieee802_1x_mka_ki *dki)
6535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	os_memcpy(&sm->distributed_ki, dki, sizeof(struct ieee802_1x_mka_ki));
6565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_distributedan -
6615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_distributedan(void *cp_ctx, u8 an)
6635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->distributed_an = an;
6665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_usingreceivesas -
6715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_usingreceivesas(void *cp_ctx, Boolean status)
6735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->using_receive_sas = status;
6765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_allreceiving -
6815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_allreceiving(void *cp_ctx, Boolean status)
6835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->all_receiving = status;
6865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
6905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_servertransmitting -
6915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
6925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_servertransmitting(void *cp_ctx, Boolean status)
6935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
6945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
6955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->server_transmitting = status;
6965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
6975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
6995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
7005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_set_usingtransmitsas -
7015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
7025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, Boolean status)
7035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
7045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
7055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->using_transmit_sa = status;
7065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
7075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/**
7105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * ieee802_1x_cp_sm_step - Advance EAPOL state machines
7115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * @sm: EAPOL state machine
7125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt *
7135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * This function is called to advance CP state machines after any change
7145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * that could affect their state.
7155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt */
7165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_cp_sm_step(void *cp_ctx)
7175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
7185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/*
7195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * Run ieee802_1x_cp_step_run from a registered timeout
7205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * to make sure that other possible timeouts/events are processed
7215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 * and to avoid long function call chains.
7225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	 */
7235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = cp_ctx;
7245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_cancel_timeout(ieee802_1x_cp_step_cb, sm, NULL);
7255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	eloop_register_timeout(0, 0, ieee802_1x_cp_step_cb, sm, NULL);
7265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
7275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void ieee802_1x_cp_retire_when_timeout(void *eloop_ctx,
7305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt					      void *timeout_ctx)
7315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
7325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = eloop_ctx;
7335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->retire_when = 0;
7345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_cp_step_run(sm);
7355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
7365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
7385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic void
7395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_cp_transmit_when_timeout(void *eloop_ctx, void *timeout_ctx)
7405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt{
7415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *sm = eloop_ctx;
7425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	sm->transmit_when = 0;
7435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	ieee802_1x_cp_step_run(sm);
7445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
745