/*
* 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 */
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];
u32 mn;
};
struct ieee802_1x_kay_peer {
struct ieee802_1x_mka_sci sci;
u8 mi[MI_LEN];
u32 mn;
time_t expire;
Boolean is_key_server;
u8 key_server_priority;
Boolean macsec_desired;
enum macsec_cap macsec_capbility;
Boolean sak_used;
struct dl_list list;
};
struct key_conf {
u8 *key;
struct ieee802_1x_mka_ki ki;
enum confidentiality_offset offset;
u8 an;
Boolean tx;
Boolean rx;
int key_len; /* unit: byte */
};
struct data_key {
u8 *key;
int key_len;
struct ieee802_1x_mka_ki key_identifier;
enum confidentiality_offset confidentiality_offset;
u8 an;
Boolean transmits;
Boolean receives;
struct os_time created_time;
u32 next_pn;
/* not defined data */
Boolean rx_latest;
Boolean tx_latest;
int user; /* FIXME: to indicate if it can be delete safely */
struct dl_list list;
};
/* TransmitSC in IEEE Std 802.1AE-2006, Figure 10-6 */
struct transmit_sc {
struct ieee802_1x_mka_sci sci; /* const SCI sci */
Boolean transmitting; /* bool transmitting (read only) */
struct os_time created_time; /* Time createdTime */
u8 encoding_sa; /* AN encodingSA (read only) */
u8 enciphering_sa; /* AN encipheringSA (read only) */
/* not defined data */
unsigned int channel;
struct dl_list list;
struct dl_list sa_list;
};
/* TransmitSA in IEEE Std 802.1AE-2006, Figure 10-6 */
struct transmit_sa {
Boolean in_use; /* bool inUse (read only) */
u32 next_pn; /* PN nextPN (read only) */
struct os_time created_time; /* Time createdTime */
Boolean enable_transmit; /* bool EnableTransmit */
u8 an;
Boolean confidentiality;
struct data_key *pkey;
struct transmit_sc *sc;
struct dl_list list; /* list entry in struct transmit_sc::sa_list */
};
/* ReceiveSC in IEEE Std 802.1AE-2006, Figure 10-6 */
struct receive_sc {
struct ieee802_1x_mka_sci sci; /* const SCI sci */
Boolean receiving; /* bool receiving (read only) */
struct os_time created_time; /* Time createdTime */
unsigned int channel;
struct dl_list list;
struct dl_list sa_list;
};
/* ReceiveSA in IEEE Std 802.1AE-2006, Figure 10-6 */
struct receive_sa {
Boolean enable_receive; /* bool enableReceive */
Boolean in_use; /* bool inUse (read only) */
u32 next_pn; /* PN nextPN (read only) */
u32 lowest_pn; /* PN lowestPN (read only) */
u8 an;
struct os_time created_time;
struct data_key *pkey;
struct receive_sc *sc; /* list entry in struct receive_sc::sa_list */
struct dl_list list;
};
struct macsec_ciphersuite {
u8 id[CS_ID_LEN];
char name[32];
enum macsec_cap capable;
int sak_len; /* unit: byte */
u32 index;
};
struct mka_alg {
u8 parameter[4];
size_t cak_len;
size_t kek_len;
size_t ick_len;
size_t icv_len;
int (*cak_trfm)(const u8 *msk, const u8 *mac1, const u8 *mac2, u8 *cak);
int (*ckn_trfm)(const u8 *msk, const u8 *mac1, const u8 *mac2,
const u8 *sid, size_t sid_len, u8 *ckn);
int (*kek_trfm)(const u8 *cak, const u8 *ckn, size_t ckn_len, u8 *kek);
int (*ick_trfm)(const u8 *cak, const u8 *ckn, size_t ckn_len, u8 *ick);
int (*icv_hash)(const u8 *ick, const u8 *msg, size_t msg_len, u8 *icv);
int index; /* index for configuring */
};
#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;
Boolean cached;
/* used by management to monitor and control activation */
Boolean active;
Boolean participant;
Boolean retain;
enum { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate;
/* used for active participant */
Boolean 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;
Boolean ltx;
Boolean lrx;
struct ieee802_1x_mka_ki oki;
u8 oan;
Boolean otx;
Boolean orx;
Boolean is_key_server;
Boolean is_obliged_key_server;
Boolean can_be_key_server;
Boolean is_elected;
struct dl_list sak_list;
struct dl_list rxsc_list;
struct transmit_sc *txsc;
u8 mi[MI_LEN];
u32 mn;
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;
Boolean to_dist_sak;
Boolean to_use_sak;
Boolean new_sak;
Boolean 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 */
u32 type:8;
/* octet 2 */
u32 reserve:8;
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 reserve1:4;
u32 length:4;
#else
#error "Please fix <bits/endian.h>"
#endif
/* octet 4 */
u32 length1:8;
};
#define MKA_HDR_LEN sizeof(struct ieee802_1x_mka_hdr)
struct ieee802_1x_mka_basic_body {
/* octet 1 */
u32 version:8;
/* octet 2 */
u32 priority:8;
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 macsec_capbility:2;
u32 macsec_desired:1;
u32 key_server:1;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 key_server:1;
u32 macsec_desired:1;
u32 macsec_capbility:2;
u32 length:4;
#endif
/* octet 4 */
u32 length1:8;
struct ieee802_1x_mka_sci actor_sci;
u8 actor_mi[MI_LEN];
u32 actor_mn;
u8 algo_agility[4];
/* followed by CAK Name*/
u8 ckn[0];
};
struct ieee802_1x_mka_peer_body {
/* octet 1 */
u32 type:8;
/* octet 2 */
u32 reserve:8;
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 reserve1:4;
u32 length:4;
#endif
/* octet 4 */
u32 length1:8;
u8 peer[0];
/* followed by Peers */
};
struct ieee802_1x_mka_sak_use_body {
/* octet 1 */
u32 type:8;
/* octet 2 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 orx:1;
u32 otx:1;
u32 oan:2;
u32 lrx:1;
u32 ltx:1;
u32 lan:2;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 lan:2;
u32 ltx:1;
u32 lrx:1;
u32 oan:2;
u32 otx:1;
u32 orx:1;
#endif
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 delay_protect:1;
u32 reserve:1;
u32 prx:1;
u32 ptx:1;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 ptx:1;
u32 prx:1;
u32 reserve:1;
u32 delay_protect:1;
u32 length:4;
#endif
/* octet 4 */
u32 length1:8;
/* octet 5 - 16 */
u8 lsrv_mi[MI_LEN];
/* octet 17 - 20 */
u32 lkn;
/* octet 21 - 24 */
u32 llpn;
/* octet 25 - 36 */
u8 osrv_mi[MI_LEN];
/* octet 37 - 40 */
u32 okn;
/* octet 41 - 44 */
u32 olpn;
};
struct ieee802_1x_mka_dist_sak_body {
/* octet 1 */
u32 type:8;
/* octet 2 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 reserve:4;
u32 confid_offset:2;
u32 dan:2;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 dan:2;
u32 confid_offset:2;
u32 reserve:4;
#endif
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 reserve1:4;
u32 length:4;
#endif
/* octet 4 */
u32 length1:8;
/* octet 5 - 8 */
u32 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 ieee802_1x_mka_icv_body {
/* octet 1 */
u32 type:8;
/* octet 2 */
u32 reserve:8;
/* octet 3 */
#if __BYTE_ORDER == __LITTLE_ENDIAN
u32 length:4;
u32 reserve1:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
u32 reserve1:4;
u32 length:4;
#endif
/* octet 4 */
u32 length1:8;
/* octet 5 - */
u8 icv[0];
};
#endif /* IEEE802_1X_KAY_I_H */