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