From 29c832d0ea4fdac45e8433c1d4e84791f5e640c3 Mon Sep 17 00:00:00 2001 From: leiwei Date: Fri, 24 May 2019 15:26:46 +0800 Subject: [PATCH] macsec: Add configuration parameters for hostapd Signed-off-by: leiwei --- hostapd/config_file.c | 87 ++++++++++++++++++++++++++++++++++++++++++ hostapd/hostapd.conf | 50 ++++++++++++++++++++++++ src/ap/ap_config.c | 6 +++ src/ap/ap_config.h | 89 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index c236cf4ee..c4106c128 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2562,7 +2562,11 @@ static int hostapd_config_fill(struct hostapd_config *conf, } else if (os_strcmp(buf, "eapol_version") == 0) { int eapol_version = atoi(pos); +#ifdef CONFIG_MACSEC + if (eapol_version < 1 || eapol_version > 3) { +#else /* CONFIG_MACSEC */ if (eapol_version < 1 || eapol_version > 2) { +#endif /* CONFIG_MACSEC */ wpa_printf(MSG_ERROR, "Line %d: invalid EAPOL version (%d): '%s'.", line, eapol_version, pos); @@ -4468,6 +4472,89 @@ static int hostapd_config_fill(struct hostapd_config *conf, return 1; } #endif /* CONFIG_AIRTIME_POLICY */ +#ifdef CONFIG_MACSEC + } else if (os_strcmp(buf, "macsec_policy") == 0) { + int macsec_policy = atoi(pos); + + if (macsec_policy < 0 || macsec_policy > 1) { + wpa_printf(MSG_ERROR, + "Line %d: invalid macsec_policy (%d): '%s'.", + line, macsec_policy, pos); + return 1; + } + bss->macsec_policy = macsec_policy; + } else if (os_strcmp(buf, "macsec_integ_only") == 0) { + int macsec_integ_only = atoi(pos); + + if (macsec_integ_only < 0 || macsec_integ_only > 1) { + wpa_printf(MSG_ERROR, + "Line %d: invalid macsec_integ_only (%d): '%s'.", + line, macsec_integ_only, pos); + return 1; + } + bss->macsec_integ_only = macsec_integ_only; + } else if (os_strcmp(buf, "macsec_replay_protect") == 0) { + int macsec_replay_protect = atoi(pos); + + if (macsec_replay_protect < 0 || macsec_replay_protect > 1) { + wpa_printf(MSG_ERROR, + "Line %d: invalid macsec_replay_protect (%d): '%s'.", + line, macsec_replay_protect, pos); + return 1; + } + bss->macsec_replay_protect = macsec_replay_protect; + } else if (os_strcmp(buf, "macsec_replay_window") == 0) { + bss->macsec_replay_window = atoi(pos); + } else if (os_strcmp(buf, "macsec_port") == 0) { + int macsec_port = atoi(pos); + + if (macsec_port < 1 || macsec_port > 65534) { + wpa_printf(MSG_ERROR, + "Line %d: invalid macsec_port (%d): '%s'.", + line, macsec_port, pos); + return 1; + } + bss->macsec_port = macsec_port; + } else if (os_strcmp(buf, "mka_priority") == 0) { + int mka_priority = atoi(pos); + + if (mka_priority < 0 || mka_priority > 255) { + wpa_printf(MSG_ERROR, + "Line %d: invalid mka_priority (%d): '%s'.", + line, mka_priority, pos); + return 1; + } + bss->mka_priority = mka_priority; + } else if (os_strcmp(buf, "mka_cak") == 0) { + size_t len = os_strlen(pos); + + if (len > 2 * MACSEC_CAK_MAX_LEN || + (len != 2 * 16 && len != 2 * 32) || + hexstr2bin(pos, bss->mka_cak, len / 2)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CAK '%s'.", + line, pos); + return 1; + } + bss->mka_cak_len = len / 2; + bss->mka_psk_set |= MKA_PSK_SET_CAK; + } else if (os_strcmp(buf, "mka_ckn") == 0) { + size_t len = os_strlen(pos); + + if (len > 2 * MACSEC_CKN_MAX_LEN || /* too long */ + len < 2 || /* too short */ + len % 2 != 0 /* not an integral number of bytes */) { + wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.", + line, pos); + return 1; + } + bss->mka_ckn_len = len / 2; + if (hexstr2bin(pos, bss->mka_ckn, bss->mka_ckn_len)) { + wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.", + line, pos); + return -1; + } + bss->mka_psk_set |= MKA_PSK_SET_CKN; +#endif /* CONFIG_MACSEC */ } else { wpa_printf(MSG_ERROR, "Line %d: unknown configuration item '%s'", diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf index 124288614..71e577a89 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -851,6 +851,8 @@ wmm_ac_vo_acm=0 # the new version number correctly (they seem to drop the frames completely). # In order to make hostapd interoperate with these clients, the version number # can be set to the older version (1) with this configuration value. +# Note: When using MACsec, eapol_version shall be set to 3, which is +# defined in IEEE Std 802.1X-2010. #eapol_version=2 # Optional displayable message sent with EAP Request-Identity. The first \0 @@ -894,6 +896,54 @@ eapol_key_index_workaround=0 # ERP is enabled (eap_server_erp=1). #erp_domain=example.com +##### MACsec ################################################################## + +# macsec_policy: IEEE 802.1X/MACsec options +# This determines how sessions are secured with MACsec (only for MACsec +# drivers). +# 0: MACsec not in use (default) +# 1: MACsec enabled - Should secure, accept key server's advice to +# determine whether to use a secure session or not. +# +# macsec_integ_only: IEEE 802.1X/MACsec transmit mode +# This setting applies only when MACsec is in use, i.e., +# - macsec_policy is enabled +# - the key server has decided to enable MACsec +# 0: Encrypt traffic (default) +# 1: Integrity only +# +# macsec_replay_protect: IEEE 802.1X/MACsec replay protection +# This setting applies only when MACsec is in use, i.e., +# - macsec_policy is enabled +# - the key server has decided to enable MACsec +# 0: Replay protection disabled (default) +# 1: Replay protection enabled +# +# macsec_replay_window: IEEE 802.1X/MACsec replay protection window +# This determines a window in which replay is tolerated, to allow receipt +# of frames that have been misordered by the network. +# This setting applies only when MACsec replay protection active, i.e., +# - macsec_replay_protect is enabled +# - the key server has decided to enable MACsec +# 0: No replay window, strict check (default) +# 1..2^32-1: number of packets that could be misordered +# +# macsec_port: IEEE 802.1X/MACsec port +# Port component of the SCI +# Range: 1-65534 (default: 1) +# +# mka_priority (Priority of MKA Actor) +# Range: 0..255 (default: 255) +# +# mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode +# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. +# In this mode, instances of hostapd can act as MACsec peers. The peer +# with lower priority will become the key server and start distributing SAKs. +# mka_cak (CAK = Secure Connectivity Association Key) takes a 16-byte (128-bit) +# hex-string (32 hex-digits) or a 32-byte (256-bit) hex-string (64 hex-digits) +# mka_ckn (CKN = CAK Name) takes a 1..32-bytes (8..256 bit) hex-string +# (2..64 hex-digits) + ##### Integrated EAP server ################################################### # Optionally, hostapd can be configured to use an integrated EAP server diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c index eecd215af..48d09bcf9 100644 --- a/src/ap/ap_config.c +++ b/src/ap/ap_config.c @@ -13,6 +13,7 @@ #include "crypto/tls.h" #include "radius/radius_client.h" #include "common/ieee802_11_defs.h" +#include "common/ieee802_1x_defs.h" #include "common/eapol_common.h" #include "common/dhcp.h" #include "eap_common/eap_wsc_common.h" @@ -139,6 +140,11 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss) bss->hs20_release = (HS20_VERSION >> 4) + 1; #endif /* CONFIG_HS20 */ +#ifdef CONFIG_MACSEC + bss->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER; + bss->macsec_port = 1; +#endif /* CONFIG_MACSEC */ + /* Default to strict CRL checking. */ bss->check_crl_strict = 1; } diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 30c4b65aa..fc6524c9e 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -583,6 +583,7 @@ struct hostapd_bss_config { int osen; int proxy_arp; int na_mcast_to_ucast; + #ifdef CONFIG_HS20 int hs20; int hs20_release; @@ -731,6 +732,94 @@ struct hostapd_bss_config { int airtime_limit; struct airtime_sta_weight *airtime_weight_list; #endif /* CONFIG_AIRTIME_POLICY */ + +#ifdef CONFIG_MACSEC + /** + * macsec_policy - Determines the policy for MACsec secure session + * + * 0: MACsec not in use (default) + * 1: MACsec enabled - Should secure, accept key server's advice to + * determine whether to use a secure session or not. + */ + int macsec_policy; + + /** + * macsec_integ_only - Determines how MACsec are transmitted + * + * This setting applies only when MACsec is in use, i.e., + * - macsec_policy is enabled + * - the key server has decided to enable MACsec + * + * 0: Encrypt traffic (default) + * 1: Integrity only + */ + int macsec_integ_only; + + /** + * macsec_replay_protect - Enable MACsec replay protection + * + * This setting applies only when MACsec is in use, i.e., + * - macsec_policy is enabled + * - the key server has decided to enable MACsec + * + * 0: Replay protection disabled (default) + * 1: Replay protection enabled + */ + int macsec_replay_protect; + + /** + * macsec_replay_window - MACsec replay protection window + * + * A window in which replay is tolerated, to allow receipt of frames + * that have been misordered by the network. + * + * This setting applies only when MACsec replay protection active, i.e., + * - macsec_replay_protect is enabled + * - the key server has decided to enable MACsec + * + * 0: No replay window, strict check (default) + * 1..2^32-1: number of packets that could be misordered + */ + u32 macsec_replay_window; + + /** + * macsec_port - MACsec port (in SCI) + * + * Port component of the SCI. + * + * Range: 1-65534 (default: 1) + */ + int macsec_port; + + /** + * mka_priority - Priority of MKA Actor + * + * Range: 0-255 (default: 255) + */ + int mka_priority; + + /** + * mka_ckn - MKA pre-shared CKN + */ +#define MACSEC_CKN_MAX_LEN 32 + size_t mka_ckn_len; + u8 mka_ckn[MACSEC_CKN_MAX_LEN]; + + /** + * mka_cak - MKA pre-shared CAK + */ +#define MACSEC_CAK_MAX_LEN 32 + size_t mka_cak_len; + u8 mka_cak[MACSEC_CAK_MAX_LEN]; + +#define MKA_PSK_SET_CKN BIT(0) +#define MKA_PSK_SET_CAK BIT(1) +#define MKA_PSK_SET (MKA_PSK_SET_CKN | MKA_PSK_SET_CAK) + /** + * mka_psk_set - Whether mka_ckn and mka_cak are set + */ + u8 mka_psk_set; +#endif /* CONFIG_MACSEC */ }; /**