xref: /freebsd/contrib/wpa/src/pae/ieee802_1x_kay.h (revision a90b9d01)
15b9c547cSRui Paulo /*
25b9c547cSRui Paulo  * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine
35b9c547cSRui Paulo  * Copyright (c) 2013, Qualcomm Atheros, Inc.
45b9c547cSRui Paulo  *
55b9c547cSRui Paulo  * This software may be distributed under the terms of the BSD license.
65b9c547cSRui Paulo  * See README for more details.
75b9c547cSRui Paulo  */
85b9c547cSRui Paulo 
95b9c547cSRui Paulo #ifndef IEEE802_1X_KAY_H
105b9c547cSRui Paulo #define IEEE802_1X_KAY_H
115b9c547cSRui Paulo 
125b9c547cSRui Paulo #include "utils/list.h"
135b9c547cSRui Paulo #include "common/defs.h"
145b9c547cSRui Paulo #include "common/ieee802_1x_defs.h"
155b9c547cSRui Paulo 
165b9c547cSRui Paulo struct macsec_init_params;
175b9c547cSRui Paulo 
1885732ac8SCy Schubert #define MI_LEN			12  /* 96-bit Member Identifier */
195b9c547cSRui Paulo #define MAX_KEY_LEN		32  /* 32 bytes, 256 bits */
205b9c547cSRui Paulo #define MAX_CKN_LEN		32  /* 32 bytes, 256 bits */
215b9c547cSRui Paulo 
225b9c547cSRui Paulo /* MKA timer, unit: millisecond */
235b9c547cSRui Paulo #define MKA_HELLO_TIME		2000
244bc52338SCy Schubert #define MKA_BOUNDED_HELLO_TIME	 500
255b9c547cSRui Paulo #define MKA_LIFE_TIME		6000
265b9c547cSRui Paulo #define MKA_SAK_RETIRE_TIME	3000
275b9c547cSRui Paulo 
2885732ac8SCy Schubert /**
2985732ac8SCy Schubert  * struct ieee802_1x_mka_ki - Key Identifier (KI)
3085732ac8SCy Schubert  * @mi: Key Server's Member Identifier
3185732ac8SCy Schubert  * @kn: Key Number, assigned by the Key Server
3285732ac8SCy Schubert  * IEEE 802.1X-2010 9.8 SAK generation, distribution, and selection
3385732ac8SCy Schubert  */
345b9c547cSRui Paulo struct ieee802_1x_mka_ki {
355b9c547cSRui Paulo 	u8 mi[MI_LEN];
365b9c547cSRui Paulo 	u32 kn;
375b9c547cSRui Paulo };
385b9c547cSRui Paulo 
395b9c547cSRui Paulo struct ieee802_1x_mka_sci {
405b9c547cSRui Paulo 	u8 addr[ETH_ALEN];
41780fb4a2SCy Schubert 	be16 port;
424bc52338SCy Schubert } STRUCT_PACKED;
435b9c547cSRui Paulo 
445b9c547cSRui Paulo struct mka_key {
455b9c547cSRui Paulo 	u8 key[MAX_KEY_LEN];
465b9c547cSRui Paulo 	size_t len;
475b9c547cSRui Paulo };
485b9c547cSRui Paulo 
495b9c547cSRui Paulo struct mka_key_name {
505b9c547cSRui Paulo 	u8 name[MAX_CKN_LEN];
515b9c547cSRui Paulo 	size_t len;
525b9c547cSRui Paulo };
535b9c547cSRui Paulo 
545b9c547cSRui Paulo enum mka_created_mode {
555b9c547cSRui Paulo 	PSK,
565b9c547cSRui Paulo 	EAP_EXCHANGE,
575b9c547cSRui Paulo };
585b9c547cSRui Paulo 
5985732ac8SCy Schubert struct data_key {
6085732ac8SCy Schubert 	u8 *key;
6185732ac8SCy Schubert 	int key_len;
6285732ac8SCy Schubert 	struct ieee802_1x_mka_ki key_identifier;
6385732ac8SCy Schubert 	enum confidentiality_offset confidentiality_offset;
6485732ac8SCy Schubert 	u8 an;
65c1d255d3SCy Schubert 	bool transmits;
66c1d255d3SCy Schubert 	bool receives;
6785732ac8SCy Schubert 	struct os_time created_time;
6885732ac8SCy Schubert 	u32 next_pn;
6985732ac8SCy Schubert 
7085732ac8SCy Schubert 	/* not defined data */
71c1d255d3SCy Schubert 	bool rx_latest;
72c1d255d3SCy Schubert 	bool tx_latest;
7385732ac8SCy Schubert 
7485732ac8SCy Schubert 	int user;
7585732ac8SCy Schubert 
7685732ac8SCy Schubert 	struct dl_list list;
7785732ac8SCy Schubert };
7885732ac8SCy Schubert 
7985732ac8SCy Schubert /* TransmitSC in IEEE Std 802.1AE-2006, Figure 10-6 */
8085732ac8SCy Schubert struct transmit_sc {
8185732ac8SCy Schubert 	struct ieee802_1x_mka_sci sci; /* const SCI sci */
82c1d255d3SCy Schubert 	bool transmitting; /* bool transmitting (read only) */
8385732ac8SCy Schubert 
8485732ac8SCy Schubert 	struct os_time created_time; /* Time createdTime */
8585732ac8SCy Schubert 
8685732ac8SCy Schubert 	u8 encoding_sa; /* AN encodingSA (read only) */
8785732ac8SCy Schubert 	u8 enciphering_sa; /* AN encipheringSA (read only) */
8885732ac8SCy Schubert 
8985732ac8SCy Schubert 	/* not defined data */
9085732ac8SCy Schubert 	struct dl_list list;
9185732ac8SCy Schubert 	struct dl_list sa_list;
9285732ac8SCy Schubert };
9385732ac8SCy Schubert 
9485732ac8SCy Schubert /* TransmitSA in IEEE Std 802.1AE-2006, Figure 10-6 */
9585732ac8SCy Schubert struct transmit_sa {
96c1d255d3SCy Schubert 	bool in_use; /* bool inUse (read only) */
9785732ac8SCy Schubert 	u32 next_pn; /* PN nextPN (read only) */
9885732ac8SCy Schubert 	struct os_time created_time; /* Time createdTime */
9985732ac8SCy Schubert 
100c1d255d3SCy Schubert 	bool enable_transmit; /* bool EnableTransmit */
10185732ac8SCy Schubert 
10285732ac8SCy Schubert 	u8 an;
103c1d255d3SCy Schubert 	bool confidentiality;
10485732ac8SCy Schubert 	struct data_key *pkey;
10585732ac8SCy Schubert 
10685732ac8SCy Schubert 	struct transmit_sc *sc;
10785732ac8SCy Schubert 	struct dl_list list; /* list entry in struct transmit_sc::sa_list */
10885732ac8SCy Schubert };
10985732ac8SCy Schubert 
11085732ac8SCy Schubert /* ReceiveSC in IEEE Std 802.1AE-2006, Figure 10-6 */
11185732ac8SCy Schubert struct receive_sc {
11285732ac8SCy Schubert 	struct ieee802_1x_mka_sci sci; /* const SCI sci */
113c1d255d3SCy Schubert 	bool receiving; /* bool receiving (read only) */
11485732ac8SCy Schubert 
11585732ac8SCy Schubert 	struct os_time created_time; /* Time createdTime */
11685732ac8SCy Schubert 
11785732ac8SCy Schubert 	struct dl_list list;
11885732ac8SCy Schubert 	struct dl_list sa_list;
11985732ac8SCy Schubert };
12085732ac8SCy Schubert 
12185732ac8SCy Schubert /* ReceiveSA in IEEE Std 802.1AE-2006, Figure 10-6 */
12285732ac8SCy Schubert struct receive_sa {
123c1d255d3SCy Schubert 	bool enable_receive; /* bool enableReceive */
124c1d255d3SCy Schubert 	bool in_use; /* bool inUse (read only) */
12585732ac8SCy Schubert 
12685732ac8SCy Schubert 	u32 next_pn; /* PN nextPN (read only) */
12785732ac8SCy Schubert 	u32 lowest_pn; /* PN lowestPN (read only) */
12885732ac8SCy Schubert 	u8 an;
12985732ac8SCy Schubert 	struct os_time created_time;
13085732ac8SCy Schubert 
13185732ac8SCy Schubert 	struct data_key *pkey;
13285732ac8SCy Schubert 	struct receive_sc *sc; /* list entry in struct receive_sc::sa_list */
13385732ac8SCy Schubert 
13485732ac8SCy Schubert 	struct dl_list list;
13585732ac8SCy Schubert };
13685732ac8SCy Schubert 
1375b9c547cSRui Paulo struct ieee802_1x_kay_ctx {
1385b9c547cSRui Paulo 	/* pointer to arbitrary upper level context */
1395b9c547cSRui Paulo 	void *ctx;
1405b9c547cSRui Paulo 
1415b9c547cSRui Paulo 	/* abstract wpa driver interface */
1425b9c547cSRui Paulo 	int (*macsec_init)(void *ctx, struct macsec_init_params *params);
1435b9c547cSRui Paulo 	int (*macsec_deinit)(void *ctx);
14485732ac8SCy Schubert 	int (*macsec_get_capability)(void *priv, enum macsec_cap *cap);
145c1d255d3SCy Schubert 	int (*enable_protect_frames)(void *ctx, bool enabled);
146c1d255d3SCy Schubert 	int (*enable_encrypt)(void *ctx, bool enabled);
147c1d255d3SCy Schubert 	int (*set_replay_protect)(void *ctx, bool enabled, u32 window);
148780fb4a2SCy Schubert 	int (*set_current_cipher_suite)(void *ctx, u64 cs);
149c1d255d3SCy Schubert 	int (*enable_controlled_port)(void *ctx, bool enabled);
15085732ac8SCy Schubert 	int (*get_receive_lowest_pn)(void *ctx, struct receive_sa *sa);
15185732ac8SCy Schubert 	int (*get_transmit_next_pn)(void *ctx, struct transmit_sa *sa);
15285732ac8SCy Schubert 	int (*set_transmit_next_pn)(void *ctx, struct transmit_sa *sa);
1534bc52338SCy Schubert 	int (*set_receive_lowest_pn)(void *ctx, struct receive_sa *sa);
15485732ac8SCy Schubert 	int (*create_receive_sc)(void *ctx, struct receive_sc *sc,
1555b9c547cSRui Paulo 				 enum validate_frames vf,
1565b9c547cSRui Paulo 				 enum confidentiality_offset co);
15785732ac8SCy Schubert 	int (*delete_receive_sc)(void *ctx, struct receive_sc *sc);
15885732ac8SCy Schubert 	int (*create_receive_sa)(void *ctx, struct receive_sa *sa);
15985732ac8SCy Schubert 	int (*delete_receive_sa)(void *ctx, struct receive_sa *sa);
16085732ac8SCy Schubert 	int (*enable_receive_sa)(void *ctx, struct receive_sa *sa);
16185732ac8SCy Schubert 	int (*disable_receive_sa)(void *ctx, struct receive_sa *sa);
16285732ac8SCy Schubert 	int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc,
1635b9c547cSRui Paulo 				  enum confidentiality_offset co);
16485732ac8SCy Schubert 	int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc);
16585732ac8SCy Schubert 	int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa);
16685732ac8SCy Schubert 	int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa);
16785732ac8SCy Schubert 	int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa);
16885732ac8SCy Schubert 	int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa);
169*a90b9d01SCy Schubert 	int (*set_offload)(void *ctx, u8 offload);
1705b9c547cSRui Paulo };
1715b9c547cSRui Paulo 
1725b9c547cSRui Paulo struct ieee802_1x_kay {
173c1d255d3SCy Schubert 	bool enable;
174c1d255d3SCy Schubert 	bool active;
1755b9c547cSRui Paulo 
176c1d255d3SCy Schubert 	bool authenticated;
177c1d255d3SCy Schubert 	bool secured;
178c1d255d3SCy Schubert 	bool failed;
1795b9c547cSRui Paulo 
1805b9c547cSRui Paulo 	struct ieee802_1x_mka_sci actor_sci;
1815b9c547cSRui Paulo 	u8 actor_priority;
1825b9c547cSRui Paulo 	struct ieee802_1x_mka_sci key_server_sci;
1835b9c547cSRui Paulo 	u8 key_server_priority;
1845b9c547cSRui Paulo 
1855b9c547cSRui Paulo 	enum macsec_cap macsec_capable;
186c1d255d3SCy Schubert 	bool macsec_desired;
187c1d255d3SCy Schubert 	bool macsec_protect;
188c1d255d3SCy Schubert 	bool macsec_encrypt;
189c1d255d3SCy Schubert 	bool macsec_replay_protect;
1905b9c547cSRui Paulo 	u32 macsec_replay_window;
1915b9c547cSRui Paulo 	enum validate_frames macsec_validate;
1925b9c547cSRui Paulo 	enum confidentiality_offset macsec_confidentiality;
1934bc52338SCy Schubert 	u32 mka_hello_time;
1945b9c547cSRui Paulo 
1955b9c547cSRui Paulo 	u32 ltx_kn;
1965b9c547cSRui Paulo 	u8 ltx_an;
1975b9c547cSRui Paulo 	u32 lrx_kn;
1985b9c547cSRui Paulo 	u8 lrx_an;
1995b9c547cSRui Paulo 
2005b9c547cSRui Paulo 	u32 otx_kn;
2015b9c547cSRui Paulo 	u8 otx_an;
2025b9c547cSRui Paulo 	u32 orx_kn;
2035b9c547cSRui Paulo 	u8 orx_an;
2045b9c547cSRui Paulo 
2055b9c547cSRui Paulo 	/* not defined in IEEE802.1X */
2065b9c547cSRui Paulo 	struct ieee802_1x_kay_ctx *ctx;
207c1d255d3SCy Schubert 	bool is_key_server;
208c1d255d3SCy Schubert 	bool is_obliged_key_server;
2095b9c547cSRui Paulo 	char if_name[IFNAMSIZ];
210*a90b9d01SCy Schubert 	u8 macsec_offload;
2115b9c547cSRui Paulo 
212780fb4a2SCy Schubert 	unsigned int macsec_csindex;  /* MACsec cipher suite table index */
2135b9c547cSRui Paulo 	int mka_algindex;  /* MKA alg table index */
2145b9c547cSRui Paulo 
2155b9c547cSRui Paulo 	u32 dist_kn;
21685732ac8SCy Schubert 	u32 rcvd_keys;
2175b9c547cSRui Paulo 	u8 dist_an;
2185b9c547cSRui Paulo 	time_t dist_time;
2195b9c547cSRui Paulo 
2205b9c547cSRui Paulo 	u8 mka_version;
2215b9c547cSRui Paulo 	u8 algo_agility[4];
2225b9c547cSRui Paulo 
2235b9c547cSRui Paulo 	u32 pn_exhaustion;
224c1d255d3SCy Schubert 	bool port_enable;
225c1d255d3SCy Schubert 	bool rx_enable;
226c1d255d3SCy Schubert 	bool tx_enable;
2275b9c547cSRui Paulo 
2285b9c547cSRui Paulo 	struct dl_list participant_list;
2295b9c547cSRui Paulo 	enum macsec_policy policy;
2305b9c547cSRui Paulo 
2315b9c547cSRui Paulo 	struct ieee802_1x_cp_sm *cp;
2325b9c547cSRui Paulo 
2335b9c547cSRui Paulo 	struct l2_packet_data *l2_mka;
2345b9c547cSRui Paulo 
2355b9c547cSRui Paulo 	enum validate_frames vf;
2365b9c547cSRui Paulo 	enum confidentiality_offset co;
2375b9c547cSRui Paulo };
2385b9c547cSRui Paulo 
2395b9c547cSRui Paulo 
24085732ac8SCy Schubert u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci);
24185732ac8SCy Schubert 
2425b9c547cSRui Paulo struct ieee802_1x_kay *
2435b9c547cSRui Paulo ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
244c1d255d3SCy Schubert 		    bool macsec_replay_protect, u32 macsec_replay_window,
245*a90b9d01SCy Schubert 		    u8 macsec_offload, u16 port, u8 priority,
246*a90b9d01SCy Schubert 		    u32 macsec_csindex, const char *ifname, const u8 *addr);
2475b9c547cSRui Paulo void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay);
2485b9c547cSRui Paulo 
2495b9c547cSRui Paulo struct ieee802_1x_mka_participant *
2505b9c547cSRui Paulo ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay,
25185732ac8SCy Schubert 			  const struct mka_key_name *ckn,
25285732ac8SCy Schubert 			  const struct mka_key *cak,
2535b9c547cSRui Paulo 			  u32 life, enum mka_created_mode mode,
254c1d255d3SCy Schubert 			  bool is_authenticator);
2555b9c547cSRui Paulo void ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay,
2565b9c547cSRui Paulo 			       struct mka_key_name *ckn);
2575b9c547cSRui Paulo void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
2585b9c547cSRui Paulo 				    struct mka_key_name *ckn,
259c1d255d3SCy Schubert 				    bool status);
2605b9c547cSRui Paulo int ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay);
2615b9c547cSRui Paulo int ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
262780fb4a2SCy Schubert 				       unsigned int cs_index);
2635b9c547cSRui Paulo 
2645b9c547cSRui Paulo int ieee802_1x_kay_set_latest_sa_attr(struct ieee802_1x_kay *kay,
2655b9c547cSRui Paulo 				      struct ieee802_1x_mka_ki *lki, u8 lan,
266c1d255d3SCy Schubert 				      bool ltx, bool lrx);
2675b9c547cSRui Paulo int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay,
2685b9c547cSRui Paulo 				   struct ieee802_1x_mka_ki *oki,
269c1d255d3SCy Schubert 				   u8 oan, bool otx, bool orx);
2705b9c547cSRui Paulo int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay,
2715b9c547cSRui Paulo 			      struct ieee802_1x_mka_ki *lki);
2725b9c547cSRui Paulo int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay,
2735b9c547cSRui Paulo 			      struct ieee802_1x_mka_ki *ki);
2745b9c547cSRui Paulo int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay,
2755b9c547cSRui Paulo 				 struct ieee802_1x_mka_ki *lki);
2765b9c547cSRui Paulo int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay,
2775b9c547cSRui Paulo 				 struct ieee802_1x_mka_ki *lki);
2785b9c547cSRui Paulo int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay);
27985732ac8SCy Schubert int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
28085732ac8SCy Schubert 			      size_t buflen);
2814bc52338SCy Schubert int ieee802_1x_kay_get_mib(struct ieee802_1x_kay *kay, char *buf,
2824bc52338SCy Schubert 			   size_t buflen);
2835b9c547cSRui Paulo 
2845b9c547cSRui Paulo #endif /* IEEE802_1X_KAY_H */
285