15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/*
25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine
35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt * Copyright (c) 2013, 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#ifndef IEEE802_1X_KAY_H
105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define IEEE802_1X_KAY_H
115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "utils/list.h"
135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/defs.h"
145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "common/ieee802_1x_defs.h"
155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct macsec_init_params;
175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_cp_conf;
185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MI_LEN			12
205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MAX_KEY_LEN		32  /* 32 bytes, 256 bits */
215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MAX_CKN_LEN		32  /* 32 bytes, 256 bits */
225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* MKA timer, unit: millisecond */
245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MKA_HELLO_TIME		2000
255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MKA_LIFE_TIME		6000
265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define MKA_SAK_RETIRE_TIME	3000
275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_mka_ki {
295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 mi[MI_LEN];
305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 kn;
315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_mka_sci {
345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 addr[ETH_ALEN];
355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u16 port;
365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct mka_key {
395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 key[MAX_KEY_LEN];
405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	size_t len;
415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct mka_key_name {
445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 name[MAX_CKN_LEN];
455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	size_t len;
465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtenum mka_created_mode {
495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	PSK,
505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	EAP_EXCHANGE,
515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	DISTRIBUTED,
525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	CACHED,
535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_kay_ctx {
565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* pointer to arbitrary upper level context */
575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	void *ctx;
585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* abstract wpa driver interface */
605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*macsec_init)(void *ctx, struct macsec_init_params *params);
615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*macsec_deinit)(void *ctx);
625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*enable_protect_frames)(void *ctx, Boolean enabled);
635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window);
645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*set_current_cipher_suite)(void *ctx, const u8 *cs, size_t cs_len);
655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*enable_controlled_port)(void *ctx, Boolean enabled);
665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*get_receive_lowest_pn)(void *ctx, u32 channel, u8 an,
675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				     u32 *lowest_pn);
685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*get_transmit_next_pn)(void *ctx, u32 channel, u8 an,
695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				    u32 *next_pn);
705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*set_transmit_next_pn)(void *ctx, u32 channel, u8 an, u32 next_pn);
715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*get_available_receive_sc)(void *ctx, u32 *channel);
725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*create_receive_sc)(void *ctx, u32 channel,
735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 struct ieee802_1x_mka_sci *sci,
745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 enum validate_frames vf,
755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 enum confidentiality_offset co);
765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*delete_receive_sc)(void *ctx, u32 channel);
775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*create_receive_sa)(void *ctx, u32 channel, u8 an, u32 lowest_pn,
785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 const u8 *sak);
795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*enable_receive_sa)(void *ctx, u32 channel, u8 an);
805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*disable_receive_sa)(void *ctx, u32 channel, u8 an);
815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*get_available_transmit_sc)(void *ctx, u32 *channel);
825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*create_transmit_sc)(void *ctx, u32 channel,
835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				  const struct ieee802_1x_mka_sci *sci,
845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				  enum confidentiality_offset co);
855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*delete_transmit_sc)(void *ctx, u32 channel);
865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*create_transmit_sa)(void *ctx, u32 channel, u8 an, u32 next_pn,
875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				  Boolean confidentiality, const u8 *sak);
885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*enable_transmit_sa)(void *ctx, u32 channel, u8 an);
895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int (*disable_transmit_sa)(void *ctx, u32 channel, u8 an);
905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_kay {
935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean enable;
945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean active;
955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean authenticated;
975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean secured;
985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean failed;
995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_mka_sci actor_sci;
1015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 actor_priority;
1025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_mka_sci key_server_sci;
1035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 key_server_priority;
1045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum macsec_cap macsec_capable;
1065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean macsec_desired;
1075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean macsec_protect;
1085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean macsec_replay_protect;
1095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 macsec_replay_window;
1105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum validate_frames macsec_validate;
1115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum confidentiality_offset macsec_confidentiality;
1125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 ltx_kn;
1145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 ltx_an;
1155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 lrx_kn;
1165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 lrx_an;
1175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 otx_kn;
1195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 otx_an;
1205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 orx_kn;
1215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 orx_an;
1225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	/* not defined in IEEE802.1X */
1245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_kay_ctx *ctx;
1255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean is_key_server;
1265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean is_obliged_key_server;
1275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	char if_name[IFNAMSIZ];
1285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int macsec_csindex;  /*  MACsec cipher suite table index */
1305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	int mka_algindex;  /* MKA alg table index */
1315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 dist_kn;
1335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 dist_an;
1345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	time_t dist_time;
1355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 mka_version;
1375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u8 algo_agility[4];
1385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 sc_ch;
1395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	u32 pn_exhaustion;
1415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean port_enable;
1425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean rx_enable;
1435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	Boolean tx_enable;
1445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct dl_list participant_list;
1465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum macsec_policy policy;
1475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct ieee802_1x_cp_sm *cp;
1495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	struct l2_packet_data *l2_mka;
1515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum validate_frames vf;
1535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt	enum confidentiality_offset co;
1545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
1555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_kay *
1585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
1595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt		    const char *ifname, const u8 *addr);
1605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay);
1615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ieee802_1x_mka_participant *
1635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay,
1645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			  struct mka_key_name *ckn, struct mka_key *cak,
1655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			  u32 life, enum mka_created_mode mode,
1665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			  Boolean is_authenticator);
1675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay,
1685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			       struct mka_key_name *ckn);
1695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
1705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				    struct mka_key_name *ckn,
1715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				    Boolean status);
1725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay);
1735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
1745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				       int cs_index);
1755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay,
1775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				      struct ieee802_1x_mka_ki *lki, u8 lan,
1785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				      Boolean ltx, Boolean lrx);
1795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay,
1805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				   struct ieee802_1x_mka_ki *oki,
1815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				   u8 oan, Boolean otx, Boolean orx);
1825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay,
1835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			      struct ieee802_1x_mka_ki *lki);
1845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay,
1855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			      struct ieee802_1x_mka_ki *ki);
1865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay,
1875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 struct ieee802_1x_mka_ki *lki);
1885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay,
1895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt				 struct ieee802_1x_mka_ki *lki);
1905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay);
1915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtint ieee802_1x_kay_cp_conf(struct ieee802_1x_kay *kay,
1925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt			   struct ieee802_1x_cp_conf *pconf);
1935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif /* IEEE802_1X_KAY_H */
195