| /* |
| * IEEE 802.1X-2010 Key Agree Protocol of PAE state machine |
| * Copyright (c) 2013, Qualcomm Atheros, Inc. |
| * |
| * This software may be distributed under the terms of the BSD license. |
| * See README for more details. |
| */ |
| |
| #ifndef IEEE802_1X_KAY_I_H |
| #define IEEE802_1X_KAY_I_H |
| |
| #include "utils/list.h" |
| #include "common/defs.h" |
| #include "common/ieee802_1x_defs.h" |
| |
| #define MKA_VERSION_ID 1 |
| |
| /* IEEE Std 802.1X-2010, 11.11.1, Table 11-7 (MKPDU parameter sets) */ |
| enum mka_packet_type { |
| MKA_BASIC_PARAMETER_SET = MKA_VERSION_ID, |
| MKA_LIVE_PEER_LIST = 1, |
| MKA_POTENTIAL_PEER_LIST = 2, |
| MKA_SAK_USE = 3, |
| MKA_DISTRIBUTED_SAK = 4, |
| MKA_DISTRIBUTED_CAK = 5, |
| MKA_KMD = 6, |
| MKA_ANNOUNCEMENT = 7, |
| MKA_ICV_INDICATOR = 255 |
| }; |
| |
| #define ICV_LEN 16 /* 16 bytes */ |
| #define SAK_WRAPPED_LEN 24 |
| /* KN + Wrapper SAK */ |
| #define DEFAULT_DIS_SAK_BODY_LENGTH (SAK_WRAPPED_LEN + 4) |
| #define MAX_RETRY_CNT 5 |
| |
| struct ieee802_1x_kay; |
| |
| struct ieee802_1x_mka_peer_id { |
| u8 mi[MI_LEN]; |
| be32 mn; |
| } STRUCT_PACKED; |
| |
| struct ieee802_1x_kay_peer { |
| struct ieee802_1x_mka_sci sci; |
| u8 mi[MI_LEN]; |
| u32 mn; |
| time_t expire; |
| bool is_key_server; |
| u8 key_server_priority; |
| bool macsec_desired; |
| enum macsec_cap macsec_capability; |
| bool sak_used; |
| int missing_sak_use_count; |
| struct dl_list list; |
| }; |
| |
| struct macsec_ciphersuite { |
| u64 id; |
| char name[32]; |
| enum macsec_cap capable; |
| int sak_len; /* unit: byte */ |
| }; |
| |
| struct mka_alg { |
| u8 parameter[4]; |
| size_t icv_len; |
| |
| int (*cak_trfm)(const u8 *msk, size_t msk_bytes, const u8 *mac1, |
| const u8 *mac2, u8 *cak, size_t cak_bytes); |
| int (*ckn_trfm)(const u8 *msk, size_t msk_bytes, const u8 *mac1, |
| const u8 *mac2, const u8 *sid, size_t sid_len, u8 *ckn); |
| int (*kek_trfm)(const u8 *cak, size_t cak_bytes, |
| const u8 *ckn, size_t ckn_len, |
| u8 *kek, size_t kek_bytes); |
| int (*ick_trfm)(const u8 *cak, size_t cak_bytes, |
| const u8 *ckn, size_t ckn_len, |
| u8 *ick, size_t ick_bytes); |
| int (*icv_hash)(const u8 *ick, size_t ick_bytes, |
| const u8 *msg, size_t msg_len, u8 *icv); |
| }; |
| |
| #define DEFAULT_MKA_ALG_INDEX 0 |
| |
| /* See IEEE Std 802.1X-2010, 9.16 MKA management */ |
| struct ieee802_1x_mka_participant { |
| /* used for active and potential participant */ |
| struct mka_key_name ckn; |
| struct mka_key cak; |
| bool cached; |
| |
| /* used by management to monitor and control activation */ |
| bool active; |
| bool participant; |
| bool retain; |
| enum mka_created_mode mode; |
| |
| enum activate_ctrl { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate; |
| |
| /* used for active participant */ |
| bool principal; |
| struct dl_list live_peers; |
| struct dl_list potential_peers; |
| |
| /* not defined in IEEE 802.1X */ |
| struct dl_list list; |
| |
| struct mka_key kek; |
| struct mka_key ick; |
| |
| struct ieee802_1x_mka_ki lki; |
| u8 lan; |
| bool ltx; |
| bool lrx; |
| |
| struct ieee802_1x_mka_ki oki; |
| u8 oan; |
| bool otx; |
| bool orx; |
| |
| bool is_key_server; |
| bool is_obliged_key_server; |
| bool can_be_key_server; |
| bool is_elected; |
| |
| struct dl_list sak_list; |
| struct dl_list rxsc_list; |
| |
| struct transmit_sc *txsc; |
| |
| u8 mi[MI_LEN]; |
| u32 mn; |
| |
| /* Current peer MI and SCI during MKPDU processing */ |
| struct ieee802_1x_mka_peer_id current_peer_id; |
| struct ieee802_1x_mka_sci current_peer_sci; |
| |
| time_t cak_life; |
| time_t mka_life; |
| bool to_dist_sak; |
| bool to_use_sak; |
| bool new_sak; |
| |
| bool advised_desired; |
| enum macsec_cap advised_capability; |
| |
| struct data_key *new_key; |
| u32 retry_count; |
| |
| struct ieee802_1x_kay *kay; |
| }; |
| |
| struct ieee802_1x_mka_hdr { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| u8 reserve; |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 reserve1:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 reserve1:4; |
| u8 length:4; |
| #else |
| #error "Please fix <bits/endian.h>" |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| } STRUCT_PACKED; |
| |
| #define MKA_HDR_LEN sizeof(struct ieee802_1x_mka_hdr) |
| |
| /** |
| * struct ieee802_1x_mka_basic_body - Basic Parameter Set (Figure 11-8) |
| * @version: MKA Version Identifier |
| * @priority: Key Server Priority |
| * @length: Parameter set body length |
| * @macsec_capability: MACsec capability, as defined in ieee802_1x_defs.h |
| * @macsec_desired: the participant wants MACsec to be used to protect frames |
| * (9.6.1) |
| * @key_server: the participant has not decided that another participant is or |
| * will be the key server (9.5.1) |
| * @length1: Parameter set body length (cont) |
| * @actor_mi: Actor's Member Identifier |
| * @actor_mn: Actor's Message Number |
| * @algo_agility: Algorithm Agility parameter |
| * @ckn: CAK Name |
| */ |
| struct ieee802_1x_mka_basic_body { |
| /* octet 1 */ |
| u8 version; |
| /* octet 2 */ |
| u8 priority; |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 macsec_capability:2; |
| u8 macsec_desired:1; |
| u8 key_server:1; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 key_server:1; |
| u8 macsec_desired:1; |
| u8 macsec_capability:2; |
| u8 length:4; |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| |
| struct ieee802_1x_mka_sci actor_sci; |
| u8 actor_mi[MI_LEN]; |
| be32 actor_mn; |
| u8 algo_agility[4]; |
| |
| /* followed by CAK Name */ |
| u8 ckn[0]; |
| } STRUCT_PACKED; |
| |
| /** |
| * struct ieee802_1x_mka_peer_body - Live Peer List and Potential Peer List |
| * parameter sets (Figure 11-9) |
| * @type: Parameter set type (1 or 2) |
| * @length: Parameter set body length |
| * @length1: Parameter set body length (cont) |
| * @peer: array of (MI, MN) pairs |
| */ |
| struct ieee802_1x_mka_peer_body { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| u8 reserve; |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 reserve1:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 reserve1:4; |
| u8 length:4; |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| |
| /* followed by Peers */ |
| u8 peer[0]; |
| } STRUCT_PACKED; |
| |
| /** |
| * struct ieee802_1x_mka_sak_use_body - MACsec SAK Use parameter set (Figure |
| * 11-10) |
| * @type: MKA message type |
| * @lan: latest key AN |
| * @ltx: latest key TX |
| * @lrx: latest key RX |
| * @oan: old key AN |
| * @otx: old key TX |
| * @orx: old key RX |
| * @ptx: plain TX, ie protectFrames is False |
| * @prx: plain RX, ie validateFrames is not Strict |
| * @delay_protect: True if LPNs are being reported sufficiently frequently to |
| * allow the recipient to provide data delay protection. If False, the LPN |
| * can be reported as zero. |
| * @lsrv_mi: latest key server MI |
| * @lkn: latest key number (together with MI, form the KI) |
| * @llpn: latest lowest acceptable PN (LPN) |
| * @osrv_mi: old key server MI |
| * @okn: old key number (together with MI, form the KI) |
| * @olpn: old lowest acceptable PN (LPN) |
| */ |
| struct ieee802_1x_mka_sak_use_body { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 orx:1; |
| u8 otx:1; |
| u8 oan:2; |
| u8 lrx:1; |
| u8 ltx:1; |
| u8 lan:2; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 lan:2; |
| u8 ltx:1; |
| u8 lrx:1; |
| u8 oan:2; |
| u8 otx:1; |
| u8 orx:1; |
| #endif |
| |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 delay_protect:1; |
| u8 reserve:1; |
| u8 prx:1; |
| u8 ptx:1; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 ptx:1; |
| u8 prx:1; |
| u8 reserve:1; |
| u8 delay_protect:1; |
| u8 length:4; |
| #endif |
| |
| /* octet 4 */ |
| u8 length1; |
| |
| /* octet 5 - 16 */ |
| u8 lsrv_mi[MI_LEN]; |
| /* octet 17 - 20 */ |
| be32 lkn; |
| /* octet 21 - 24 */ |
| be32 llpn; |
| |
| /* octet 25 - 36 */ |
| u8 osrv_mi[MI_LEN]; |
| /* octet 37 - 40 */ |
| be32 okn; |
| /* octet 41 - 44 */ |
| be32 olpn; |
| } STRUCT_PACKED; |
| |
| /** |
| * struct ieee802_1x_mka_dist_sak_body - Distributed SAK parameter set |
| * (GCM-AES-128, Figure 11-11) |
| * @type: Parameter set type (4) |
| * @length: Parameter set body length |
| * @length1: Parameter set body length (cont) |
| * Total parameter body length values: |
| * - 0 for plain text |
| * - 28 for GCM-AES-128 |
| * - 36 or more for other cipher suites |
| * @confid_offset: confidentiality offset, as defined in ieee802_1x_defs.h |
| * @dan: distributed AN (0 for plain text) |
| * @kn: Key Number |
| * @sak: AES Key Wrap of SAK (see 9.8) |
| */ |
| struct ieee802_1x_mka_dist_sak_body { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 reserve:4; |
| u8 confid_offset:2; |
| u8 dan:2; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 dan:2; |
| u8 confid_offset:2; |
| u8 reserve:4; |
| #endif |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 reserve1:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 reserve1:4; |
| u8 length:4; |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| /* octet 5 - 8 */ |
| be32 kn; |
| |
| /* for GCM-AES-128: octet 9-32: SAK |
| * for other cipher suite: octet 9-16: cipher suite id, octet 17-: SAK |
| */ |
| u8 sak[0]; |
| } STRUCT_PACKED; |
| |
| /** |
| * struct ieee802_1x_mka_dist_cak_body - Distributed CAK parameter set (Figure |
| * 11-13) |
| * @type: Parameter set type (5) |
| * @length: Parameter set body length |
| * @length1: Parameter set body length (cont) |
| * Total parameter body length values: |
| * - 0 for plain text |
| * - 28 for GCM-AES-128 |
| * - 36 or more for other cipher suites |
| * @cak: AES Key Wrap of CAK (see 9.8) |
| * @ckn: CAK Name |
| */ |
| struct ieee802_1x_mka_dist_cak_body { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| u8 reserve; |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 reserve1:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 reserve1:4; |
| u8 length:4; |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| |
| /* octet 5 - 28 */ |
| u8 cak[24]; |
| |
| /* followed by CAK Name, 29- */ |
| u8 ckn[0]; |
| } STRUCT_PACKED; |
| |
| struct ieee802_1x_mka_icv_body { |
| /* octet 1 */ |
| u8 type; |
| /* octet 2 */ |
| u8 reserve; |
| /* octet 3 */ |
| #if __BYTE_ORDER == __LITTLE_ENDIAN |
| u8 length:4; |
| u8 reserve1:4; |
| #elif __BYTE_ORDER == __BIG_ENDIAN |
| u8 reserve1:4; |
| u8 length:4; |
| #endif |
| /* octet 4 */ |
| u8 length1; |
| |
| /* octet 5 - */ |
| u8 icv[0]; |
| } STRUCT_PACKED; |
| |
| #endif /* IEEE802_1X_KAY_I_H */ |