From 41389ac197f405de674bd7794fb1309f9de10e2f Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 02 2019 17:07:18 +0000 Subject: import wpa_supplicant-2.6-12.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8df909d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/wpa_supplicant-2.6.tar.gz diff --git a/.wpa_supplicant.metadata b/.wpa_supplicant.metadata new file mode 100644 index 0000000..be49793 --- /dev/null +++ b/.wpa_supplicant.metadata @@ -0,0 +1 @@ +8189704e257c3e9f8300c49dc6e49a381b1d6299 SOURCES/wpa_supplicant-2.6.tar.gz diff --git a/SOURCES/build-config b/SOURCES/build-config new file mode 100644 index 0000000..81cf22f --- /dev/null +++ b/SOURCES/build-config @@ -0,0 +1,40 @@ +CONFIG_CTRL_IFACE=y +CONFIG_CTRL_IFACE_DBUS=y +CONFIG_CTRL_IFACE_DBUS_NEW=y +CONFIG_CTRL_IFACE_DBUS_INTRO=y +CONFIG_DRIVER_WEXT=y +CONFIG_LIBNL32=y +CONFIG_DRIVER_NL80211=y +CONFIG_DRIVER_WIRED=y +CONFIG_DRIVER_MACSEC_LINUX=y +CONFIG_IEEE8021X_EAPOL=y +CONFIG_EAP_MD5=y +CONFIG_EAP_MSCHAPV2=y +CONFIG_EAP_TLS=y +CONFIG_EAP_PEAP=y +CONFIG_EAP_TTLS=y +CONFIG_EAP_FAST=y +CONFIG_EAP_GTC=y +CONFIG_EAP_OTP=y +CONFIG_EAP_AKA=y +CONFIG_EAP_PAX=y +CONFIG_EAP_LEAP=y +CONFIG_EAP_SAKE=y +CONFIG_EAP_GPSK=y +CONFIG_EAP_GPSK_SHA256=y +CONFIG_EAP_TNC=y +CONFIG_WPS=y +CONFIG_EAP_IKEV2=y +CONFIG_PKCS12=y +CONFIG_SMARTCARD=y +CONFIG_DEBUG_FILE=y +CONFIG_BACKEND=file +CONFIG_PEERKEY=y +CONFIG_BGSCAN_SIMPLE=y +#CONFIG_FIPS=y +CONFIG_AP=y +CONFIG_P2P=y +CONFIG_IBSS_RSN=y +CONFIG_IEEE80211N=y +CONFIG_EAPOL_TEST=y +CONFIG_MACSEC=y diff --git a/SOURCES/if_link.h b/SOURCES/if_link.h new file mode 100644 index 0000000..6b13e59 --- /dev/null +++ b/SOURCES/if_link.h @@ -0,0 +1,892 @@ +#ifndef _UAPI_LINUX_IF_LINK_H +#define _UAPI_LINUX_IF_LINK_H + +#include +#include + +/* This struct should be in sync with struct rtnl_link_stats64 */ +struct rtnl_link_stats { + __u32 rx_packets; /* total packets received */ + __u32 tx_packets; /* total packets transmitted */ + __u32 rx_bytes; /* total bytes received */ + __u32 tx_bytes; /* total bytes transmitted */ + __u32 rx_errors; /* bad packets received */ + __u32 tx_errors; /* packet transmit problems */ + __u32 rx_dropped; /* no space in linux buffers */ + __u32 tx_dropped; /* no space available in linux */ + __u32 multicast; /* multicast packets received */ + __u32 collisions; + + /* detailed rx_errors: */ + __u32 rx_length_errors; + __u32 rx_over_errors; /* receiver ring buff overflow */ + __u32 rx_crc_errors; /* recved pkt with crc error */ + __u32 rx_frame_errors; /* recv'd frame alignment error */ + __u32 rx_fifo_errors; /* recv'r fifo overrun */ + __u32 rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + __u32 tx_aborted_errors; + __u32 tx_carrier_errors; + __u32 tx_fifo_errors; + __u32 tx_heartbeat_errors; + __u32 tx_window_errors; + + /* for cslip etc */ + __u32 rx_compressed; + __u32 tx_compressed; + + __u32 rx_nohandler; /* dropped, no handler found */ +}; + +/* The main device statistics structure */ +struct rtnl_link_stats64 { + __u64 rx_packets; /* total packets received */ + __u64 tx_packets; /* total packets transmitted */ + __u64 rx_bytes; /* total bytes received */ + __u64 tx_bytes; /* total bytes transmitted */ + __u64 rx_errors; /* bad packets received */ + __u64 tx_errors; /* packet transmit problems */ + __u64 rx_dropped; /* no space in linux buffers */ + __u64 tx_dropped; /* no space available in linux */ + __u64 multicast; /* multicast packets received */ + __u64 collisions; + + /* detailed rx_errors: */ + __u64 rx_length_errors; + __u64 rx_over_errors; /* receiver ring buff overflow */ + __u64 rx_crc_errors; /* recved pkt with crc error */ + __u64 rx_frame_errors; /* recv'd frame alignment error */ + __u64 rx_fifo_errors; /* recv'r fifo overrun */ + __u64 rx_missed_errors; /* receiver missed packet */ + + /* detailed tx_errors */ + __u64 tx_aborted_errors; + __u64 tx_carrier_errors; + __u64 tx_fifo_errors; + __u64 tx_heartbeat_errors; + __u64 tx_window_errors; + + /* for cslip etc */ + __u64 rx_compressed; + __u64 tx_compressed; + + __u64 rx_nohandler; /* dropped, no handler found */ +}; + +/* The struct should be in sync with struct ifmap */ +struct rtnl_link_ifmap { + __u64 mem_start; + __u64 mem_end; + __u64 base_addr; + __u16 irq; + __u8 dma; + __u8 port; +}; + +/* + * IFLA_AF_SPEC + * Contains nested attributes for address family specific attributes. + * Each address family may create a attribute with the address family + * number as type and create its own attribute structure in it. + * + * Example: + * [IFLA_AF_SPEC] = { + * [AF_INET] = { + * [IFLA_INET_CONF] = ..., + * }, + * [AF_INET6] = { + * [IFLA_INET6_FLAGS] = ..., + * [IFLA_INET6_CONF] = ..., + * } + * } + */ + +enum { + IFLA_UNSPEC, + IFLA_ADDRESS, + IFLA_BROADCAST, + IFLA_IFNAME, + IFLA_MTU, + IFLA_LINK, + IFLA_QDISC, + IFLA_STATS, + IFLA_COST, +#define IFLA_COST IFLA_COST + IFLA_PRIORITY, +#define IFLA_PRIORITY IFLA_PRIORITY + IFLA_MASTER, +#define IFLA_MASTER IFLA_MASTER + IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */ +#define IFLA_WIRELESS IFLA_WIRELESS + IFLA_PROTINFO, /* Protocol specific information for a link */ +#define IFLA_PROTINFO IFLA_PROTINFO + IFLA_TXQLEN, +#define IFLA_TXQLEN IFLA_TXQLEN + IFLA_MAP, +#define IFLA_MAP IFLA_MAP + IFLA_WEIGHT, +#define IFLA_WEIGHT IFLA_WEIGHT + IFLA_OPERSTATE, + IFLA_LINKMODE, + IFLA_LINKINFO, +#define IFLA_LINKINFO IFLA_LINKINFO + IFLA_NET_NS_PID, + IFLA_IFALIAS, + IFLA_NUM_VF, /* Number of VFs if device is SR-IOV PF */ + IFLA_VFINFO_LIST, + IFLA_STATS64, + IFLA_VF_PORTS, + IFLA_PORT_SELF, + IFLA_AF_SPEC, + IFLA_GROUP, /* Group the device belongs to */ + IFLA_NET_NS_FD, + IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ + IFLA_PROMISCUITY, /* Promiscuity count: > 0 means acts PROMISC */ +#define IFLA_PROMISCUITY IFLA_PROMISCUITY + IFLA_NUM_TX_QUEUES, + IFLA_NUM_RX_QUEUES, + IFLA_CARRIER, + IFLA_PHYS_PORT_ID, + IFLA_CARRIER_CHANGES, + IFLA_PHYS_SWITCH_ID, + IFLA_LINK_NETNSID, + IFLA_PHYS_PORT_NAME, + IFLA_PROTO_DOWN, + IFLA_GSO_MAX_SEGS, + IFLA_GSO_MAX_SIZE, + IFLA_PAD, + IFLA_XDP, + __IFLA_MAX +}; + + +#define IFLA_MAX (__IFLA_MAX - 1) + +/* backwards compatibility for userspace */ +#ifndef __KERNEL__ +#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) +#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg)) +#endif + +enum { + IFLA_INET_UNSPEC, + IFLA_INET_CONF, + __IFLA_INET_MAX, +}; + +#define IFLA_INET_MAX (__IFLA_INET_MAX - 1) + +/* ifi_flags. + + IFF_* flags. + + The only change is: + IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are + more not changeable by user. They describe link media + characteristics and set by device driver. + + Comments: + - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid + - If neither of these three flags are set; + the interface is NBMA. + + - IFF_MULTICAST does not mean anything special: + multicasts can be used on all not-NBMA links. + IFF_MULTICAST means that this media uses special encapsulation + for multicast frames. Apparently, all IFF_POINTOPOINT and + IFF_BROADCAST devices are able to use multicasts too. + */ + +/* IFLA_LINK. + For usual devices it is equal ifi_index. + If it is a "virtual interface" (f.e. tunnel), ifi_link + can point to real physical interface (f.e. for bandwidth calculations), + or maybe 0, what means, that real media is unknown (usual + for IPIP tunnels, when route to endpoint is allowed to change) + */ + +/* Subtype attributes for IFLA_PROTINFO */ +enum { + IFLA_INET6_UNSPEC, + IFLA_INET6_FLAGS, /* link flags */ + IFLA_INET6_CONF, /* sysctl parameters */ + IFLA_INET6_STATS, /* statistics */ + IFLA_INET6_MCAST, /* MC things. What of them? */ + IFLA_INET6_CACHEINFO, /* time values and max reasm size */ + IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ + IFLA_INET6_TOKEN, /* device token */ + IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */ + __IFLA_INET6_MAX +}; + +#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1) + +enum in6_addr_gen_mode { + IN6_ADDR_GEN_MODE_EUI64, + IN6_ADDR_GEN_MODE_NONE, + IN6_ADDR_GEN_MODE_STABLE_PRIVACY, + IN6_ADDR_GEN_MODE_RANDOM, +}; + +/* Bridge section */ + +enum { + IFLA_BR_UNSPEC, + IFLA_BR_FORWARD_DELAY, + IFLA_BR_HELLO_TIME, + IFLA_BR_MAX_AGE, + IFLA_BR_AGEING_TIME, + IFLA_BR_STP_STATE, + IFLA_BR_PRIORITY, + IFLA_BR_VLAN_FILTERING, + IFLA_BR_VLAN_PROTOCOL, + IFLA_BR_GROUP_FWD_MASK, + IFLA_BR_ROOT_ID, + IFLA_BR_BRIDGE_ID, + IFLA_BR_ROOT_PORT, + IFLA_BR_ROOT_PATH_COST, + IFLA_BR_TOPOLOGY_CHANGE, + IFLA_BR_TOPOLOGY_CHANGE_DETECTED, + IFLA_BR_HELLO_TIMER, + IFLA_BR_TCN_TIMER, + IFLA_BR_TOPOLOGY_CHANGE_TIMER, + IFLA_BR_GC_TIMER, + IFLA_BR_GROUP_ADDR, + IFLA_BR_FDB_FLUSH, + IFLA_BR_MCAST_ROUTER, + IFLA_BR_MCAST_SNOOPING, + IFLA_BR_MCAST_QUERY_USE_IFADDR, + IFLA_BR_MCAST_QUERIER, + IFLA_BR_MCAST_HASH_ELASTICITY, + IFLA_BR_MCAST_HASH_MAX, + IFLA_BR_MCAST_LAST_MEMBER_CNT, + IFLA_BR_MCAST_STARTUP_QUERY_CNT, + IFLA_BR_MCAST_LAST_MEMBER_INTVL, + IFLA_BR_MCAST_MEMBERSHIP_INTVL, + IFLA_BR_MCAST_QUERIER_INTVL, + IFLA_BR_MCAST_QUERY_INTVL, + IFLA_BR_MCAST_QUERY_RESPONSE_INTVL, + IFLA_BR_MCAST_STARTUP_QUERY_INTVL, + IFLA_BR_NF_CALL_IPTABLES, + IFLA_BR_NF_CALL_IP6TABLES, + IFLA_BR_NF_CALL_ARPTABLES, + IFLA_BR_VLAN_DEFAULT_PVID, + IFLA_BR_PAD, + IFLA_BR_VLAN_STATS_ENABLED, + IFLA_BR_MCAST_STATS_ENABLED, + IFLA_BR_MCAST_IGMP_VERSION, + IFLA_BR_MCAST_MLD_VERSION, + __IFLA_BR_MAX, +}; + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) + +struct ifla_bridge_id { + __u8 prio[2]; + __u8 addr[6]; /* ETH_ALEN */ +}; + +enum { + BRIDGE_MODE_UNSPEC, + BRIDGE_MODE_HAIRPIN, +}; + +enum { + IFLA_BRPORT_UNSPEC, + IFLA_BRPORT_STATE, /* Spanning tree state */ + IFLA_BRPORT_PRIORITY, /* " priority */ + IFLA_BRPORT_COST, /* " cost */ + IFLA_BRPORT_MODE, /* mode (hairpin) */ + IFLA_BRPORT_GUARD, /* bpdu guard */ + IFLA_BRPORT_PROTECT, /* root port protection */ + IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */ + IFLA_BRPORT_LEARNING, /* mac learning */ + IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */ + IFLA_BRPORT_PROXYARP, /* proxy ARP */ + IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */ + IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */ + IFLA_BRPORT_ROOT_ID, /* designated root */ + IFLA_BRPORT_BRIDGE_ID, /* designated bridge */ + IFLA_BRPORT_DESIGNATED_PORT, + IFLA_BRPORT_DESIGNATED_COST, + IFLA_BRPORT_ID, + IFLA_BRPORT_NO, + IFLA_BRPORT_TOPOLOGY_CHANGE_ACK, + IFLA_BRPORT_CONFIG_PENDING, + IFLA_BRPORT_MESSAGE_AGE_TIMER, + IFLA_BRPORT_FORWARD_DELAY_TIMER, + IFLA_BRPORT_HOLD_TIMER, + IFLA_BRPORT_FLUSH, + IFLA_BRPORT_MULTICAST_ROUTER, + IFLA_BRPORT_PAD, + IFLA_BRPORT_MCAST_FLOOD, + __IFLA_BRPORT_MAX +}; +#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) + +struct ifla_cacheinfo { + __u32 max_reasm_len; + __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ + __u32 reachable_time; + __u32 retrans_time; +}; + +enum { + IFLA_INFO_UNSPEC, + IFLA_INFO_KIND, + IFLA_INFO_DATA, + IFLA_INFO_XSTATS, + IFLA_INFO_SLAVE_KIND, + IFLA_INFO_SLAVE_DATA, + __IFLA_INFO_MAX, +}; + +#define IFLA_INFO_MAX (__IFLA_INFO_MAX - 1) + +/* VLAN section */ + +enum { + IFLA_VLAN_UNSPEC, + IFLA_VLAN_ID, + IFLA_VLAN_FLAGS, + IFLA_VLAN_EGRESS_QOS, + IFLA_VLAN_INGRESS_QOS, + IFLA_VLAN_PROTOCOL, + __IFLA_VLAN_MAX, +}; + +#define IFLA_VLAN_MAX (__IFLA_VLAN_MAX - 1) + +struct ifla_vlan_flags { + __u32 flags; + __u32 mask; +}; + +enum { + IFLA_VLAN_QOS_UNSPEC, + IFLA_VLAN_QOS_MAPPING, + __IFLA_VLAN_QOS_MAX +}; + +#define IFLA_VLAN_QOS_MAX (__IFLA_VLAN_QOS_MAX - 1) + +struct ifla_vlan_qos_mapping { + __u32 from; + __u32 to; +}; + +/* MACVLAN section */ +enum { + IFLA_MACVLAN_UNSPEC, + IFLA_MACVLAN_MODE, + IFLA_MACVLAN_FLAGS, + IFLA_MACVLAN_MACADDR_MODE, + IFLA_MACVLAN_MACADDR, + IFLA_MACVLAN_MACADDR_DATA, + IFLA_MACVLAN_MACADDR_COUNT, + __IFLA_MACVLAN_MAX, +}; + +#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1) + +enum macvlan_mode { + MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */ + MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */ + MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */ + MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ + MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */ +}; + +enum macvlan_macaddr_mode { + MACVLAN_MACADDR_ADD, + MACVLAN_MACADDR_DEL, + MACVLAN_MACADDR_FLUSH, + MACVLAN_MACADDR_SET, +}; + +#define MACVLAN_FLAG_NOPROMISC 1 + +/* VRF section */ +enum { + IFLA_VRF_UNSPEC, + IFLA_VRF_TABLE, + __IFLA_VRF_MAX +}; + +#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1) + +enum { + IFLA_VRF_PORT_UNSPEC, + IFLA_VRF_PORT_TABLE, + __IFLA_VRF_PORT_MAX +}; + +#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1) + +/* MACSEC section */ +enum { + IFLA_MACSEC_UNSPEC, + IFLA_MACSEC_SCI, + IFLA_MACSEC_PORT, + IFLA_MACSEC_ICV_LEN, + IFLA_MACSEC_CIPHER_SUITE, + IFLA_MACSEC_WINDOW, + IFLA_MACSEC_ENCODING_SA, + IFLA_MACSEC_ENCRYPT, + IFLA_MACSEC_PROTECT, + IFLA_MACSEC_INC_SCI, + IFLA_MACSEC_ES, + IFLA_MACSEC_SCB, + IFLA_MACSEC_REPLAY_PROTECT, + IFLA_MACSEC_VALIDATION, + IFLA_MACSEC_PAD, + __IFLA_MACSEC_MAX, +}; + +#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1) + +enum macsec_validation_type { + MACSEC_VALIDATE_DISABLED = 0, + MACSEC_VALIDATE_CHECK = 1, + MACSEC_VALIDATE_STRICT = 2, + __MACSEC_VALIDATE_END, + MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1, +}; + +/* IPVLAN section */ +enum { + IFLA_IPVLAN_UNSPEC, + IFLA_IPVLAN_MODE, + __IFLA_IPVLAN_MAX +}; + +#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1) + +enum ipvlan_mode { + IPVLAN_MODE_L2 = 0, + IPVLAN_MODE_L3, + IPVLAN_MODE_L3S, + IPVLAN_MODE_MAX +}; + +/* VXLAN section */ +enum { + IFLA_VXLAN_UNSPEC, + IFLA_VXLAN_ID, + IFLA_VXLAN_GROUP, /* group or remote address */ + IFLA_VXLAN_LINK, + IFLA_VXLAN_LOCAL, + IFLA_VXLAN_TTL, + IFLA_VXLAN_TOS, + IFLA_VXLAN_LEARNING, + IFLA_VXLAN_AGEING, + IFLA_VXLAN_LIMIT, + IFLA_VXLAN_PORT_RANGE, /* source port */ + IFLA_VXLAN_PROXY, + IFLA_VXLAN_RSC, + IFLA_VXLAN_L2MISS, + IFLA_VXLAN_L3MISS, + IFLA_VXLAN_PORT, /* destination port */ + IFLA_VXLAN_GROUP6, + IFLA_VXLAN_LOCAL6, + IFLA_VXLAN_UDP_CSUM, + IFLA_VXLAN_UDP_ZERO_CSUM6_TX, + IFLA_VXLAN_UDP_ZERO_CSUM6_RX, + IFLA_VXLAN_REMCSUM_TX, + IFLA_VXLAN_REMCSUM_RX, + IFLA_VXLAN_GBP, + IFLA_VXLAN_REMCSUM_NOPARTIAL, + IFLA_VXLAN_COLLECT_METADATA, + IFLA_VXLAN_LABEL, + IFLA_VXLAN_GPE, + __IFLA_VXLAN_MAX +}; +#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) + +struct ifla_vxlan_port_range { + __be16 low; + __be16 high; +}; + +/* GENEVE section */ +enum { + IFLA_GENEVE_UNSPEC, + IFLA_GENEVE_ID, + IFLA_GENEVE_REMOTE, + IFLA_GENEVE_TTL, + IFLA_GENEVE_TOS, + IFLA_GENEVE_PORT, /* destination port */ + IFLA_GENEVE_COLLECT_METADATA, + IFLA_GENEVE_REMOTE6, + IFLA_GENEVE_UDP_CSUM, + IFLA_GENEVE_UDP_ZERO_CSUM6_TX, + IFLA_GENEVE_UDP_ZERO_CSUM6_RX, + IFLA_GENEVE_LABEL, + __IFLA_GENEVE_MAX +}; +#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1) + +/* PPP section */ +enum { + IFLA_PPP_UNSPEC, + IFLA_PPP_DEV_FD, + __IFLA_PPP_MAX +}; +#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1) + +/* GTP section */ +enum { + IFLA_GTP_UNSPEC, + IFLA_GTP_FD0, + IFLA_GTP_FD1, + IFLA_GTP_PDP_HASHSIZE, + __IFLA_GTP_MAX, +}; +#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1) + +/* Bonding section */ + +enum { + IFLA_BOND_UNSPEC, + IFLA_BOND_MODE, + IFLA_BOND_ACTIVE_SLAVE, + IFLA_BOND_MIIMON, + IFLA_BOND_UPDELAY, + IFLA_BOND_DOWNDELAY, + IFLA_BOND_USE_CARRIER, + IFLA_BOND_ARP_INTERVAL, + IFLA_BOND_ARP_IP_TARGET, + IFLA_BOND_ARP_VALIDATE, + IFLA_BOND_ARP_ALL_TARGETS, + IFLA_BOND_PRIMARY, + IFLA_BOND_PRIMARY_RESELECT, + IFLA_BOND_FAIL_OVER_MAC, + IFLA_BOND_XMIT_HASH_POLICY, + IFLA_BOND_RESEND_IGMP, + IFLA_BOND_NUM_PEER_NOTIF, + IFLA_BOND_ALL_SLAVES_ACTIVE, + IFLA_BOND_MIN_LINKS, + IFLA_BOND_LP_INTERVAL, + IFLA_BOND_PACKETS_PER_SLAVE, + IFLA_BOND_AD_LACP_RATE, + IFLA_BOND_AD_SELECT, + IFLA_BOND_AD_INFO, + IFLA_BOND_AD_ACTOR_SYS_PRIO, + IFLA_BOND_AD_USER_PORT_KEY, + IFLA_BOND_AD_ACTOR_SYSTEM, + IFLA_BOND_TLB_DYNAMIC_LB, + __IFLA_BOND_MAX, +}; + +#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1) + +enum { + IFLA_BOND_AD_INFO_UNSPEC, + IFLA_BOND_AD_INFO_AGGREGATOR, + IFLA_BOND_AD_INFO_NUM_PORTS, + IFLA_BOND_AD_INFO_ACTOR_KEY, + IFLA_BOND_AD_INFO_PARTNER_KEY, + IFLA_BOND_AD_INFO_PARTNER_MAC, + __IFLA_BOND_AD_INFO_MAX, +}; + +#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1) + +enum { + IFLA_BOND_SLAVE_UNSPEC, + IFLA_BOND_SLAVE_STATE, + IFLA_BOND_SLAVE_MII_STATUS, + IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, + IFLA_BOND_SLAVE_PERM_HWADDR, + IFLA_BOND_SLAVE_QUEUE_ID, + IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, + IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, + IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, + __IFLA_BOND_SLAVE_MAX, +}; + +#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_MAX - 1) + +/* SR-IOV virtual function management section */ + +enum { + IFLA_VF_INFO_UNSPEC, + IFLA_VF_INFO, + __IFLA_VF_INFO_MAX, +}; + +#define IFLA_VF_INFO_MAX (__IFLA_VF_INFO_MAX - 1) + +enum { + IFLA_VF_UNSPEC, + IFLA_VF_MAC, /* Hardware queue specific attributes */ + IFLA_VF_VLAN, /* VLAN ID and QoS */ + IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */ + IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */ + IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */ + IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */ + IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query + * on/off switch + */ + IFLA_VF_STATS, /* network device statistics */ + IFLA_VF_TRUST, /* Trust VF */ + IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */ + IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */ + IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */ + __IFLA_VF_MAX, +}; + +#define IFLA_VF_MAX (__IFLA_VF_MAX - 1) + +struct ifla_vf_mac { + __u32 vf; + __u8 mac[32]; /* MAX_ADDR_LEN */ +}; + +struct ifla_vf_vlan { + __u32 vf; + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + __u32 qos; +}; + +enum { + IFLA_VF_VLAN_INFO_UNSPEC, + IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */ + __IFLA_VF_VLAN_INFO_MAX, +}; + +#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1) +#define MAX_VLAN_LIST_LEN 1 + +struct ifla_vf_vlan_info { + __u32 vf; + __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */ + __u32 qos; + __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */ +}; + +struct ifla_vf_tx_rate { + __u32 vf; + __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */ +}; + +struct ifla_vf_rate { + __u32 vf; + __u32 min_tx_rate; /* Min Bandwidth in Mbps */ + __u32 max_tx_rate; /* Max Bandwidth in Mbps */ +}; + +struct ifla_vf_spoofchk { + __u32 vf; + __u32 setting; +}; + +struct ifla_vf_guid { + __u32 vf; + __u64 guid; +}; + +enum { + IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */ + IFLA_VF_LINK_STATE_ENABLE, /* link always up */ + IFLA_VF_LINK_STATE_DISABLE, /* link always down */ + __IFLA_VF_LINK_STATE_MAX, +}; + +struct ifla_vf_link_state { + __u32 vf; + __u32 link_state; +}; + +struct ifla_vf_rss_query_en { + __u32 vf; + __u32 setting; +}; + +enum { + IFLA_VF_STATS_RX_PACKETS, + IFLA_VF_STATS_TX_PACKETS, + IFLA_VF_STATS_RX_BYTES, + IFLA_VF_STATS_TX_BYTES, + IFLA_VF_STATS_BROADCAST, + IFLA_VF_STATS_MULTICAST, + IFLA_VF_STATS_PAD, + __IFLA_VF_STATS_MAX, +}; + +#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1) + +struct ifla_vf_trust { + __u32 vf; + __u32 setting; +}; + +/* VF ports management section + * + * Nested layout of set/get msg is: + * + * [IFLA_NUM_VF] + * [IFLA_VF_PORTS] + * [IFLA_VF_PORT] + * [IFLA_PORT_*], ... + * [IFLA_VF_PORT] + * [IFLA_PORT_*], ... + * ... + * [IFLA_PORT_SELF] + * [IFLA_PORT_*], ... + */ + +enum { + IFLA_VF_PORT_UNSPEC, + IFLA_VF_PORT, /* nest */ + __IFLA_VF_PORT_MAX, +}; + +#define IFLA_VF_PORT_MAX (__IFLA_VF_PORT_MAX - 1) + +enum { + IFLA_PORT_UNSPEC, + IFLA_PORT_VF, /* __u32 */ + IFLA_PORT_PROFILE, /* string */ + IFLA_PORT_VSI_TYPE, /* 802.1Qbg (pre-)standard VDP */ + IFLA_PORT_INSTANCE_UUID, /* binary UUID */ + IFLA_PORT_HOST_UUID, /* binary UUID */ + IFLA_PORT_REQUEST, /* __u8 */ + IFLA_PORT_RESPONSE, /* __u16, output only */ + __IFLA_PORT_MAX, +}; + +#define IFLA_PORT_MAX (__IFLA_PORT_MAX - 1) + +#define PORT_PROFILE_MAX 40 +#define PORT_UUID_MAX 16 +#define PORT_SELF_VF -1 + +enum { + PORT_REQUEST_PREASSOCIATE = 0, + PORT_REQUEST_PREASSOCIATE_RR, + PORT_REQUEST_ASSOCIATE, + PORT_REQUEST_DISASSOCIATE, +}; + +enum { + PORT_VDP_RESPONSE_SUCCESS = 0, + PORT_VDP_RESPONSE_INVALID_FORMAT, + PORT_VDP_RESPONSE_INSUFFICIENT_RESOURCES, + PORT_VDP_RESPONSE_UNUSED_VTID, + PORT_VDP_RESPONSE_VTID_VIOLATION, + PORT_VDP_RESPONSE_VTID_VERSION_VIOALTION, + PORT_VDP_RESPONSE_OUT_OF_SYNC, + /* 0x08-0xFF reserved for future VDP use */ + PORT_PROFILE_RESPONSE_SUCCESS = 0x100, + PORT_PROFILE_RESPONSE_INPROGRESS, + PORT_PROFILE_RESPONSE_INVALID, + PORT_PROFILE_RESPONSE_BADSTATE, + PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES, + PORT_PROFILE_RESPONSE_ERROR, +}; + +struct ifla_port_vsi { + __u8 vsi_mgr_id; + __u8 vsi_type_id[3]; + __u8 vsi_type_version; + __u8 pad[3]; +}; + + +/* IPoIB section */ + +enum { + IFLA_IPOIB_UNSPEC, + IFLA_IPOIB_PKEY, + IFLA_IPOIB_MODE, + IFLA_IPOIB_UMCAST, + __IFLA_IPOIB_MAX +}; + +enum { + IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */ + IPOIB_MODE_CONNECTED = 1, /* using connected QPs */ +}; + +#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1) + + +/* HSR section */ + +enum { + IFLA_HSR_UNSPEC, + IFLA_HSR_SLAVE1, + IFLA_HSR_SLAVE2, + IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */ + IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ + IFLA_HSR_SEQ_NR, + IFLA_HSR_VERSION, /* HSR version */ + __IFLA_HSR_MAX, +}; + +#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1) + +/* STATS section */ + +struct if_stats_msg { + __u8 family; + __u8 pad1; + __u16 pad2; + __u32 ifindex; + __u32 filter_mask; +}; + +/* A stats attribute can be netdev specific or a global stat. + * For netdev stats, lets use the prefix IFLA_STATS_LINK_* + */ +enum { + IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ + IFLA_STATS_LINK_64, + IFLA_STATS_LINK_XSTATS, + IFLA_STATS_LINK_XSTATS_SLAVE, + IFLA_STATS_LINK_OFFLOAD_XSTATS, + __IFLA_STATS_MAX, +}; + +#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1) + +#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1)) + +/* These are embedded into IFLA_STATS_LINK_XSTATS: + * [IFLA_STATS_LINK_XSTATS] + * -> [LINK_XSTATS_TYPE_xxx] + * -> [rtnl link type specific attributes] + */ +enum { + LINK_XSTATS_TYPE_UNSPEC, + LINK_XSTATS_TYPE_BRIDGE, + __LINK_XSTATS_TYPE_MAX +}; +#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1) + +/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */ +enum { + IFLA_OFFLOAD_XSTATS_UNSPEC, + IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */ + __IFLA_OFFLOAD_XSTATS_MAX +}; +#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1) + +/* XDP section */ + +#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0) +#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST) + +enum { + IFLA_XDP_UNSPEC, + IFLA_XDP_FD, + IFLA_XDP_ATTACHED, + IFLA_XDP_FLAGS, + __IFLA_XDP_MAX, +}; + +#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1) + +#endif /* _UAPI_LINUX_IF_LINK_H */ diff --git a/SOURCES/if_macsec.h b/SOURCES/if_macsec.h new file mode 100644 index 0000000..02fc49c --- /dev/null +++ b/SOURCES/if_macsec.h @@ -0,0 +1,171 @@ +/* + * include/uapi/linux/if_macsec.h - MACsec device + * + * Copyright (c) 2015 Sabrina Dubroca + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _UAPI_MACSEC_H +#define _UAPI_MACSEC_H + +#include + +#define MACSEC_GENL_NAME "macsec" +#define MACSEC_GENL_VERSION 1 + +#define MACSEC_MAX_KEY_LEN 128 + +#define MACSEC_KEYID_LEN 16 + +#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL +#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL + +#define MACSEC_MIN_ICV_LEN 8 +#define MACSEC_MAX_ICV_LEN 32 +/* upper limit for ICV length as recommended by IEEE802.1AE-2006 */ +#define MACSEC_STD_ICV_LEN 16 + +enum macsec_attrs { + MACSEC_ATTR_UNSPEC, + MACSEC_ATTR_IFINDEX, /* u32, ifindex of the MACsec netdevice */ + MACSEC_ATTR_RXSC_CONFIG, /* config, nested macsec_rxsc_attrs */ + MACSEC_ATTR_SA_CONFIG, /* config, nested macsec_sa_attrs */ + MACSEC_ATTR_SECY, /* dump, nested macsec_secy_attrs */ + MACSEC_ATTR_TXSA_LIST, /* dump, nested, macsec_sa_attrs for each TXSA */ + MACSEC_ATTR_RXSC_LIST, /* dump, nested, macsec_rxsc_attrs for each RXSC */ + MACSEC_ATTR_TXSC_STATS, /* dump, nested, macsec_txsc_stats_attr */ + MACSEC_ATTR_SECY_STATS, /* dump, nested, macsec_secy_stats_attr */ + __MACSEC_ATTR_END, + NUM_MACSEC_ATTR = __MACSEC_ATTR_END, + MACSEC_ATTR_MAX = __MACSEC_ATTR_END - 1, +}; + +enum macsec_secy_attrs { + MACSEC_SECY_ATTR_UNSPEC, + MACSEC_SECY_ATTR_SCI, + MACSEC_SECY_ATTR_ENCODING_SA, + MACSEC_SECY_ATTR_WINDOW, + MACSEC_SECY_ATTR_CIPHER_SUITE, + MACSEC_SECY_ATTR_ICV_LEN, + MACSEC_SECY_ATTR_PROTECT, + MACSEC_SECY_ATTR_REPLAY, + MACSEC_SECY_ATTR_OPER, + MACSEC_SECY_ATTR_VALIDATE, + MACSEC_SECY_ATTR_ENCRYPT, + MACSEC_SECY_ATTR_INC_SCI, + MACSEC_SECY_ATTR_ES, + MACSEC_SECY_ATTR_SCB, + MACSEC_SECY_ATTR_PAD, + __MACSEC_SECY_ATTR_END, + NUM_MACSEC_SECY_ATTR = __MACSEC_SECY_ATTR_END, + MACSEC_SECY_ATTR_MAX = __MACSEC_SECY_ATTR_END - 1, +}; + +enum macsec_rxsc_attrs { + MACSEC_RXSC_ATTR_UNSPEC, + MACSEC_RXSC_ATTR_SCI, /* config/dump, u64 */ + MACSEC_RXSC_ATTR_ACTIVE, /* config/dump, u8 0..1 */ + MACSEC_RXSC_ATTR_SA_LIST, /* dump, nested */ + MACSEC_RXSC_ATTR_STATS, /* dump, nested, macsec_rxsc_stats_attr */ + MACSEC_RXSC_ATTR_PAD, + __MACSEC_RXSC_ATTR_END, + NUM_MACSEC_RXSC_ATTR = __MACSEC_RXSC_ATTR_END, + MACSEC_RXSC_ATTR_MAX = __MACSEC_RXSC_ATTR_END - 1, +}; + +enum macsec_sa_attrs { + MACSEC_SA_ATTR_UNSPEC, + MACSEC_SA_ATTR_AN, /* config/dump, u8 0..3 */ + MACSEC_SA_ATTR_ACTIVE, /* config/dump, u8 0..1 */ + MACSEC_SA_ATTR_PN, /* config/dump, u32 */ + MACSEC_SA_ATTR_KEY, /* config, data */ + MACSEC_SA_ATTR_KEYID, /* config/dump, 128-bit */ + MACSEC_SA_ATTR_STATS, /* dump, nested, macsec_sa_stats_attr */ + MACSEC_SA_ATTR_PAD, + __MACSEC_SA_ATTR_END, + NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END, + MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1, +}; + +enum macsec_nl_commands { + MACSEC_CMD_GET_TXSC, + MACSEC_CMD_ADD_RXSC, + MACSEC_CMD_DEL_RXSC, + MACSEC_CMD_UPD_RXSC, + MACSEC_CMD_ADD_TXSA, + MACSEC_CMD_DEL_TXSA, + MACSEC_CMD_UPD_TXSA, + MACSEC_CMD_ADD_RXSA, + MACSEC_CMD_DEL_RXSA, + MACSEC_CMD_UPD_RXSA, +}; + +/* u64 per-RXSC stats */ +enum macsec_rxsc_stats_attr { + MACSEC_RXSC_STATS_ATTR_UNSPEC, + MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED, + MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA, + MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA, + MACSEC_RXSC_STATS_ATTR_PAD, + __MACSEC_RXSC_STATS_ATTR_END, + NUM_MACSEC_RXSC_STATS_ATTR = __MACSEC_RXSC_STATS_ATTR_END, + MACSEC_RXSC_STATS_ATTR_MAX = __MACSEC_RXSC_STATS_ATTR_END - 1, +}; + +/* u32 per-{RX,TX}SA stats */ +enum macsec_sa_stats_attr { + MACSEC_SA_STATS_ATTR_UNSPEC, + MACSEC_SA_STATS_ATTR_IN_PKTS_OK, + MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID, + MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID, + MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA, + MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA, + MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED, + MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED, + __MACSEC_SA_STATS_ATTR_END, + NUM_MACSEC_SA_STATS_ATTR = __MACSEC_SA_STATS_ATTR_END, + MACSEC_SA_STATS_ATTR_MAX = __MACSEC_SA_STATS_ATTR_END - 1, +}; + +/* u64 per-TXSC stats */ +enum macsec_txsc_stats_attr { + MACSEC_TXSC_STATS_ATTR_UNSPEC, + MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED, + MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED, + MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED, + MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED, + MACSEC_TXSC_STATS_ATTR_PAD, + __MACSEC_TXSC_STATS_ATTR_END, + NUM_MACSEC_TXSC_STATS_ATTR = __MACSEC_TXSC_STATS_ATTR_END, + MACSEC_TXSC_STATS_ATTR_MAX = __MACSEC_TXSC_STATS_ATTR_END - 1, +}; + +/* u64 per-SecY stats */ +enum macsec_secy_stats_attr { + MACSEC_SECY_STATS_ATTR_UNSPEC, + MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED, + MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED, + MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG, + MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG, + MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG, + MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI, + MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI, + MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN, + MACSEC_SECY_STATS_ATTR_PAD, + __MACSEC_SECY_STATS_ATTR_END, + NUM_MACSEC_SECY_STATS_ATTR = __MACSEC_SECY_STATS_ATTR_END, + MACSEC_SECY_STATS_ATTR_MAX = __MACSEC_SECY_STATS_ATTR_END - 1, +}; + +#endif /* _UAPI_MACSEC_H */ diff --git a/SOURCES/macsec-0001-mka-Move-structs-transmit-receive-_-sa-sc-to-a-commo.patch b/SOURCES/macsec-0001-mka-Move-structs-transmit-receive-_-sa-sc-to-a-commo.patch new file mode 100644 index 0000000..eac57ac --- /dev/null +++ b/SOURCES/macsec-0001-mka-Move-structs-transmit-receive-_-sa-sc-to-a-commo.patch @@ -0,0 +1,237 @@ +From f75f6e2b03fa5e807142a37039b0b613565eafa7 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Tue, 20 Sep 2016 09:43:04 +0200 +Subject: [PATCH] mka: Move structs {transmit,receive}_{sa,sc} to a common + header + +These structs will be passed down to macsec drivers in a coming patch to +make the driver interface cleaner, so they need to be shared between the +core MKA implementation and the drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 3 ++ + src/pae/ieee802_1x_kay.h | 82 +++++++++++++++++++++++++++++++++++++++++++ + src/pae/ieee802_1x_kay_i.h | 82 ------------------------------------------- + src/pae/ieee802_1x_secy_ops.h | 4 --- + 4 files changed, 85 insertions(+), 86 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index a449cc9..073219e 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -21,6 +21,9 @@ + + #include "common/defs.h" + #include "common/ieee802_11_defs.h" ++#ifdef CONFIG_MACSEC ++#include "pae/ieee802_1x_kay.h" ++#endif /* CONFIG_MACSEC */ + #include "utils/list.h" + + #define HOSTAPD_CHAN_DISABLED 0x00000001 +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index afbaa33..0361e1a 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -49,6 +49,88 @@ enum mka_created_mode { + EAP_EXCHANGE, + }; + ++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 ieee802_1x_kay_ctx { + /* pointer to arbitrary upper level context */ + void *ctx; +diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h +index 622282e..e3d7db4 100644 +--- a/src/pae/ieee802_1x_kay_i.h ++++ b/src/pae/ieee802_1x_kay_i.h +@@ -54,88 +54,6 @@ struct ieee802_1x_kay_peer { + struct dl_list list; + }; + +-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 { + u64 id; + char name[32]; +diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h +index f5057ee..120ca3c 100644 +--- a/src/pae/ieee802_1x_secy_ops.h ++++ b/src/pae/ieee802_1x_secy_ops.h +@@ -13,10 +13,6 @@ + #include "common/ieee802_1x_defs.h" + + struct ieee802_1x_kay_conf; +-struct receive_sa; +-struct transmit_sa; +-struct receive_sc; +-struct transmit_sc; + + int secy_init_macsec(struct ieee802_1x_kay *kay); + int secy_deinit_macsec(struct ieee802_1x_kay *kay); +-- +2.7.4 + diff --git a/SOURCES/macsec-0002-mka-Pass-full-structures-down-to-macsec-drivers-pack.patch b/SOURCES/macsec-0002-mka-Pass-full-structures-down-to-macsec-drivers-pack.patch new file mode 100644 index 0000000..beba8f2 --- /dev/null +++ b/SOURCES/macsec-0002-mka-Pass-full-structures-down-to-macsec-drivers-pack.patch @@ -0,0 +1,296 @@ +From 7fa5eff8abbbff4f3385932175b080aad40bf211 Mon Sep 17 00:00:00 2001 +Message-Id: <7fa5eff8abbbff4f3385932175b080aad40bf211.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Tue, 20 Sep 2016 09:43:05 +0200 +Subject: [PATCH] mka: Pass full structures down to macsec drivers' packet + number ops + +Clean up the driver interface by passing pointers to structs transmit_sa +and receive_sa down the stack to get_receive_lowest_pn(), +get_transmit_next_pn(), and set_transmit_next_pn() ops, instead of +passing the individual arguments. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 21 ++++++--------------- + src/drivers/driver_macsec_qca.c | 33 ++++++++++++++++++--------------- + src/pae/ieee802_1x_kay.h | 8 +++----- + src/pae/ieee802_1x_secy_ops.c | 15 +++------------ + wpa_supplicant/driver_i.h | 18 ++++++------------ + wpa_supplicant/wpas_kay.c | 15 ++++++--------- + 6 files changed, 42 insertions(+), 68 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 073219e..2c7ce6c 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3336,35 +3336,26 @@ struct wpa_driver_ops { + /** + * get_receive_lowest_pn - Get receive lowest pn + * @priv: Private driver interface data +- * @channel: secure channel +- * @an: association number +- * @lowest_pn: lowest accept pn ++ * @sa: secure association + * Returns: 0 on success, -1 on failure (or if not supported) + */ +- int (*get_receive_lowest_pn)(void *priv, u32 channel, u8 an, +- u32 *lowest_pn); ++ int (*get_receive_lowest_pn)(void *priv, struct receive_sa *sa); + + /** + * get_transmit_next_pn - Get transmit next pn + * @priv: Private driver interface data +- * @channel: secure channel +- * @an: association number +- * @next_pn: next pn ++ * @sa: secure association + * Returns: 0 on success, -1 on failure (or if not supported) + */ +- int (*get_transmit_next_pn)(void *priv, u32 channel, u8 an, +- u32 *next_pn); ++ int (*get_transmit_next_pn)(void *priv, struct transmit_sa *sa); + + /** + * set_transmit_next_pn - Set transmit next pn + * @priv: Private driver interface data +- * @channel: secure channel +- * @an: association number +- * @next_pn: next pn ++ * @sa: secure association + * Returns: 0 on success, -1 on failure (or if not supported) + */ +- int (*set_transmit_next_pn)(void *priv, u32 channel, u8 an, +- u32 next_pn); ++ int (*set_transmit_next_pn)(void *priv, struct transmit_sa *sa); + + /** + * get_available_receive_sc - get available receive channel +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 826d3cc..95f1e27 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -29,6 +29,7 @@ + #include "utils/eloop.h" + #include "common/defs.h" + #include "common/ieee802_1x_defs.h" ++#include "pae/ieee802_1x_kay.h" + #include "driver.h" + + #include "nss_macsec_secy.h" +@@ -515,16 +516,16 @@ static int macsec_qca_enable_controlled_port(void *priv, Boolean enabled) + } + + +-static int macsec_qca_get_receive_lowest_pn(void *priv, u32 channel, u8 an, +- u32 *lowest_pn) ++static int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + u32 next_pn = 0; + bool enabled = FALSE; + u32 win; ++ u32 channel = sa->sc->channel; + +- ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, an, ++ ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, sa->an, + &next_pn); + ret += nss_macsec_secy_rx_sc_replay_protect_get(drv->secy_id, channel, + &enabled); +@@ -532,40 +533,42 @@ static int macsec_qca_get_receive_lowest_pn(void *priv, u32 channel, u8 an, + channel, &win); + + if (enabled) +- *lowest_pn = (next_pn > win) ? (next_pn - win) : 1; ++ sa->lowest_pn = (next_pn > win) ? (next_pn - win) : 1; + else +- *lowest_pn = next_pn; ++ sa->lowest_pn = next_pn; + +- wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, *lowest_pn); ++ wpa_printf(MSG_DEBUG, "%s: lpn=0x%x", __func__, sa->lowest_pn); + + return ret; + } + + +-static int macsec_qca_get_transmit_next_pn(void *priv, u32 channel, u8 an, +- u32 *next_pn) ++static int macsec_qca_get_transmit_next_pn(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; + +- ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, an, +- next_pn); ++ ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, sa->an, ++ &sa->next_pn); + +- wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, *next_pn); ++ wpa_printf(MSG_DEBUG, "%s: npn=0x%x", __func__, sa->next_pn); + + return ret; + } + + +-int macsec_qca_set_transmit_next_pn(void *priv, u32 channel, u8 an, u32 next_pn) ++int macsec_qca_set_transmit_next_pn(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; + +- ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, an, +- next_pn); + +- wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, next_pn); ++ ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an, ++ sa->next_pn); ++ ++ wpa_printf(MSG_INFO, "%s: npn=0x%x", __func__, sa->next_pn); + + return ret; + } +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 0361e1a..a747b11 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -142,11 +142,9 @@ struct ieee802_1x_kay_ctx { + int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window); + int (*set_current_cipher_suite)(void *ctx, u64 cs); + int (*enable_controlled_port)(void *ctx, Boolean enabled); +- int (*get_receive_lowest_pn)(void *ctx, u32 channel, u8 an, +- u32 *lowest_pn); +- int (*get_transmit_next_pn)(void *ctx, u32 channel, u8 an, +- u32 *next_pn); +- int (*set_transmit_next_pn)(void *ctx, u32 channel, u8 an, u32 next_pn); ++ int (*get_receive_lowest_pn)(void *ctx, struct receive_sa *sa); ++ int (*get_transmit_next_pn)(void *ctx, struct transmit_sa *sa); ++ int (*set_transmit_next_pn)(void *ctx, struct transmit_sa *sa); + int (*get_available_receive_sc)(void *ctx, u32 *channel); + int (*create_receive_sc)(void *ctx, u32 channel, + struct ieee802_1x_mka_sci *sci, +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index 2d12911..d05e00f 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -130,10 +130,7 @@ int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->get_receive_lowest_pn(ops->ctx, +- rxsa->sc->channel, +- rxsa->an, +- &rxsa->lowest_pn); ++ return ops->get_receive_lowest_pn(ops->ctx, rxsa); + } + + +@@ -154,10 +151,7 @@ int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->get_transmit_next_pn(ops->ctx, +- txsa->sc->channel, +- txsa->an, +- &txsa->next_pn); ++ return ops->get_transmit_next_pn(ops->ctx, txsa); + } + + +@@ -178,10 +172,7 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->set_transmit_next_pn(ops->ctx, +- txsa->sc->channel, +- txsa->an, +- txsa->next_pn); ++ return ops->set_transmit_next_pn(ops->ctx, txsa); + } + + +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index 220b7ba..639bb83 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -749,33 +749,27 @@ static inline int wpa_drv_enable_controlled_port(struct wpa_supplicant *wpa_s, + } + + static inline int wpa_drv_get_receive_lowest_pn(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an, +- u32 *lowest_pn) ++ struct receive_sa *sa) + { + if (!wpa_s->driver->get_receive_lowest_pn) + return -1; +- return wpa_s->driver->get_receive_lowest_pn(wpa_s->drv_priv, channel, +- an, lowest_pn); ++ return wpa_s->driver->get_receive_lowest_pn(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_get_transmit_next_pn(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an, +- u32 *next_pn) ++ struct transmit_sa *sa) + { + if (!wpa_s->driver->get_transmit_next_pn) + return -1; +- return wpa_s->driver->get_transmit_next_pn(wpa_s->drv_priv, channel, +- an, next_pn); ++ return wpa_s->driver->get_transmit_next_pn(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_set_transmit_next_pn(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an, +- u32 next_pn) ++ struct transmit_sa *sa) + { + if (!wpa_s->driver->set_transmit_next_pn) + return -1; +- return wpa_s->driver->set_transmit_next_pn(wpa_s->drv_priv, channel, +- an, next_pn); ++ return wpa_s->driver->set_transmit_next_pn(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_get_available_receive_sc(struct wpa_supplicant *wpa_s, +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index d6ec8c5..306d9f1 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -62,24 +62,21 @@ static int wpas_enable_controlled_port(void *wpa_s, Boolean enabled) + } + + +-static int wpas_get_receive_lowest_pn(void *wpa_s, u32 channel, +- u8 an, u32 *lowest_pn) ++static int wpas_get_receive_lowest_pn(void *wpa_s, struct receive_sa *sa) + { +- return wpa_drv_get_receive_lowest_pn(wpa_s, channel, an, lowest_pn); ++ return wpa_drv_get_receive_lowest_pn(wpa_s, sa); + } + + +-static int wpas_get_transmit_next_pn(void *wpa_s, u32 channel, +- u8 an, u32 *next_pn) ++static int wpas_get_transmit_next_pn(void *wpa_s, struct transmit_sa *sa) + { +- return wpa_drv_get_transmit_next_pn(wpa_s, channel, an, next_pn); ++ return wpa_drv_get_transmit_next_pn(wpa_s, sa); + } + + +-static int wpas_set_transmit_next_pn(void *wpa_s, u32 channel, +- u8 an, u32 next_pn) ++static int wpas_set_transmit_next_pn(void *wpa_s, struct transmit_sa *sa) + { +- return wpa_drv_set_transmit_next_pn(wpa_s, channel, an, next_pn); ++ return wpa_drv_set_transmit_next_pn(wpa_s, sa); + } + + +-- +2.7.4 + diff --git a/SOURCES/macsec-0003-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch b/SOURCES/macsec-0003-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch new file mode 100644 index 0000000..1878f40 --- /dev/null +++ b/SOURCES/macsec-0003-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch @@ -0,0 +1,290 @@ +From 909c1b9835ecc9c115980e9827a9313c17dab22b Mon Sep 17 00:00:00 2001 +Message-Id: <909c1b9835ecc9c115980e9827a9313c17dab22b.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Tue, 20 Sep 2016 09:43:07 +0200 +Subject: [PATCH] mka: Pass full structures down to macsec drivers' transmit SA + ops + +Clean up the driver interface by passing pointers to struct transmit_sa +down the stack to the {create,enable,disable}_transmit_sa ops, instead +of passing the individual properties of the SA. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 20 ++++++-------------- + src/drivers/driver_macsec_qca.c | 39 +++++++++++++++++++++++---------------- + src/pae/ieee802_1x_kay.h | 7 +++---- + src/pae/ieee802_1x_secy_ops.c | 8 +++----- + wpa_supplicant/driver_i.h | 16 ++++++---------- + wpa_supplicant/wpas_kay.c | 15 ++++++--------- + 6 files changed, 47 insertions(+), 58 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 2c7ce6c..bb2d1d2 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3448,34 +3448,26 @@ struct wpa_driver_ops { + /** + * create_transmit_sa - create secure association for transmit + * @priv: private driver interface data from init() +- * @channel: secure channel index +- * @an: association number +- * @next_pn: the packet number used as next transmit packet +- * @confidentiality: True if the SA is to provide confidentiality +- * as well as integrity +- * @sak: the secure association key ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*create_transmit_sa)(void *priv, u32 channel, u8 an, u32 next_pn, +- Boolean confidentiality, const u8 *sak); ++ int (*create_transmit_sa)(void *priv, struct transmit_sa *sa); + + /** + * enable_transmit_sa - enable SA for transmit + * @priv: private driver interface data from init() +- * @channel: secure channel +- * @an: association number ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*enable_transmit_sa)(void *priv, u32 channel, u8 an); ++ int (*enable_transmit_sa)(void *priv, struct transmit_sa *sa); + + /** + * disable_transmit_sa - disable SA for transmit + * @priv: private driver interface data from init() +- * @channel: secure channel +- * @an: association number ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*disable_transmit_sa)(void *priv, u32 channel, u8 an); ++ int (*disable_transmit_sa)(void *priv, struct transmit_sa *sa); + #endif /* CONFIG_MACSEC */ + + /** +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 95f1e27..9bfc9a4 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -794,19 +794,18 @@ static int macsec_qca_delete_transmit_sc(void *priv, u32 channel) + } + + +-static int macsec_qca_create_transmit_sa(void *priv, u32 channel, u8 an, +- u32 next_pn, Boolean confidentiality, +- const u8 *sak) ++static int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + u8 tci = 0; + fal_tx_sak_t tx_sak; + int i; ++ u32 channel = sa->sc->channel; + + wpa_printf(MSG_DEBUG, + "%s: channel=%d, an=%d, next_pn=0x%x, confidentiality=%d", +- __func__, channel, an, next_pn, confidentiality); ++ __func__, channel, sa->an, sa->next_pn, sa->confidentiality); + + if (drv->always_include_sci) + tci |= TCI_SC; +@@ -815,45 +814,53 @@ static int macsec_qca_create_transmit_sa(void *priv, u32 channel, u8 an, + else if (drv->use_scb) + tci |= TCI_SCB; + +- if (confidentiality) ++ if (sa->confidentiality) + tci |= TCI_E | TCI_C; + + os_memset(&tx_sak, 0, sizeof(tx_sak)); + for (i = 0; i < 16; i++) +- tx_sak.sak[i] = sak[15 - i]; ++ tx_sak.sak[i] = sa->pkey->key[15 - i]; + +- ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, an, +- next_pn); +- ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, an, &tx_sak); ++ ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an, ++ sa->next_pn); ++ ret += nss_macsec_secy_tx_sak_set(drv->secy_id, channel, sa->an, ++ &tx_sak); + ret += nss_macsec_secy_tx_sc_tci_7_2_set(drv->secy_id, channel, + (tci >> 2)); +- ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, an); ++ ret += nss_macsec_secy_tx_sc_an_set(drv->secy_id, channel, sa->an); + + return ret; + } + + +-static int macsec_qca_enable_transmit_sa(void *priv, u32 channel, u8 an) ++static int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; + +- wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an); + +- ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, an, TRUE); ++ wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, ++ sa->an); ++ ++ ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an, ++ TRUE); + + return ret; + } + + +-static int macsec_qca_disable_transmit_sa(void *priv, u32 channel, u8 an) ++static int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; + +- wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an); ++ wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, ++ sa->an); + +- ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, an, FALSE); ++ ret += nss_macsec_secy_tx_sa_en_set(drv->secy_id, channel, sa->an, ++ FALSE); + + return ret; + } +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index a747b11..36a7bd6 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -160,10 +160,9 @@ struct ieee802_1x_kay_ctx { + const struct ieee802_1x_mka_sci *sci, + enum confidentiality_offset co); + int (*delete_transmit_sc)(void *ctx, u32 channel); +- int (*create_transmit_sa)(void *ctx, u32 channel, u8 an, u32 next_pn, +- Boolean confidentiality, const u8 *sak); +- int (*enable_transmit_sa)(void *ctx, u32 channel, u8 an); +- int (*disable_transmit_sa)(void *ctx, u32 channel, u8 an); ++ int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); ++ int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); ++ int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); + }; + + struct ieee802_1x_kay { +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index d05e00f..8c31ca9 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -382,9 +382,7 @@ int secy_create_transmit_sa(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->create_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an, +- txsa->next_pn, txsa->confidentiality, +- txsa->pkey->key); ++ return ops->create_transmit_sa(ops->ctx, txsa); + } + + +@@ -407,7 +405,7 @@ int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, + + txsa->enable_transmit = TRUE; + +- return ops->enable_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an); ++ return ops->enable_transmit_sa(ops->ctx, txsa); + } + + +@@ -430,7 +428,7 @@ int secy_disable_transmit_sa(struct ieee802_1x_kay *kay, + + txsa->enable_transmit = FALSE; + +- return ops->disable_transmit_sa(ops->ctx, txsa->sc->channel, txsa->an); ++ return ops->disable_transmit_sa(ops->ctx, txsa); + } + + +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index 639bb83..e2c2bd7 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -857,31 +857,27 @@ static inline int wpa_drv_delete_transmit_sc(struct wpa_supplicant *wpa_s, + } + + static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an, +- u32 next_pn, +- Boolean confidentiality, +- const u8 *sak) ++ struct transmit_sa *sa) + { + if (!wpa_s->driver->create_transmit_sa) + return -1; +- return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, channel, an, +- next_pn, confidentiality, sak); ++ return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_enable_transmit_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an) ++ struct transmit_sa *sa) + { + if (!wpa_s->driver->enable_transmit_sa) + return -1; +- return wpa_s->driver->enable_transmit_sa(wpa_s->drv_priv, channel, an); ++ return wpa_s->driver->enable_transmit_sa(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_disable_transmit_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an) ++ struct transmit_sa *sa) + { + if (!wpa_s->driver->disable_transmit_sa) + return -1; +- return wpa_s->driver->disable_transmit_sa(wpa_s->drv_priv, channel, an); ++ return wpa_s->driver->disable_transmit_sa(wpa_s->drv_priv, sa); + } + #endif /* CONFIG_MACSEC */ + +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 306d9f1..4b74112 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -159,24 +159,21 @@ static int wpas_delete_transmit_sc(void *wpa_s, u32 channel) + } + + +-static int wpas_create_transmit_sa(void *wpa_s, u32 channel, u8 an, +- u32 next_pn, Boolean confidentiality, +- const u8 *sak) ++static int wpas_create_transmit_sa(void *wpa_s, struct transmit_sa *sa) + { +- return wpa_drv_create_transmit_sa(wpa_s, channel, an, next_pn, +- confidentiality, sak); ++ return wpa_drv_create_transmit_sa(wpa_s, sa); + } + + +-static int wpas_enable_transmit_sa(void *wpa_s, u32 channel, u8 an) ++static int wpas_enable_transmit_sa(void *wpa_s, struct transmit_sa *sa) + { +- return wpa_drv_enable_transmit_sa(wpa_s, channel, an); ++ return wpa_drv_enable_transmit_sa(wpa_s, sa); + } + + +-static int wpas_disable_transmit_sa(void *wpa_s, u32 channel, u8 an) ++static int wpas_disable_transmit_sa(void *wpa_s, struct transmit_sa *sa) + { +- return wpa_drv_disable_transmit_sa(wpa_s, channel, an); ++ return wpa_drv_disable_transmit_sa(wpa_s, sa); + } + + +-- +2.7.4 + diff --git a/SOURCES/macsec-0004-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch b/SOURCES/macsec-0004-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch new file mode 100644 index 0000000..520d24f --- /dev/null +++ b/SOURCES/macsec-0004-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch @@ -0,0 +1,264 @@ +From cecdecdbe81c9ca86127413c6559be2d3ffcabd3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Tue, 20 Sep 2016 09:43:09 +0200 +Subject: [PATCH] mka: Pass full structures down to macsec drivers' receive SA + ops + +Clean up the driver interface by passing pointers to struct receive_sa +down the stack to the {create,enable,disable}_receive_sa() ops, instead +of passing the individual properties of the SA. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 18 ++++++------------ + src/drivers/driver_macsec_qca.c | 32 ++++++++++++++++++++------------ + src/pae/ieee802_1x_kay.h | 7 +++---- + src/pae/ieee802_1x_secy_ops.c | 7 +++---- + wpa_supplicant/driver_i.h | 14 ++++++-------- + wpa_supplicant/wpas_kay.c | 13 ++++++------- + 6 files changed, 44 insertions(+), 47 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index bb2d1d2..f1915fc 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3391,32 +3391,26 @@ struct wpa_driver_ops { + /** + * create_receive_sa - create secure association for receive + * @priv: private driver interface data from init() +- * @channel: secure channel +- * @an: association number +- * @lowest_pn: the lowest packet number can be received +- * @sak: the secure association key ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*create_receive_sa)(void *priv, u32 channel, u8 an, +- u32 lowest_pn, const u8 *sak); ++ int (*create_receive_sa)(void *priv, struct receive_sa *sa); + + /** + * enable_receive_sa - enable the SA for receive + * @priv: private driver interface data from init() +- * @channel: secure channel +- * @an: association number ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*enable_receive_sa)(void *priv, u32 channel, u8 an); ++ int (*enable_receive_sa)(void *priv, struct receive_sa *sa); + + /** + * disable_receive_sa - disable SA for receive + * @priv: private driver interface data from init() +- * @channel: secure channel index +- * @an: association number ++ * @sa: secure association + * Returns: 0 on success, -1 on failure + */ +- int (*disable_receive_sa)(void *priv, u32 channel, u8 an); ++ int (*disable_receive_sa)(void *priv, struct receive_sa *sa); + + /** + * get_available_transmit_sc - get available transmit channel +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 9bfc9a4..2867c31 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -667,49 +667,57 @@ static int macsec_qca_delete_receive_sc(void *priv, u32 channel) + } + + +-static int macsec_qca_create_receive_sa(void *priv, u32 channel, u8 an, +- u32 lowest_pn, const u8 *sak) ++static int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + fal_rx_sak_t rx_sak; + int i = 0; ++ u32 channel = sa->sc->channel; + + wpa_printf(MSG_DEBUG, "%s, channel=%d, an=%d, lpn=0x%x", +- __func__, channel, an, lowest_pn); ++ __func__, channel, sa->an, sa->lowest_pn); + + os_memset(&rx_sak, 0, sizeof(rx_sak)); + for (i = 0; i < 16; i++) +- rx_sak.sak[i] = sak[15 - i]; ++ rx_sak.sak[i] = sa->pkey->key[15 - i]; + +- ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, an); +- ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, an, &rx_sak); ++ ret += nss_macsec_secy_rx_sa_create(drv->secy_id, channel, sa->an); ++ ret += nss_macsec_secy_rx_sak_set(drv->secy_id, channel, sa->an, ++ &rx_sak); + + return ret; + } + + +-static int macsec_qca_enable_receive_sa(void *priv, u32 channel, u8 an) ++static int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; ++ + +- wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an); ++ wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, ++ sa->an); + +- ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, an, TRUE); ++ ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an, ++ TRUE); + + return ret; + } + + +-static int macsec_qca_disable_receive_sa(void *priv, u32 channel, u8 an) ++static int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; ++ u32 channel = sa->sc->channel; + +- wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, an); ++ wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, ++ sa->an); + +- ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, an, FALSE); ++ ret += nss_macsec_secy_rx_sa_en_set(drv->secy_id, channel, sa->an, ++ FALSE); + + return ret; + } +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 36a7bd6..8ee5860 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -151,10 +151,9 @@ struct ieee802_1x_kay_ctx { + enum validate_frames vf, + enum confidentiality_offset co); + int (*delete_receive_sc)(void *ctx, u32 channel); +- int (*create_receive_sa)(void *ctx, u32 channel, u8 an, u32 lowest_pn, +- const u8 *sak); +- int (*enable_receive_sa)(void *ctx, u32 channel, u8 an); +- int (*disable_receive_sa)(void *ctx, u32 channel, u8 an); ++ int (*create_receive_sa)(void *ctx, struct receive_sa *sa); ++ int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); ++ int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*get_available_transmit_sc)(void *ctx, u32 *channel); + int (*create_transmit_sc)(void *ctx, u32 channel, + const struct ieee802_1x_mka_sci *sci, +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index 8c31ca9..fb376df 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -253,8 +253,7 @@ int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + return -1; + } + +- return ops->create_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an, +- rxsa->lowest_pn, rxsa->pkey->key); ++ return ops->create_receive_sa(ops->ctx, rxsa); + } + + +@@ -276,7 +275,7 @@ int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + + rxsa->enable_receive = TRUE; + +- return ops->enable_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an); ++ return ops->enable_receive_sa(ops->ctx, rxsa); + } + + +@@ -298,7 +297,7 @@ int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + + rxsa->enable_receive = FALSE; + +- return ops->disable_receive_sa(ops->ctx, rxsa->sc->channel, rxsa->an); ++ return ops->disable_receive_sa(ops->ctx, rxsa); + } + + +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index e2c2bd7..666798b 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -802,29 +802,27 @@ static inline int wpa_drv_delete_receive_sc(struct wpa_supplicant *wpa_s, + } + + static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an, +- u32 lowest_pn, const u8 *sak) ++ struct receive_sa *sa) + { + if (!wpa_s->driver->create_receive_sa) + return -1; +- return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, channel, an, +- lowest_pn, sak); ++ return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_enable_receive_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an) ++ struct receive_sa *sa) + { + if (!wpa_s->driver->enable_receive_sa) + return -1; +- return wpa_s->driver->enable_receive_sa(wpa_s->drv_priv, channel, an); ++ return wpa_s->driver->enable_receive_sa(wpa_s->drv_priv, sa); + } + + static inline int wpa_drv_disable_receive_sa(struct wpa_supplicant *wpa_s, +- u32 channel, u8 an) ++ struct receive_sa *sa) + { + if (!wpa_s->driver->disable_receive_sa) + return -1; +- return wpa_s->driver->disable_receive_sa(wpa_s->drv_priv, channel, an); ++ return wpa_s->driver->disable_receive_sa(wpa_s->drv_priv, sa); + } + + static inline int +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 4b74112..344c59e 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -117,22 +117,21 @@ static int wpas_delete_receive_sc(void *wpa_s, u32 channel) + } + + +-static int wpas_create_receive_sa(void *wpa_s, u32 channel, u8 an, +- u32 lowest_pn, const u8 *sak) ++static int wpas_create_receive_sa(void *wpa_s, struct receive_sa *sa) + { +- return wpa_drv_create_receive_sa(wpa_s, channel, an, lowest_pn, sak); ++ return wpa_drv_create_receive_sa(wpa_s, sa); + } + + +-static int wpas_enable_receive_sa(void *wpa_s, u32 channel, u8 an) ++static int wpas_enable_receive_sa(void *wpa_s, struct receive_sa *sa) + { +- return wpa_drv_enable_receive_sa(wpa_s, channel, an); ++ return wpa_drv_enable_receive_sa(wpa_s, sa); + } + + +-static int wpas_disable_receive_sa(void *wpa_s, u32 channel, u8 an) ++static int wpas_disable_receive_sa(void *wpa_s, struct receive_sa *sa) + { +- return wpa_drv_disable_receive_sa(wpa_s, channel, an); ++ return wpa_drv_disable_receive_sa(wpa_s, sa); + } + + +-- +2.7.4 + diff --git a/SOURCES/macsec-0005-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch b/SOURCES/macsec-0005-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch new file mode 100644 index 0000000..2f61a55 --- /dev/null +++ b/SOURCES/macsec-0005-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch @@ -0,0 +1,204 @@ +From 8ebfc7c2ba77ac1f71577b3ddc46a050d9fb1103 Mon Sep 17 00:00:00 2001 +Message-Id: <8ebfc7c2ba77ac1f71577b3ddc46a050d9fb1103.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 7 Oct 2016 12:08:09 +0200 +Subject: [PATCH] mka: Pass full structures down to macsec drivers' transmit SC + ops + +Clean up the driver interface by passing pointers to struct transmit_sc +down the stack to the {create,delete}_transmit_sc() ops, instead of +passing the individual arguments. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 13 ++++++------- + src/drivers/driver_macsec_qca.c | 13 +++++++------ + src/pae/ieee802_1x_kay.h | 5 ++--- + src/pae/ieee802_1x_secy_ops.c | 5 ++--- + wpa_supplicant/driver_i.h | 10 ++++------ + wpa_supplicant/wpas_kay.c | 11 ++++------- + 6 files changed, 25 insertions(+), 32 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index f1915fc..1e2d623 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3423,21 +3423,20 @@ struct wpa_driver_ops { + /** + * create_transmit_sc - create secure connection for transmit + * @priv: private driver interface data from init() +- * @channel: secure channel +- * @sci_addr: secure channel identifier - address +- * @sci_port: secure channel identifier - port ++ * @sc: secure channel ++ * @conf_offset: confidentiality offset (0, 30, or 50) + * Returns: 0 on success, -1 on failure + */ +- int (*create_transmit_sc)(void *priv, u32 channel, const u8 *sci_addr, +- u16 sci_port, unsigned int conf_offset); ++ int (*create_transmit_sc)(void *priv, struct transmit_sc *sc, ++ unsigned int conf_offset); + + /** + * delete_transmit_sc - delete secure connection for transmit + * @priv: private driver interface data from init() +- * @channel: secure channel ++ * @sc: secure channel + * Returns: 0 on success, -1 on failure + */ +- int (*delete_transmit_sc)(void *priv, u32 channel); ++ int (*delete_transmit_sc)(void *priv, struct transmit_sc *sc); + + /** + * create_transmit_sa - create secure association for transmit +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 2867c31..fef93df 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -750,14 +750,14 @@ static int macsec_qca_get_available_transmit_sc(void *priv, u32 *channel) + } + + +-static int macsec_qca_create_transmit_sc(void *priv, u32 channel, +- const u8 *sci_addr, u16 sci_port, ++static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc, + unsigned int conf_offset) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + fal_tx_class_lut_t entry; + u8 psci[ETH_ALEN + 2]; ++ u32 channel = sc->channel; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +@@ -768,9 +768,9 @@ static int macsec_qca_create_transmit_sc(void *priv, u32 channel, + entry.action = FAL_TX_CLASS_ACTION_FORWARD; + entry.channel = channel; + +- os_memcpy(psci, sci_addr, ETH_ALEN); +- psci[6] = (sci_port >> 8) & 0xf; +- psci[7] = sci_port & 0xf; ++ os_memcpy(psci, sc->sci.addr, ETH_ALEN); ++ psci[6] = (sc->sci.port >> 8) & 0xf; ++ psci[7] = sc->sci.port & 0xf; + + ret += nss_macsec_secy_tx_class_lut_set(drv->secy_id, channel, &entry); + ret += nss_macsec_secy_tx_sc_create(drv->secy_id, channel, psci, 8); +@@ -784,11 +784,12 @@ static int macsec_qca_create_transmit_sc(void *priv, u32 channel, + } + + +-static int macsec_qca_delete_transmit_sc(void *priv, u32 channel) ++static int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + fal_tx_class_lut_t entry; ++ u32 channel = sc->channel; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 8ee5860..8cd5fa6 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -155,10 +155,9 @@ struct ieee802_1x_kay_ctx { + int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*get_available_transmit_sc)(void *ctx, u32 *channel); +- int (*create_transmit_sc)(void *ctx, u32 channel, +- const struct ieee802_1x_mka_sci *sci, ++ int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, + enum confidentiality_offset co); +- int (*delete_transmit_sc)(void *ctx, u32 channel); ++ int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); + int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index fb376df..669dc98 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -338,8 +338,7 @@ int secy_create_transmit_sc(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->create_transmit_sc(ops->ctx, txsc->channel, &txsc->sci, +- kay->co); ++ return ops->create_transmit_sc(ops->ctx, txsc, kay->co); + } + + +@@ -360,7 +359,7 @@ int secy_delete_transmit_sc(struct ieee802_1x_kay *kay, + return -1; + } + +- return ops->delete_transmit_sc(ops->ctx, txsc->channel); ++ return ops->delete_transmit_sc(ops->ctx, txsc); + } + + +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index 666798b..2dc74bf 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -835,23 +835,21 @@ wpa_drv_get_available_transmit_sc(struct wpa_supplicant *wpa_s, u32 *channel) + } + + static inline int +-wpa_drv_create_transmit_sc(struct wpa_supplicant *wpa_s, u32 channel, +- const u8 *sci_addr, u16 sci_port, ++wpa_drv_create_transmit_sc(struct wpa_supplicant *wpa_s, struct transmit_sc *sc, + unsigned int conf_offset) + { + if (!wpa_s->driver->create_transmit_sc) + return -1; +- return wpa_s->driver->create_transmit_sc(wpa_s->drv_priv, channel, +- sci_addr, sci_port, ++ return wpa_s->driver->create_transmit_sc(wpa_s->drv_priv, sc, + conf_offset); + } + + static inline int wpa_drv_delete_transmit_sc(struct wpa_supplicant *wpa_s, +- u32 channel) ++ struct transmit_sc *sc) + { + if (!wpa_s->driver->delete_transmit_sc) + return -1; +- return wpa_s->driver->delete_transmit_sc(wpa_s->drv_priv, channel); ++ return wpa_s->driver->delete_transmit_sc(wpa_s->drv_priv, sc); + } + + static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s, +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 344c59e..e0f8e28 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -142,19 +142,16 @@ static int wpas_get_available_transmit_sc(void *wpa_s, u32 *channel) + + + static int +-wpas_create_transmit_sc(void *wpa_s, u32 channel, +- const struct ieee802_1x_mka_sci *sci, ++wpas_create_transmit_sc(void *wpa_s, struct transmit_sc *sc, + enum confidentiality_offset co) + { +- return wpa_drv_create_transmit_sc(wpa_s, channel, sci->addr, +- be_to_host16(sci->port), +- conf_offset_val(co)); ++ return wpa_drv_create_transmit_sc(wpa_s, sc, conf_offset_val(co)); + } + + +-static int wpas_delete_transmit_sc(void *wpa_s, u32 channel) ++static int wpas_delete_transmit_sc(void *wpa_s, struct transmit_sc *sc) + { +- return wpa_drv_delete_transmit_sc(wpa_s, channel); ++ return wpa_drv_delete_transmit_sc(wpa_s, sc); + } + + +-- +2.7.4 + diff --git a/SOURCES/macsec-0006-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch b/SOURCES/macsec-0006-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch new file mode 100644 index 0000000..14d08a4 --- /dev/null +++ b/SOURCES/macsec-0006-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch @@ -0,0 +1,200 @@ +From 5f5ca28414de7ae0b86d4c2aa09c3e67b697dd56 Mon Sep 17 00:00:00 2001 +Message-Id: <5f5ca28414de7ae0b86d4c2aa09c3e67b697dd56.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 7 Oct 2016 12:08:10 +0200 +Subject: [PATCH] mka: Pass full structures down to macsec drivers' receive SC + ops + +Clean up the driver interface by passing pointers to struct receive_sc +down the stack to the {create,delete}_recevie_sc() ops, instead of +passing the individual properties of the SC. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 12 +++++------- + src/drivers/driver_macsec_qca.c | 9 ++++++--- + src/pae/ieee802_1x_kay.h | 5 ++--- + src/pae/ieee802_1x_secy_ops.c | 5 ++--- + wpa_supplicant/driver_i.h | 12 +++++------- + wpa_supplicant/wpas_kay.c | 11 ++++------- + 6 files changed, 24 insertions(+), 30 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 1e2d623..a57aa53 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3368,25 +3368,23 @@ struct wpa_driver_ops { + /** + * create_receive_sc - create secure channel for receiving + * @priv: Private driver interface data +- * @channel: secure channel +- * @sci_addr: secure channel identifier - address +- * @sci_port: secure channel identifier - port ++ * @sc: secure channel + * @conf_offset: confidentiality offset (0, 30, or 50) + * @validation: frame validation policy (0 = Disabled, 1 = Checked, + * 2 = Strict) + * Returns: 0 on success, -1 on failure (or if not supported) + */ +- int (*create_receive_sc)(void *priv, u32 channel, const u8 *sci_addr, +- u16 sci_port, unsigned int conf_offset, ++ int (*create_receive_sc)(void *priv, struct receive_sc *sc, ++ unsigned int conf_offset, + int validation); + + /** + * delete_receive_sc - delete secure connection for receiving + * @priv: private driver interface data from init() +- * @channel: secure channel ++ * @sc: secure channel + * Returns: 0 on success, -1 on failure + */ +- int (*delete_receive_sc)(void *priv, u32 channel); ++ int (*delete_receive_sc)(void *priv, struct receive_sc *sc); + + /** + * create_receive_sa - create secure association for receive +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index fef93df..385f7c5 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -601,8 +601,7 @@ static int macsec_qca_get_available_receive_sc(void *priv, u32 *channel) + } + + +-static int macsec_qca_create_receive_sc(void *priv, u32 channel, +- const u8 *sci_addr, u16 sci_port, ++static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc, + unsigned int conf_offset, + int validation) + { +@@ -611,6 +610,9 @@ static int macsec_qca_create_receive_sc(void *priv, u32 channel, + fal_rx_prc_lut_t entry; + fal_rx_sc_validate_frame_e vf; + enum validate_frames validate_frames = validation; ++ u32 channel = sc->channel; ++ const u8 *sci_addr = sc->sci.addr; ++ u16 sci_port = be_to_host16(sc->sci.port); + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +@@ -649,11 +651,12 @@ static int macsec_qca_create_receive_sc(void *priv, u32 channel, + } + + +-static int macsec_qca_delete_receive_sc(void *priv, u32 channel) ++static int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc) + { + struct macsec_qca_data *drv = priv; + int ret = 0; + fal_rx_prc_lut_t entry; ++ u32 channel = sc->channel; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 8cd5fa6..144ee90 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -146,11 +146,10 @@ struct ieee802_1x_kay_ctx { + int (*get_transmit_next_pn)(void *ctx, struct transmit_sa *sa); + int (*set_transmit_next_pn)(void *ctx, struct transmit_sa *sa); + int (*get_available_receive_sc)(void *ctx, u32 *channel); +- int (*create_receive_sc)(void *ctx, u32 channel, +- struct ieee802_1x_mka_sci *sci, ++ int (*create_receive_sc)(void *ctx, struct receive_sc *sc, + enum validate_frames vf, + enum confidentiality_offset co); +- int (*delete_receive_sc)(void *ctx, u32 channel); ++ int (*delete_receive_sc)(void *ctx, struct receive_sc *sc); + int (*create_receive_sa)(void *ctx, struct receive_sa *sa); + int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index 669dc98..b8fcf05 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -212,8 +212,7 @@ int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc) + return -1; + } + +- return ops->create_receive_sc(ops->ctx, rxsc->channel, &rxsc->sci, +- kay->vf, kay->co); ++ return ops->create_receive_sc(ops->ctx, rxsc, kay->vf, kay->co); + } + + +@@ -233,7 +232,7 @@ int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc) + return -1; + } + +- return ops->delete_receive_sc(ops->ctx, rxsc->channel); ++ return ops->delete_receive_sc(ops->ctx, rxsc); + } + + +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index 2dc74bf..d47395c 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -782,23 +782,21 @@ static inline int wpa_drv_get_available_receive_sc(struct wpa_supplicant *wpa_s, + } + + static inline int +-wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, u32 channel, +- const u8 *sci_addr, u16 sci_port, ++wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, struct receive_sc *sc, + unsigned int conf_offset, int validation) + { + if (!wpa_s->driver->create_receive_sc) + return -1; +- return wpa_s->driver->create_receive_sc(wpa_s->drv_priv, channel, +- sci_addr, sci_port, conf_offset, +- validation); ++ return wpa_s->driver->create_receive_sc(wpa_s->drv_priv, sc, ++ conf_offset, validation); + } + + static inline int wpa_drv_delete_receive_sc(struct wpa_supplicant *wpa_s, +- u32 channel) ++ struct receive_sc *sc) + { + if (!wpa_s->driver->delete_receive_sc) + return -1; +- return wpa_s->driver->delete_receive_sc(wpa_s->drv_priv, channel); ++ return wpa_s->driver->delete_receive_sc(wpa_s->drv_priv, sc); + } + + static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s, +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index e0f8e28..4163b61 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -100,20 +100,17 @@ static unsigned int conf_offset_val(enum confidentiality_offset co) + } + + +-static int wpas_create_receive_sc(void *wpa_s, u32 channel, +- struct ieee802_1x_mka_sci *sci, ++static int wpas_create_receive_sc(void *wpa_s, struct receive_sc *sc, + enum validate_frames vf, + enum confidentiality_offset co) + { +- return wpa_drv_create_receive_sc(wpa_s, channel, sci->addr, +- be_to_host16(sci->port), +- conf_offset_val(co), vf); ++ return wpa_drv_create_receive_sc(wpa_s, sc, conf_offset_val(co), vf); + } + + +-static int wpas_delete_receive_sc(void *wpa_s, u32 channel) ++static int wpas_delete_receive_sc(void *wpa_s, struct receive_sc *sc) + { +- return wpa_drv_delete_receive_sc(wpa_s, channel); ++ return wpa_drv_delete_receive_sc(wpa_s, sc); + } + + +-- +2.7.4 + diff --git a/SOURCES/macsec-0007-mka-Add-driver-op-to-get-macsec-capabilities.patch b/SOURCES/macsec-0007-mka-Add-driver-op-to-get-macsec-capabilities.patch new file mode 100644 index 0000000..9ea4c46 --- /dev/null +++ b/SOURCES/macsec-0007-mka-Add-driver-op-to-get-macsec-capabilities.patch @@ -0,0 +1,219 @@ +From a25e4efc9e428d968e83398bd8c9c94698ba5851 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Fri, 7 Oct 2016 12:08:12 +0200 +Subject: [PATCH] mka: Add driver op to get macsec capabilities + +This also implements the macsec_get_capability for the macsec_qca +driver to maintain the existing behavior. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 8 ++++++++ + src/drivers/driver_macsec_qca.c | 11 +++++++++++ + src/pae/ieee802_1x_kay.c | 18 ++++++++++++++++-- + src/pae/ieee802_1x_kay.h | 1 + + src/pae/ieee802_1x_secy_ops.c | 20 ++++++++++++++++++++ + src/pae/ieee802_1x_secy_ops.h | 1 + + wpa_supplicant/driver_i.h | 8 ++++++++ + wpa_supplicant/wpas_kay.c | 7 +++++++ + 8 files changed, 72 insertions(+), 2 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index a57aa53..ea4a41f 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3298,6 +3298,14 @@ struct wpa_driver_ops { + int (*macsec_deinit)(void *priv); + + /** ++ * macsec_get_capability - Inform MKA of this driver's capability ++ * @priv: Private driver interface data ++ * @cap: Driver's capability ++ * Returns: 0 on success, -1 on failure ++ */ ++ int (*macsec_get_capability)(void *priv, enum macsec_cap *cap); ++ ++ /** + * enable_protect_frames - Set protect frames status + * @priv: Private driver interface data + * @enabled: TRUE = protect frames enabled +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 385f7c5..041bcf5 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -458,6 +458,16 @@ static int macsec_qca_macsec_deinit(void *priv) + } + + ++static int macsec_qca_get_capability(void *priv, enum macsec_cap *cap) ++{ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ *cap = MACSEC_CAP_INTEG_AND_CONF_0_30_50; ++ ++ return 0; ++} ++ ++ + static int macsec_qca_enable_protect_frames(void *priv, Boolean enabled) + { + struct macsec_qca_data *drv = priv; +@@ -889,6 +899,7 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = { + + .macsec_init = macsec_qca_macsec_init, + .macsec_deinit = macsec_qca_macsec_deinit, ++ .macsec_get_capability = macsec_qca_get_capability, + .enable_protect_frames = macsec_qca_enable_protect_frames, + .set_replay_protect = macsec_qca_set_replay_protect, + .set_current_cipher_suite = macsec_qca_set_current_cipher_suite, +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index a8e7efc..52eeeff 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3069,13 +3069,20 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + kay->macsec_replay_window = 0; + kay->macsec_confidentiality = CONFIDENTIALITY_NONE; + } else { +- kay->macsec_capable = MACSEC_CAP_INTEG_AND_CONF_0_30_50; ++ if (secy_get_capability(kay, &kay->macsec_capable) < 0) { ++ os_free(kay); ++ return NULL; ++ } ++ + kay->macsec_desired = TRUE; + kay->macsec_protect = TRUE; + kay->macsec_validate = Strict; + kay->macsec_replay_protect = FALSE; + kay->macsec_replay_window = 0; +- kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; ++ if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF) ++ kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; ++ else ++ kay->macsec_confidentiality = MACSEC_CAP_INTEGRITY; + } + + wpa_printf(MSG_DEBUG, "KaY: state machine created"); +@@ -3409,6 +3416,7 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, + unsigned int cs_index) + { + struct ieee802_1x_mka_participant *participant; ++ enum macsec_cap secy_cap; + + if (!kay) + return -1; +@@ -3427,6 +3435,12 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, + kay->macsec_csindex = cs_index; + kay->macsec_capable = cipher_suite_tbl[kay->macsec_csindex].capable; + ++ if (secy_get_capability(kay, &secy_cap) < 0) ++ return -3; ++ ++ if (kay->macsec_capable > secy_cap) ++ kay->macsec_capable = secy_cap; ++ + participant = ieee802_1x_kay_get_principal_participant(kay); + if (participant) { + wpa_printf(MSG_INFO, "KaY: Cipher Suite changed"); +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 144ee90..bf6fbe5 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -138,6 +138,7 @@ struct ieee802_1x_kay_ctx { + /* abstract wpa driver interface */ + int (*macsec_init)(void *ctx, struct macsec_init_params *params); + int (*macsec_deinit)(void *ctx); ++ int (*macsec_get_capability)(void *priv, enum macsec_cap *cap); + int (*enable_protect_frames)(void *ctx, Boolean enabled); + int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window); + int (*set_current_cipher_suite)(void *ctx, u64 cs); +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index b8fcf05..32ee816 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -113,6 +113,26 @@ int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean enabled) + } + + ++int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap) ++{ ++ struct ieee802_1x_kay_ctx *ops; ++ ++ if (!kay) { ++ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); ++ return -1; ++ } ++ ++ ops = kay->ctx; ++ if (!ops || !ops->macsec_get_capability) { ++ wpa_printf(MSG_ERROR, ++ "KaY: secy macsec_get_capability operation not supported"); ++ return -1; ++ } ++ ++ return ops->macsec_get_capability(ops->ctx, cap); ++} ++ ++ + int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay, + struct receive_sa *rxsa) + { +diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h +index 120ca3c..bfd5737 100644 +--- a/src/pae/ieee802_1x_secy_ops.h ++++ b/src/pae/ieee802_1x_secy_ops.h +@@ -28,6 +28,7 @@ int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay, + int secy_cp_control_enable_port(struct ieee802_1x_kay *kay, Boolean flag); + + /****** KaY -> SecY *******/ ++int secy_get_capability(struct ieee802_1x_kay *kay, enum macsec_cap *cap); + int secy_get_receive_lowest_pn(struct ieee802_1x_kay *kay, + struct receive_sa *rxsa); + int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay, +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index d47395c..5d5dcf0 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -715,6 +715,14 @@ static inline int wpa_drv_macsec_deinit(struct wpa_supplicant *wpa_s) + return wpa_s->driver->macsec_deinit(wpa_s->drv_priv); + } + ++static inline int wpa_drv_macsec_get_capability(struct wpa_supplicant *wpa_s, ++ enum macsec_cap *cap) ++{ ++ if (!wpa_s->driver->macsec_get_capability) ++ return -1; ++ return wpa_s->driver->macsec_get_capability(wpa_s->drv_priv, cap); ++} ++ + static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s, + Boolean enabled) + { +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 4163b61..29b7b56 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -38,6 +38,12 @@ static int wpas_macsec_deinit(void *priv) + } + + ++static int wpas_macsec_get_capability(void *priv, enum macsec_cap *cap) ++{ ++ return wpa_drv_macsec_get_capability(priv, cap); ++} ++ ++ + static int wpas_enable_protect_frames(void *wpa_s, Boolean enabled) + { + return wpa_drv_enable_protect_frames(wpa_s, enabled); +@@ -191,6 +197,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + + kay_ctx->macsec_init = wpas_macsec_init; + kay_ctx->macsec_deinit = wpas_macsec_deinit; ++ kay_ctx->macsec_get_capability = wpas_macsec_get_capability; + kay_ctx->enable_protect_frames = wpas_enable_protect_frames; + kay_ctx->set_replay_protect = wpas_set_replay_protect; + kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite; +-- +2.7.4 + diff --git a/SOURCES/macsec-0008-mka-Remove-channel-hacks-from-the-stack-and-the-macs.patch b/SOURCES/macsec-0008-mka-Remove-channel-hacks-from-the-stack-and-the-macs.patch new file mode 100644 index 0000000..cab3859 --- /dev/null +++ b/SOURCES/macsec-0008-mka-Remove-channel-hacks-from-the-stack-and-the-macs.patch @@ -0,0 +1,774 @@ +From 6f551abdfca16021e7cd9d4ac891e3eb27010a90 Mon Sep 17 00:00:00 2001 +Message-Id: <6f551abdfca16021e7cd9d4ac891e3eb27010a90.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 21 Oct 2016 14:45:26 +0200 +Subject: [PATCH] mka: Remove "channel" hacks from the stack and the macsec_qca + driver + +This is specific to the macsec_qca driver. The core implementation +shouldn't care about this, and only deal with the complete secure +channel, and pass this down to the driver. + +Drivers that have such limitations should take care of these in their +->create functions and throw an error. + +Since the core MKA no longer saves the channel number, the macsec_qca +driver must be able to recover it. Add a map (which is just an array +since it's quite short) to match SCIs to channel numbers, and lookup +functions that will be called in every place where functions would get +the channel from the core code. Getting an available channel should be +part of channel creation, instead of being a preparation step. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 16 ---- + src/drivers/driver_macsec_qca.c | 174 +++++++++++++++++++++++++++++++++------- + src/pae/ieee802_1x_kay.c | 41 +++------- + src/pae/ieee802_1x_kay.h | 7 -- + src/pae/ieee802_1x_secy_ops.c | 40 --------- + src/pae/ieee802_1x_secy_ops.h | 2 - + wpa_supplicant/driver_i.h | 18 ----- + wpa_supplicant/wpas_kay.c | 14 ---- + 8 files changed, 159 insertions(+), 153 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index aeb9694..54ae6b7 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3390,14 +3390,6 @@ struct wpa_driver_ops { + int (*set_transmit_next_pn)(void *priv, struct transmit_sa *sa); + + /** +- * get_available_receive_sc - get available receive channel +- * @priv: Private driver interface data +- * @channel: secure channel +- * Returns: 0 on success, -1 on failure (or if not supported) +- */ +- int (*get_available_receive_sc)(void *priv, u32 *channel); +- +- /** + * create_receive_sc - create secure channel for receiving + * @priv: Private driver interface data + * @sc: secure channel +@@ -3443,14 +3435,6 @@ struct wpa_driver_ops { + int (*disable_receive_sa)(void *priv, struct receive_sa *sa); + + /** +- * get_available_transmit_sc - get available transmit channel +- * @priv: Private driver interface data +- * @channel: secure channel +- * Returns: 0 on success, -1 on failure (or if not supported) +- */ +- int (*get_available_transmit_sc)(void *priv, u32 *channel); +- +- /** + * create_transmit_sc - create secure connection for transmit + * @priv: private driver interface data from init() + * @sc: secure channel +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 041bcf5..22d414c 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -56,6 +56,10 @@ + static const u8 pae_group_addr[ETH_ALEN] = + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + ++struct channel_map { ++ struct ieee802_1x_mka_sci sci; ++}; ++ + struct macsec_qca_data { + char ifname[IFNAMSIZ + 1]; + u32 secy_id; +@@ -72,6 +76,9 @@ struct macsec_qca_data { + Boolean protect_frames; + Boolean replay_protect; + u32 replay_window; ++ ++ struct channel_map receive_channel_map[MAXSC]; ++ struct channel_map transmit_channel_map[MAXSC]; + }; + + +@@ -526,6 +533,68 @@ static int macsec_qca_enable_controlled_port(void *priv, Boolean enabled) + } + + ++static int macsec_qca_lookup_channel(struct channel_map *map, ++ struct ieee802_1x_mka_sci *sci, ++ u32 *channel) ++{ ++ u32 i; ++ ++ for (i = 0; i < MAXSC; i++) { ++ if (os_memcmp(&map[i].sci, sci, ++ sizeof(struct ieee802_1x_mka_sci)) == 0) { ++ *channel = i; ++ return 0; ++ } ++ } ++ ++ return -1; ++} ++ ++ ++static void macsec_qca_register_channel(struct channel_map *map, ++ struct ieee802_1x_mka_sci *sci, ++ u32 channel) ++{ ++ os_memcpy(&map[channel].sci, sci, sizeof(struct ieee802_1x_mka_sci)); ++} ++ ++ ++static int macsec_qca_lookup_receive_channel(struct macsec_qca_data *drv, ++ struct receive_sc *sc, ++ u32 *channel) ++{ ++ return macsec_qca_lookup_channel(drv->receive_channel_map, &sc->sci, ++ channel); ++} ++ ++ ++static void macsec_qca_register_receive_channel(struct macsec_qca_data *drv, ++ struct receive_sc *sc, ++ u32 channel) ++{ ++ macsec_qca_register_channel(drv->receive_channel_map, &sc->sci, ++ channel); ++} ++ ++ ++static int macsec_qca_lookup_transmit_channel(struct macsec_qca_data *drv, ++ struct transmit_sc *sc, ++ u32 *channel) ++{ ++ return macsec_qca_lookup_channel(drv->transmit_channel_map, &sc->sci, ++ channel); ++} ++ ++ ++static void macsec_qca_register_transmit_channel(struct macsec_qca_data *drv, ++ struct transmit_sc *sc, ++ u32 channel) ++{ ++ macsec_qca_register_channel(drv->transmit_channel_map, &sc->sci, ++ channel); ++} ++ ++ + static int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; +@@ -533,7 +602,11 @@ static int macsec_qca_get_receive_lowest_pn(void *priv, struct receive_sa *sa) + u32 next_pn = 0; + bool enabled = FALSE; + u32 win; +- u32 channel = sa->sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + ret += nss_macsec_secy_rx_sa_next_pn_get(drv->secy_id, channel, sa->an, + &next_pn); +@@ -557,7 +630,11 @@ static int macsec_qca_get_transmit_next_pn(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; +- u32 channel = sa->sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + ret += nss_macsec_secy_tx_sa_next_pn_get(drv->secy_id, channel, sa->an, + &sa->next_pn); +@@ -572,8 +649,11 @@ int macsec_qca_set_transmit_next_pn(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; + int ret = 0; +- u32 channel = sa->sc->channel; ++ u32 channel; + ++ ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + ret += nss_macsec_secy_tx_sa_next_pn_set(drv->secy_id, channel, sa->an, + sa->next_pn); +@@ -620,10 +700,14 @@ static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc, + fal_rx_prc_lut_t entry; + fal_rx_sc_validate_frame_e vf; + enum validate_frames validate_frames = validation; +- u32 channel = sc->channel; ++ u32 channel; + const u8 *sci_addr = sc->sci.addr; + u16 sci_port = be_to_host16(sc->sci.port); + ++ ret = macsec_qca_get_available_receive_sc(priv, &channel); ++ if (ret != 0) ++ return ret; ++ + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + + /* rx prc lut */ +@@ -657,6 +741,8 @@ static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc, + channel, + drv->replay_window); + ++ macsec_qca_register_receive_channel(drv, sc, channel); ++ + return ret; + } + +@@ -664,9 +750,13 @@ static int macsec_qca_create_receive_sc(void *priv, struct receive_sc *sc, + static int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; ++ int ret; + fal_rx_prc_lut_t entry; +- u32 channel = sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_receive_channel(priv, sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +@@ -683,10 +773,14 @@ static int macsec_qca_delete_receive_sc(void *priv, struct receive_sc *sc) + static int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; ++ int ret; + fal_rx_sak_t rx_sak; + int i = 0; +- u32 channel = sa->sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s, channel=%d, an=%d, lpn=0x%x", + __func__, channel, sa->an, sa->lowest_pn); +@@ -706,9 +800,12 @@ static int macsec_qca_create_receive_sa(void *priv, struct receive_sa *sa) + static int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; +- u32 channel = sa->sc->channel; ++ int ret; ++ u32 channel; + ++ ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, + sa->an); +@@ -723,8 +820,12 @@ static int macsec_qca_enable_receive_sa(void *priv, struct receive_sa *sa) + static int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; +- u32 channel = sa->sc->channel; ++ int ret; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_receive_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, + sa->an); +@@ -739,14 +840,12 @@ static int macsec_qca_disable_receive_sa(void *priv, struct receive_sa *sa) + static int macsec_qca_get_available_transmit_sc(void *priv, u32 *channel) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; + u32 sc_ch = 0; + bool in_use = FALSE; + + for (sc_ch = 0; sc_ch < MAXSC; sc_ch++) { +- ret = nss_macsec_secy_tx_sc_in_used_get(drv->secy_id, sc_ch, +- &in_use); +- if (ret) ++ if (nss_macsec_secy_tx_sc_in_used_get(drv->secy_id, sc_ch, ++ &in_use)) + continue; + + if (!in_use) { +@@ -767,10 +866,14 @@ static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc, + unsigned int conf_offset) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; ++ int ret; + fal_tx_class_lut_t entry; + u8 psci[ETH_ALEN + 2]; +- u32 channel = sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_get_available_transmit_sc(priv, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +@@ -793,6 +896,8 @@ static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc, + channel, + conf_offset); + ++ macsec_qca_register_transmit_channel(drv, sc, channel); ++ + return ret; + } + +@@ -800,9 +905,13 @@ static int macsec_qca_create_transmit_sc(void *priv, struct transmit_sc *sc, + static int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; ++ int ret; + fal_tx_class_lut_t entry; +- u32 channel = sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_transmit_channel(priv, sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d", __func__, channel); + +@@ -819,11 +928,15 @@ static int macsec_qca_delete_transmit_sc(void *priv, struct transmit_sc *sc) + static int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; ++ int ret; + u8 tci = 0; + fal_tx_sak_t tx_sak; + int i; +- u32 channel = sa->sc->channel; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, + "%s: channel=%d, an=%d, next_pn=0x%x, confidentiality=%d", +@@ -858,9 +971,12 @@ static int macsec_qca_create_transmit_sa(void *priv, struct transmit_sa *sa) + static int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; +- u32 channel = sa->sc->channel; ++ int ret; ++ u32 channel; + ++ ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, + sa->an); +@@ -875,8 +991,12 @@ static int macsec_qca_enable_transmit_sa(void *priv, struct transmit_sa *sa) + static int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa) + { + struct macsec_qca_data *drv = priv; +- int ret = 0; +- u32 channel = sa->sc->channel; ++ int ret; ++ u32 channel; ++ ++ ret = macsec_qca_lookup_transmit_channel(priv, sa->sc, &channel); ++ if (ret != 0) ++ return ret; + + wpa_printf(MSG_DEBUG, "%s: channel=%d, an=%d", __func__, channel, + sa->an); +@@ -907,13 +1027,11 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = { + .get_receive_lowest_pn = macsec_qca_get_receive_lowest_pn, + .get_transmit_next_pn = macsec_qca_get_transmit_next_pn, + .set_transmit_next_pn = macsec_qca_set_transmit_next_pn, +- .get_available_receive_sc = macsec_qca_get_available_receive_sc, + .create_receive_sc = macsec_qca_create_receive_sc, + .delete_receive_sc = macsec_qca_delete_receive_sc, + .create_receive_sa = macsec_qca_create_receive_sa, + .enable_receive_sa = macsec_qca_enable_receive_sa, + .disable_receive_sa = macsec_qca_disable_receive_sa, +- .get_available_transmit_sc = macsec_qca_get_available_transmit_sc, + .create_transmit_sc = macsec_qca_create_transmit_sc, + .delete_transmit_sc = macsec_qca_delete_transmit_sc, + .create_transmit_sa = macsec_qca_create_transmit_sa, +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 52eeeff..38a8293 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -440,8 +440,8 @@ ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, + + dl_list_add(&psc->sa_list, &psa->list); + wpa_printf(MSG_DEBUG, +- "KaY: Create receive SA(AN: %hhu lowest_pn: %u of SC(channel: %d)", +- an, lowest_pn, psc->channel); ++ "KaY: Create receive SA(AN: %hhu lowest_pn: %u of SC", ++ an, lowest_pn); + + return psa; + } +@@ -465,8 +465,7 @@ static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa) + * ieee802_1x_kay_init_receive_sc - + */ + static struct receive_sc * +-ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci, +- int channel) ++ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci) + { + struct receive_sc *psc; + +@@ -480,13 +479,12 @@ ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci, + } + + os_memcpy(&psc->sci, psci, sizeof(psc->sci)); +- psc->channel = channel; + + os_get_time(&psc->created_time); + psc->receiving = FALSE; + + dl_list_init(&psc->sa_list); +- wpa_printf(MSG_DEBUG, "KaY: Create receive SC(channel: %d)", channel); ++ wpa_printf(MSG_DEBUG, "KaY: Create receive SC"); + wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)psci, sizeof(*psci)); + + return psc; +@@ -502,8 +500,7 @@ ieee802_1x_kay_deinit_receive_sc( + { + struct receive_sa *psa, *pre_sa; + +- wpa_printf(MSG_DEBUG, "KaY: Delete receive SC(channel: %d)", +- psc->channel); ++ wpa_printf(MSG_DEBUG, "KaY: Delete receive SC"); + dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, + list) { + secy_disable_receive_sa(participant->kay, psa); +@@ -552,7 +549,6 @@ ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant, + { + struct ieee802_1x_kay_peer *peer; + struct receive_sc *rxsc; +- u32 sc_ch = 0; + + peer = ieee802_1x_kay_create_peer(mi, mn); + if (!peer) +@@ -561,9 +557,7 @@ ieee802_1x_kay_create_live_peer(struct ieee802_1x_mka_participant *participant, + os_memcpy(&peer->sci, &participant->current_peer_sci, + sizeof(peer->sci)); + +- secy_get_available_receive_sc(participant->kay, &sc_ch); +- +- rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci, sc_ch); ++ rxsc = ieee802_1x_kay_init_receive_sc(&peer->sci); + if (!rxsc) { + os_free(peer); + return NULL; +@@ -611,12 +605,10 @@ ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant, + { + struct ieee802_1x_kay_peer *peer; + struct receive_sc *rxsc; +- u32 sc_ch = 0; + + peer = ieee802_1x_kay_get_potential_peer(participant, mi); + +- rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci, +- sc_ch); ++ rxsc = ieee802_1x_kay_init_receive_sc(&participant->current_peer_sci); + if (!rxsc) + return NULL; + +@@ -631,8 +623,6 @@ ieee802_1x_kay_move_live_peer(struct ieee802_1x_mka_participant *participant, + dl_list_del(&peer->list); + dl_list_add_tail(&participant->live_peers, &peer->list); + +- secy_get_available_receive_sc(participant->kay, &sc_ch); +- + dl_list_add(&participant->rxsc_list, &rxsc->list); + secy_create_receive_sc(participant->kay, rxsc); + +@@ -2438,8 +2428,8 @@ ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, + + dl_list_add(&psc->sa_list, &psa->list); + wpa_printf(MSG_DEBUG, +- "KaY: Create transmit SA(an: %hhu, next_PN: %u) of SC(channel: %d)", +- an, next_PN, psc->channel); ++ "KaY: Create transmit SA(an: %hhu, next_PN: %u) of SC", ++ an, next_PN); + + return psa; + } +@@ -2463,8 +2453,7 @@ static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa) + * init_transmit_sc - + */ + static struct transmit_sc * +-ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci, +- int channel) ++ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci) + { + struct transmit_sc *psc; + +@@ -2474,7 +2463,6 @@ ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci, + return NULL; + } + os_memcpy(&psc->sci, sci, sizeof(psc->sci)); +- psc->channel = channel; + + os_get_time(&psc->created_time); + psc->transmitting = FALSE; +@@ -2482,7 +2470,7 @@ ieee802_1x_kay_init_transmit_sc(const struct ieee802_1x_mka_sci *sci, + psc->enciphering_sa = FALSE; + + dl_list_init(&psc->sa_list); +- wpa_printf(MSG_DEBUG, "KaY: Create transmit SC(channel: %d)", channel); ++ wpa_printf(MSG_DEBUG, "KaY: Create transmit SC"); + wpa_hexdump(MSG_DEBUG, "SCI: ", (u8 *)sci , sizeof(*sci)); + + return psc; +@@ -2498,8 +2486,7 @@ ieee802_1x_kay_deinit_transmit_sc( + { + struct transmit_sa *psa, *tmp; + +- wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC(channel: %d)", +- psc->channel); ++ wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC"); + dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, + list) { + secy_disable_transmit_sa(participant->kay, psa); +@@ -3089,7 +3076,6 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + + /* Initialize the SecY must be prio to CP, as CP will control SecY */ + secy_init_macsec(kay); +- secy_get_available_transmit_sc(kay, &kay->sc_ch); + + wpa_printf(MSG_DEBUG, "KaY: secy init macsec done"); + +@@ -3250,8 +3236,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn, + dl_list_init(&participant->sak_list); + participant->new_key = NULL; + dl_list_init(&participant->rxsc_list); +- participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci, +- kay->sc_ch); ++ participant->txsc = ieee802_1x_kay_init_transmit_sc(&kay->actor_sci); + secy_cp_control_protect_frames(kay, kay->macsec_protect); + secy_cp_control_replay(kay, kay->macsec_replay_protect, + kay->macsec_replay_window); +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index bf6fbe5..c6fa387 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -80,8 +80,6 @@ struct transmit_sc { + u8 enciphering_sa; /* AN encipheringSA (read only) */ + + /* not defined data */ +- unsigned int channel; +- + struct dl_list list; + struct dl_list sa_list; + }; +@@ -109,8 +107,6 @@ struct receive_sc { + + struct os_time created_time; /* Time createdTime */ + +- unsigned int channel; +- + struct dl_list list; + struct dl_list sa_list; + }; +@@ -146,7 +142,6 @@ struct ieee802_1x_kay_ctx { + int (*get_receive_lowest_pn)(void *ctx, struct receive_sa *sa); + int (*get_transmit_next_pn)(void *ctx, struct transmit_sa *sa); + int (*set_transmit_next_pn)(void *ctx, struct transmit_sa *sa); +- int (*get_available_receive_sc)(void *ctx, u32 *channel); + int (*create_receive_sc)(void *ctx, struct receive_sc *sc, + enum validate_frames vf, + enum confidentiality_offset co); +@@ -154,7 +149,6 @@ struct ieee802_1x_kay_ctx { + int (*create_receive_sa)(void *ctx, struct receive_sa *sa); + int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); +- int (*get_available_transmit_sc)(void *ctx, u32 *channel); + int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, + enum confidentiality_offset co); + int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); +@@ -209,7 +203,6 @@ struct ieee802_1x_kay { + + u8 mka_version; + u8 algo_agility[4]; +- u32 sc_ch; + + u32 pn_exhaustion; + Boolean port_enable; +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index 32ee816..b57c670 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -196,26 +196,6 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay, + } + + +-int secy_get_available_receive_sc(struct ieee802_1x_kay *kay, u32 *channel) +-{ +- struct ieee802_1x_kay_ctx *ops; +- +- if (!kay) { +- wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); +- return -1; +- } +- +- ops = kay->ctx; +- if (!ops || !ops->get_available_receive_sc) { +- wpa_printf(MSG_ERROR, +- "KaY: secy get_available_receive_sc operation not supported"); +- return -1; +- } +- +- return ops->get_available_receive_sc(ops->ctx, channel); +-} +- +- + int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc) + { + struct ieee802_1x_kay_ctx *ops; +@@ -320,26 +300,6 @@ int secy_disable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + } + + +-int secy_get_available_transmit_sc(struct ieee802_1x_kay *kay, u32 *channel) +-{ +- struct ieee802_1x_kay_ctx *ops; +- +- if (!kay) { +- wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); +- return -1; +- } +- +- ops = kay->ctx; +- if (!ops || !ops->get_available_transmit_sc) { +- wpa_printf(MSG_ERROR, +- "KaY: secy get_available_transmit_sc operation not supported"); +- return -1; +- } +- +- return ops->get_available_transmit_sc(ops->ctx, channel); +-} +- +- + int secy_create_transmit_sc(struct ieee802_1x_kay *kay, + struct transmit_sc *txsc) + { +diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h +index bfd5737..59f0baa 100644 +--- a/src/pae/ieee802_1x_secy_ops.h ++++ b/src/pae/ieee802_1x_secy_ops.h +@@ -35,7 +35,6 @@ int secy_get_transmit_next_pn(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa); + int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa); +-int secy_get_available_receive_sc(struct ieee802_1x_kay *kay, u32 *channel); + int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); + int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); + int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); +@@ -43,7 +42,6 @@ int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); + int secy_disable_receive_sa(struct ieee802_1x_kay *kay, + struct receive_sa *rxsa); + +-int secy_get_available_transmit_sc(struct ieee802_1x_kay *kay, u32 *channel); + int secy_create_transmit_sc(struct ieee802_1x_kay *kay, + struct transmit_sc *txsc); + int secy_delete_transmit_sc(struct ieee802_1x_kay *kay, +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index f8efddc..244e386 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -780,15 +780,6 @@ static inline int wpa_drv_set_transmit_next_pn(struct wpa_supplicant *wpa_s, + return wpa_s->driver->set_transmit_next_pn(wpa_s->drv_priv, sa); + } + +-static inline int wpa_drv_get_available_receive_sc(struct wpa_supplicant *wpa_s, +- u32 *channel) +-{ +- if (!wpa_s->driver->get_available_receive_sc) +- return -1; +- return wpa_s->driver->get_available_receive_sc(wpa_s->drv_priv, +- channel); +-} +- + static inline int + wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, struct receive_sc *sc, + unsigned int conf_offset, int validation) +@@ -832,15 +823,6 @@ static inline int wpa_drv_disable_receive_sa(struct wpa_supplicant *wpa_s, + } + + static inline int +-wpa_drv_get_available_transmit_sc(struct wpa_supplicant *wpa_s, u32 *channel) +-{ +- if (!wpa_s->driver->get_available_transmit_sc) +- return -1; +- return wpa_s->driver->get_available_transmit_sc(wpa_s->drv_priv, +- channel); +-} +- +-static inline int + wpa_drv_create_transmit_sc(struct wpa_supplicant *wpa_s, struct transmit_sc *sc, + unsigned int conf_offset) + { +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 29b7b56..64364f7 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -86,12 +86,6 @@ static int wpas_set_transmit_next_pn(void *wpa_s, struct transmit_sa *sa) + } + + +-static int wpas_get_available_receive_sc(void *wpa_s, u32 *channel) +-{ +- return wpa_drv_get_available_receive_sc(wpa_s, channel); +-} +- +- + static unsigned int conf_offset_val(enum confidentiality_offset co) + { + switch (co) { +@@ -138,12 +132,6 @@ static int wpas_disable_receive_sa(void *wpa_s, struct receive_sa *sa) + } + + +-static int wpas_get_available_transmit_sc(void *wpa_s, u32 *channel) +-{ +- return wpa_drv_get_available_transmit_sc(wpa_s, channel); +-} +- +- + static int + wpas_create_transmit_sc(void *wpa_s, struct transmit_sc *sc, + enum confidentiality_offset co) +@@ -205,13 +193,11 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + kay_ctx->get_receive_lowest_pn = wpas_get_receive_lowest_pn; + kay_ctx->get_transmit_next_pn = wpas_get_transmit_next_pn; + kay_ctx->set_transmit_next_pn = wpas_set_transmit_next_pn; +- kay_ctx->get_available_receive_sc = wpas_get_available_receive_sc; + kay_ctx->create_receive_sc = wpas_create_receive_sc; + kay_ctx->delete_receive_sc = wpas_delete_receive_sc; + kay_ctx->create_receive_sa = wpas_create_receive_sa; + kay_ctx->enable_receive_sa = wpas_enable_receive_sa; + kay_ctx->disable_receive_sa = wpas_disable_receive_sa; +- kay_ctx->get_available_transmit_sc = wpas_get_available_transmit_sc; + kay_ctx->create_transmit_sc = wpas_create_transmit_sc; + kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc; + kay_ctx->create_transmit_sa = wpas_create_transmit_sa; +-- +2.7.4 + diff --git a/SOURCES/macsec-0009-mka-Sync-structs-definitions-with-IEEE-Std-802.1X-20.patch b/SOURCES/macsec-0009-mka-Sync-structs-definitions-with-IEEE-Std-802.1X-20.patch new file mode 100644 index 0000000..18a88b2 --- /dev/null +++ b/SOURCES/macsec-0009-mka-Sync-structs-definitions-with-IEEE-Std-802.1X-20.patch @@ -0,0 +1,180 @@ +From 6b6175b788c5f44ff40f61003cbdb315dfabe0a2 Mon Sep 17 00:00:00 2001 +Message-Id: <6b6175b788c5f44ff40f61003cbdb315dfabe0a2.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 21 Oct 2016 14:45:27 +0200 +Subject: [PATCH] mka: Sync structs definitions with IEEE Std 802.1X-2010 + +Document some data structures from IEEE Std 802.1X-2010, and add the +(not used yet) struct ieee802_1x_mka_dist_cak_body. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.h | 8 +++- + src/pae/ieee802_1x_kay_i.h | 97 +++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 103 insertions(+), 2 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index c6fa387..e2ba180 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -15,7 +15,7 @@ + + struct macsec_init_params; + +-#define MI_LEN 12 ++#define MI_LEN 12 /* 96-bit Member Identifier */ + #define MAX_KEY_LEN 32 /* 32 bytes, 256 bits */ + #define MAX_CKN_LEN 32 /* 32 bytes, 256 bits */ + +@@ -24,6 +24,12 @@ struct macsec_init_params; + #define MKA_LIFE_TIME 6000 + #define MKA_SAK_RETIRE_TIME 3000 + ++/** ++ * struct ieee802_1x_mka_ki - Key Identifier (KI) ++ * @mi: Key Server's Member Identifier ++ * @kn: Key Number, assigned by the Key Server ++ * IEEE 802.1X-2010 9.8 SAK generation, distribution, and selection ++ */ + struct ieee802_1x_mka_ki { + u8 mi[MI_LEN]; + u32 kn; +diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h +index e3d7db4..0c4bb8e 100644 +--- a/src/pae/ieee802_1x_kay_i.h ++++ b/src/pae/ieee802_1x_kay_i.h +@@ -168,6 +168,22 @@ struct ieee802_1x_mka_hdr { + + #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; +@@ -197,6 +213,14 @@ struct ieee802_1x_mka_basic_body { + u8 ckn[0]; + }; + ++/** ++ * 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; +@@ -217,6 +241,28 @@ struct ieee802_1x_mka_peer_body { + /* followed by Peers */ + }; + ++/** ++ * 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; +@@ -270,7 +316,21 @@ struct ieee802_1x_mka_sak_use_body { + be32 olpn; + }; + +- ++/** ++ * 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; +@@ -303,6 +363,41 @@ struct ieee802_1x_mka_dist_sak_body { + u8 sak[0]; + }; + ++/** ++ * 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 ieee802_1x_mka_icv_body { + /* octet 1 */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0010-mka-Add-support-for-removing-SAs.patch b/SOURCES/macsec-0010-mka-Add-support-for-removing-SAs.patch new file mode 100644 index 0000000..c0fa74b --- /dev/null +++ b/SOURCES/macsec-0010-mka-Add-support-for-removing-SAs.patch @@ -0,0 +1,388 @@ +From 23c3528a8461681b23c94ed441cd94c8d528bebe Mon Sep 17 00:00:00 2001 +Message-Id: <23c3528a8461681b23c94ed441cd94c8d528bebe.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 21 Oct 2016 14:45:28 +0200 +Subject: [PATCH] mka: Add support for removing SAs + +So that the core can notify drivers that need to perform some operations +when an SA is deleted. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 16 +++++++++ + src/pae/ieee802_1x_kay.c | 81 +++++++++++++++++++++++++++++++++---------- + src/pae/ieee802_1x_kay.h | 2 ++ + src/pae/ieee802_1x_secy_ops.c | 41 ++++++++++++++++++++++ + src/pae/ieee802_1x_secy_ops.h | 3 ++ + wpa_supplicant/driver_i.h | 16 +++++++++ + wpa_supplicant/wpas_kay.c | 14 ++++++++ + 7 files changed, 154 insertions(+), 19 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 54ae6b7..9a6db90 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3419,6 +3419,14 @@ struct wpa_driver_ops { + int (*create_receive_sa)(void *priv, struct receive_sa *sa); + + /** ++ * delete_receive_sa - Delete secure association for receive ++ * @priv: Private driver interface data from init() ++ * @sa: Secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++ int (*delete_receive_sa)(void *priv, struct receive_sa *sa); ++ ++ /** + * enable_receive_sa - enable the SA for receive + * @priv: private driver interface data from init() + * @sa: secure association +@@ -3461,6 +3469,14 @@ struct wpa_driver_ops { + int (*create_transmit_sa)(void *priv, struct transmit_sa *sa); + + /** ++ * delete_transmit_sa - Delete secure association for transmit ++ * @priv: Private driver interface data from init() ++ * @sa: Secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++ int (*delete_transmit_sa)(void *priv, struct transmit_sa *sa); ++ ++ /** + * enable_transmit_sa - enable SA for transmit + * @priv: private driver interface data from init() + * @sa: secure association +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 38a8293..e312d04 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -491,6 +491,15 @@ ieee802_1x_kay_init_receive_sc(const struct ieee802_1x_mka_sci *psci) + } + + ++static void ieee802_1x_delete_receive_sa(struct ieee802_1x_kay *kay, ++ struct receive_sa *sa) ++{ ++ secy_disable_receive_sa(kay, sa); ++ secy_delete_receive_sa(kay, sa); ++ ieee802_1x_kay_deinit_receive_sa(sa); ++} ++ ++ + /** + * ieee802_1x_kay_deinit_receive_sc - + **/ +@@ -502,10 +511,9 @@ ieee802_1x_kay_deinit_receive_sc( + + wpa_printf(MSG_DEBUG, "KaY: Delete receive SC"); + dl_list_for_each_safe(psa, pre_sa, &psc->sa_list, struct receive_sa, +- list) { +- secy_disable_receive_sa(participant->kay, psa); +- ieee802_1x_kay_deinit_receive_sa(psa); +- } ++ list) ++ ieee802_1x_delete_receive_sa(participant->kay, psa); ++ + dl_list_del(&psc->list); + os_free(psc); + } +@@ -2270,6 +2278,16 @@ ieee802_1x_participant_send_mkpdu( + + + static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa); ++ ++static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay, ++ struct transmit_sa *sa) ++{ ++ secy_disable_transmit_sa(kay, sa); ++ secy_delete_transmit_sa(kay, sa); ++ ieee802_1x_kay_deinit_transmit_sa(sa); ++} ++ ++ + /** + * ieee802_1x_participant_timer - + */ +@@ -2344,8 +2362,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) + dl_list_for_each_safe(txsa, pre_txsa, + &participant->txsc->sa_list, + struct transmit_sa, list) { +- secy_disable_transmit_sa(kay, txsa); +- ieee802_1x_kay_deinit_transmit_sa(txsa); ++ ieee802_1x_delete_transmit_sa(kay, txsa); + } + + ieee802_1x_cp_connect_authenticated(kay->cp); +@@ -2487,11 +2504,8 @@ ieee802_1x_kay_deinit_transmit_sc( + struct transmit_sa *psa, *tmp; + + wpa_printf(MSG_DEBUG, "KaY: Delete transmit SC"); +- dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, +- list) { +- secy_disable_transmit_sa(participant->kay, psa); +- ieee802_1x_kay_deinit_transmit_sa(psa); +- } ++ dl_list_for_each_safe(psa, tmp, &psc->sa_list, struct transmit_sa, list) ++ ieee802_1x_delete_transmit_sa(participant->kay, psa); + + os_free(psc); + } +@@ -2569,6 +2583,32 @@ int ieee802_1x_kay_set_old_sa_attr(struct ieee802_1x_kay *kay, + } + + ++static struct transmit_sa * lookup_txsa_by_an(struct transmit_sc *txsc, u8 an) ++{ ++ struct transmit_sa *txsa; ++ ++ dl_list_for_each(txsa, &txsc->sa_list, struct transmit_sa, list) { ++ if (txsa->an == an) ++ return txsa; ++ } ++ ++ return NULL; ++} ++ ++ ++static struct receive_sa * lookup_rxsa_by_an(struct receive_sc *rxsc, u8 an) ++{ ++ struct receive_sa *rxsa; ++ ++ dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) { ++ if (rxsa->an == an) ++ return rxsa; ++ } ++ ++ return NULL; ++} ++ ++ + /** + * ieee802_1x_kay_create_sas - + */ +@@ -2603,6 +2643,9 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, + } + + dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { ++ while ((rxsa = lookup_rxsa_by_an(rxsc, latest_sak->an)) != NULL) ++ ieee802_1x_delete_receive_sa(kay, rxsa); ++ + rxsa = ieee802_1x_kay_init_receive_sa(rxsc, latest_sak->an, 1, + latest_sak); + if (!rxsa) +@@ -2611,6 +2654,10 @@ int ieee802_1x_kay_create_sas(struct ieee802_1x_kay *kay, + secy_create_receive_sa(kay, rxsa); + } + ++ while ((txsa = lookup_txsa_by_an(principal->txsc, latest_sak->an)) != ++ NULL) ++ ieee802_1x_delete_transmit_sa(kay, txsa); ++ + txsa = ieee802_1x_kay_init_transmit_sa(principal->txsc, latest_sak->an, + 1, latest_sak); + if (!txsa) +@@ -2644,20 +2691,16 @@ int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, + /* remove the transmit sa */ + dl_list_for_each_safe(txsa, pre_txsa, &principal->txsc->sa_list, + struct transmit_sa, list) { +- if (is_ki_equal(&txsa->pkey->key_identifier, ki)) { +- secy_disable_transmit_sa(kay, txsa); +- ieee802_1x_kay_deinit_transmit_sa(txsa); +- } ++ if (is_ki_equal(&txsa->pkey->key_identifier, ki)) ++ ieee802_1x_delete_transmit_sa(kay, txsa); + } + + /* remove the receive sa */ + dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) { + dl_list_for_each_safe(rxsa, pre_rxsa, &rxsc->sa_list, + struct receive_sa, list) { +- if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) { +- secy_disable_receive_sa(kay, rxsa); +- ieee802_1x_kay_deinit_receive_sa(rxsa); +- } ++ if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) ++ ieee802_1x_delete_receive_sa(kay, rxsa); + } + } + +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index e2ba180..5233cb2 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -153,12 +153,14 @@ struct ieee802_1x_kay_ctx { + enum confidentiality_offset co); + int (*delete_receive_sc)(void *ctx, struct receive_sc *sc); + int (*create_receive_sa)(void *ctx, struct receive_sa *sa); ++ int (*delete_receive_sa)(void *ctx, struct receive_sa *sa); + int (*enable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*disable_receive_sa)(void *ctx, struct receive_sa *sa); + int (*create_transmit_sc)(void *ctx, struct transmit_sc *sc, + enum confidentiality_offset co); + int (*delete_transmit_sc)(void *ctx, struct transmit_sc *sc); + int (*create_transmit_sa)(void *ctx, struct transmit_sa *sa); ++ int (*delete_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*enable_transmit_sa)(void *ctx, struct transmit_sa *sa); + int (*disable_transmit_sa)(void *ctx, struct transmit_sa *sa); + }; +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index b57c670..b1a9d22 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -256,6 +256,26 @@ int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + } + + ++int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) ++{ ++ struct ieee802_1x_kay_ctx *ops; ++ ++ if (!kay || !rxsa) { ++ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); ++ return -1; ++ } ++ ++ ops = kay->ctx; ++ if (!ops || !ops->delete_receive_sa) { ++ wpa_printf(MSG_ERROR, ++ "KaY: secy delete_receive_sa operation not supported"); ++ return -1; ++ } ++ ++ return ops->delete_receive_sa(ops->ctx, rxsa); ++} ++ ++ + int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa) + { + struct ieee802_1x_kay_ctx *ops; +@@ -363,6 +383,27 @@ int secy_create_transmit_sa(struct ieee802_1x_kay *kay, + } + + ++int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, ++ struct transmit_sa *txsa) ++{ ++ struct ieee802_1x_kay_ctx *ops; ++ ++ if (!kay || !txsa) { ++ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); ++ return -1; ++ } ++ ++ ops = kay->ctx; ++ if (!ops || !ops->delete_transmit_sa) { ++ wpa_printf(MSG_ERROR, ++ "KaY: secy delete_transmit_sa operation not supported"); ++ return -1; ++ } ++ ++ return ops->delete_transmit_sa(ops->ctx, txsa); ++} ++ ++ + int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa) + { +diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h +index 59f0baa..477120b 100644 +--- a/src/pae/ieee802_1x_secy_ops.h ++++ b/src/pae/ieee802_1x_secy_ops.h +@@ -38,6 +38,7 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay, + int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); + int secy_delete_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc); + int secy_create_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); ++int secy_delete_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); + int secy_enable_receive_sa(struct ieee802_1x_kay *kay, struct receive_sa *rxsa); + int secy_disable_receive_sa(struct ieee802_1x_kay *kay, + struct receive_sa *rxsa); +@@ -48,6 +49,8 @@ int secy_delete_transmit_sc(struct ieee802_1x_kay *kay, + struct transmit_sc *txsc); + int secy_create_transmit_sa(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa); ++int secy_delete_transmit_sa(struct ieee802_1x_kay *kay, ++ struct transmit_sa *txsa); + int secy_enable_transmit_sa(struct ieee802_1x_kay *kay, + struct transmit_sa *txsa); + int secy_disable_transmit_sa(struct ieee802_1x_kay *kay, +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index 244e386..c9bb20d 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -806,6 +806,14 @@ static inline int wpa_drv_create_receive_sa(struct wpa_supplicant *wpa_s, + return wpa_s->driver->create_receive_sa(wpa_s->drv_priv, sa); + } + ++static inline int wpa_drv_delete_receive_sa(struct wpa_supplicant *wpa_s, ++ struct receive_sa *sa) ++{ ++ if (!wpa_s->driver->delete_receive_sa) ++ return -1; ++ return wpa_s->driver->delete_receive_sa(wpa_s->drv_priv, sa); ++} ++ + static inline int wpa_drv_enable_receive_sa(struct wpa_supplicant *wpa_s, + struct receive_sa *sa) + { +@@ -848,6 +856,14 @@ static inline int wpa_drv_create_transmit_sa(struct wpa_supplicant *wpa_s, + return wpa_s->driver->create_transmit_sa(wpa_s->drv_priv, sa); + } + ++static inline int wpa_drv_delete_transmit_sa(struct wpa_supplicant *wpa_s, ++ struct transmit_sa *sa) ++{ ++ if (!wpa_s->driver->delete_transmit_sa) ++ return -1; ++ return wpa_s->driver->delete_transmit_sa(wpa_s->drv_priv, sa); ++} ++ + static inline int wpa_drv_enable_transmit_sa(struct wpa_supplicant *wpa_s, + struct transmit_sa *sa) + { +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 64364f7..e032330 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -120,6 +120,12 @@ static int wpas_create_receive_sa(void *wpa_s, struct receive_sa *sa) + } + + ++static int wpas_delete_receive_sa(void *wpa_s, struct receive_sa *sa) ++{ ++ return wpa_drv_delete_receive_sa(wpa_s, sa); ++} ++ ++ + static int wpas_enable_receive_sa(void *wpa_s, struct receive_sa *sa) + { + return wpa_drv_enable_receive_sa(wpa_s, sa); +@@ -152,6 +158,12 @@ static int wpas_create_transmit_sa(void *wpa_s, struct transmit_sa *sa) + } + + ++static int wpas_delete_transmit_sa(void *wpa_s, struct transmit_sa *sa) ++{ ++ return wpa_drv_delete_transmit_sa(wpa_s, sa); ++} ++ ++ + static int wpas_enable_transmit_sa(void *wpa_s, struct transmit_sa *sa) + { + return wpa_drv_enable_transmit_sa(wpa_s, sa); +@@ -196,11 +208,13 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + kay_ctx->create_receive_sc = wpas_create_receive_sc; + kay_ctx->delete_receive_sc = wpas_delete_receive_sc; + kay_ctx->create_receive_sa = wpas_create_receive_sa; ++ kay_ctx->delete_receive_sa = wpas_delete_receive_sa; + kay_ctx->enable_receive_sa = wpas_enable_receive_sa; + kay_ctx->disable_receive_sa = wpas_disable_receive_sa; + kay_ctx->create_transmit_sc = wpas_create_transmit_sc; + kay_ctx->delete_transmit_sc = wpas_delete_transmit_sc; + kay_ctx->create_transmit_sa = wpas_create_transmit_sa; ++ kay_ctx->delete_transmit_sa = wpas_delete_transmit_sa; + kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa; + kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; + +-- +2.7.4 + diff --git a/SOURCES/macsec-0011-mka-Implement-reference-counting-on-data_key.patch b/SOURCES/macsec-0011-mka-Implement-reference-counting-on-data_key.patch new file mode 100644 index 0000000..770b7c0 --- /dev/null +++ b/SOURCES/macsec-0011-mka-Implement-reference-counting-on-data_key.patch @@ -0,0 +1,149 @@ +From 99b82bf53792d48b5d0c3f9edcccc6e53c9510fe Mon Sep 17 00:00:00 2001 +Message-Id: <99b82bf53792d48b5d0c3f9edcccc6e53c9510fe.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Fri, 21 Oct 2016 14:45:29 +0200 +Subject: [PATCH] mka: Implement reference counting on data_key + +struct data_key already had a 'user' field for reference counting, but +it was basically unused. + +Add an ieee802_1x_kay_use_data_key() function to take a reference on a +key, and use ieee802_1x_kay_deinit_data_key() to release the reference. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.c | 28 ++++++++++++++++++++++++---- + src/pae/ieee802_1x_kay.h | 2 +- + 2 files changed, 25 insertions(+), 5 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index e312d04..63bbd13 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -411,6 +411,8 @@ ieee802_1x_kay_get_peer_sci(struct ieee802_1x_mka_participant *participant, + } + + ++static void ieee802_1x_kay_use_data_key(struct data_key *pkey); ++ + /** + * ieee802_1x_kay_init_receive_sa - + */ +@@ -429,6 +431,7 @@ ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, + return NULL; + } + ++ ieee802_1x_kay_use_data_key(key); + psa->pkey = key; + psa->lowest_pn = lowest_pn; + psa->next_pn = lowest_pn; +@@ -447,11 +450,14 @@ ieee802_1x_kay_init_receive_sa(struct receive_sc *psc, u8 an, u32 lowest_pn, + } + + ++static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey); ++ + /** + * ieee802_1x_kay_deinit_receive_sa - + */ + static void ieee802_1x_kay_deinit_receive_sa(struct receive_sa *psa) + { ++ ieee802_1x_kay_deinit_data_key(psa->pkey); + psa->pkey = NULL; + wpa_printf(MSG_DEBUG, + "KaY: Delete receive SA(an: %hhu) of SC", +@@ -1612,6 +1618,7 @@ ieee802_1x_mka_decode_dist_sak_body( + sa_key->an = body->dan; + ieee802_1x_kay_init_data_key(sa_key); + ++ ieee802_1x_kay_use_data_key(sa_key); + dl_list_add(&participant->sak_list, &sa_key->list); + + ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id); +@@ -1873,7 +1880,17 @@ static struct mka_param_body_handler mka_body_handler[] = { + + + /** +- * ieee802_1x_kay_deinit_data_key - ++ * ieee802_1x_kay_use_data_key - Take reference on a key ++ */ ++static void ieee802_1x_kay_use_data_key(struct data_key *pkey) ++{ ++ pkey->user++; ++} ++ ++ ++/** ++ * ieee802_1x_kay_deinit_data_key - Release reference on a key and ++ * free if there are no remaining users + */ + static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey) + { +@@ -1884,7 +1901,6 @@ static void ieee802_1x_kay_deinit_data_key(struct data_key *pkey) + if (pkey->user > 1) + return; + +- dl_list_del(&pkey->list); + os_free(pkey->key); + os_free(pkey); + } +@@ -1994,7 +2010,9 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant) + + participant->new_key = sa_key; + ++ ieee802_1x_kay_use_data_key(sa_key); + dl_list_add(&participant->sak_list, &sa_key->list); ++ + ieee802_1x_cp_set_ciphersuite(kay->cp, cs->id); + ieee802_1x_cp_sm_step(kay->cp); + ieee802_1x_cp_set_offset(kay->cp, kay->macsec_confidentiality); +@@ -2436,6 +2454,7 @@ ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, + psa->confidentiality = FALSE; + + psa->an = an; ++ ieee802_1x_kay_use_data_key(key); + psa->pkey = key; + psa->next_pn = next_PN; + psa->sc = psc; +@@ -2457,6 +2476,7 @@ ieee802_1x_kay_init_transmit_sa(struct transmit_sc *psc, u8 an, u32 next_PN, + */ + static void ieee802_1x_kay_deinit_transmit_sa(struct transmit_sa *psa) + { ++ ieee802_1x_kay_deinit_data_key(psa->pkey); + psa->pkey = NULL; + wpa_printf(MSG_DEBUG, + "KaY: Delete transmit SA(an: %hhu) of SC", +@@ -2708,6 +2728,7 @@ int ieee802_1x_kay_delete_sas(struct ieee802_1x_kay *kay, + dl_list_for_each_safe(sa_key, pre_key, &principal->sak_list, + struct data_key, list) { + if (is_ki_equal(&sa_key->key_identifier, ki)) { ++ dl_list_del(&sa_key->list); + ieee802_1x_kay_deinit_data_key(sa_key); + break; + } +@@ -3375,8 +3396,7 @@ ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn) + sak = dl_list_entry(participant->sak_list.next, + struct data_key, list); + dl_list_del(&sak->list); +- os_free(sak->key); +- os_free(sak); ++ ieee802_1x_kay_deinit_data_key(sak); + } + while (!dl_list_empty(&participant->rxsc_list)) { + rxsc = dl_list_entry(participant->rxsc_list.next, +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 5233cb2..576a8a0 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -70,7 +70,7 @@ struct data_key { + Boolean rx_latest; + Boolean tx_latest; + +- int user; /* FIXME: to indicate if it can be delete safely */ ++ int user; + + struct dl_list list; + }; +-- +2.7.4 + diff --git a/SOURCES/macsec-0012-mka-Fix-getting-capabilities-from-the-driver.patch b/SOURCES/macsec-0012-mka-Fix-getting-capabilities-from-the-driver.patch new file mode 100644 index 0000000..3ea1d7f --- /dev/null +++ b/SOURCES/macsec-0012-mka-Fix-getting-capabilities-from-the-driver.patch @@ -0,0 +1,66 @@ +From 088d53dd15b14a1868b70fd0b8d695ac6b68f642 Mon Sep 17 00:00:00 2001 +Message-Id: <088d53dd15b14a1868b70fd0b8d695ac6b68f642.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Tue, 15 Nov 2016 18:06:23 +0100 +Subject: [PATCH] mka: Fix getting capabilities from the driver + +In commit a25e4efc9e428d968e83398bd8c9c94698ba5851 ('mka: Add driver op +to get macsec capabilities') I added some code to check the driver's +capabilities. This commit has two problems: + - wrong enum type set in kay->macsec_confidentiality + - ignores that drivers could report MACSEC_CAP_NOT_IMPLEMENTED, in + which case the MKA would claim that MACsec is supported. + +Fix this by interpreting MACSEC_CAP_NOT_IMPLEMENTED in the same way as a +DO_NOT_SECURE policy, and set the correct value in +kay->macsec_confidentiality. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.c | 16 +++++++++------- + 1 file changed, 9 insertions(+), 7 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 63bbd13..2841b10 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3111,7 +3111,14 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + + dl_list_init(&kay->participant_list); + +- if (policy == DO_NOT_SECURE) { ++ if (policy != DO_NOT_SECURE && ++ secy_get_capability(kay, &kay->macsec_capable) < 0) { ++ os_free(kay); ++ return NULL; ++ } ++ ++ if (policy == DO_NOT_SECURE || ++ kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { + kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED; + kay->macsec_desired = FALSE; + kay->macsec_protect = FALSE; +@@ -3120,11 +3127,6 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + kay->macsec_replay_window = 0; + kay->macsec_confidentiality = CONFIDENTIALITY_NONE; + } else { +- if (secy_get_capability(kay, &kay->macsec_capable) < 0) { +- os_free(kay); +- return NULL; +- } +- + kay->macsec_desired = TRUE; + kay->macsec_protect = TRUE; + kay->macsec_validate = Strict; +@@ -3133,7 +3135,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF) + kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0; + else +- kay->macsec_confidentiality = MACSEC_CAP_INTEGRITY; ++ kay->macsec_confidentiality = CONFIDENTIALITY_NONE; + } + + wpa_printf(MSG_DEBUG, "KaY: state machine created"); +-- +2.7.4 + diff --git a/SOURCES/macsec-0013-wpa_supplicant-Allow-pre-shared-CAK-CKN-pair-for-MKA.patch b/SOURCES/macsec-0013-wpa_supplicant-Allow-pre-shared-CAK-CKN-pair-for-MKA.patch new file mode 100644 index 0000000..54ecbcd --- /dev/null +++ b/SOURCES/macsec-0013-wpa_supplicant-Allow-pre-shared-CAK-CKN-pair-for-MKA.patch @@ -0,0 +1,317 @@ +From ad51731abf06efb284d020578eb34e7b1daeb23e Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Wed, 2 Nov 2016 16:38:35 +0100 +Subject: [PATCH] wpa_supplicant: Allow pre-shared (CAK,CKN) pair for MKA + +This enables configuring key_mgmt=NONE + mka_ckn + mka_cak. +This allows wpa_supplicant to work in a peer-to-peer mode, where peers +are authenticated by the pre-shared (CAK,CKN) pair. In this mode, peers +can act as key server to distribute keys for the MACsec instances. + +This is what some MACsec switches support, and even without HW +support, it's a convenient way to setup a network. + +Signed-off-by: Sabrina Dubroca +--- + wpa_supplicant/config.c | 65 ++++++++++++++++++++++++++++++++++++++ + wpa_supplicant/config_file.c | 36 +++++++++++++++++++++ + wpa_supplicant/config_ssid.h | 20 ++++++++++++ + wpa_supplicant/wpa_supplicant.c | 7 +++- + wpa_supplicant/wpa_supplicant.conf | 8 +++++ + wpa_supplicant/wpas_kay.c | 48 ++++++++++++++++++++++++++++ + wpa_supplicant/wpas_kay.h | 10 ++++++ + 7 files changed, 193 insertions(+), 1 deletion(-) + +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index a0b64b2..9011389 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -1828,6 +1828,69 @@ static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data, + #endif /* CONFIG_MESH */ + + ++#ifdef CONFIG_MACSEC ++ ++static int wpa_config_parse_mka_cak(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ if (hexstr2bin(value, ssid->mka_cak, MACSEC_CAK_LEN) || ++ value[MACSEC_CAK_LEN * 2] != '\0') { ++ wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CAK '%s'.", ++ line, value); ++ return -1; ++ } ++ ++ ssid->mka_psk_set |= MKA_PSK_SET_CAK; ++ ++ wpa_hexdump_key(MSG_MSGDUMP, "MKA-CAK", ssid->mka_cak, MACSEC_CAK_LEN); ++ return 0; ++} ++ ++ ++static int wpa_config_parse_mka_ckn(const struct parse_data *data, ++ struct wpa_ssid *ssid, int line, ++ const char *value) ++{ ++ if (hexstr2bin(value, ssid->mka_ckn, MACSEC_CKN_LEN) || ++ value[MACSEC_CKN_LEN * 2] != '\0') { ++ wpa_printf(MSG_ERROR, "Line %d: Invalid MKA-CKN '%s'.", ++ line, value); ++ return -1; ++ } ++ ++ ssid->mka_psk_set |= MKA_PSK_SET_CKN; ++ ++ wpa_hexdump_key(MSG_MSGDUMP, "MKA-CKN", ssid->mka_ckn, MACSEC_CKN_LEN); ++ return 0; ++} ++ ++ ++#ifndef NO_CONFIG_WRITE ++ ++static char * wpa_config_write_mka_cak(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK)) ++ return NULL; ++ ++ return wpa_config_write_string_hex(ssid->mka_cak, MACSEC_CAK_LEN); ++} ++ ++ ++static char * wpa_config_write_mka_ckn(const struct parse_data *data, ++ struct wpa_ssid *ssid) ++{ ++ if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN)) ++ return NULL; ++ return wpa_config_write_string_hex(ssid->mka_ckn, MACSEC_CKN_LEN); ++} ++ ++#endif /* NO_CONFIG_WRITE */ ++ ++#endif /* CONFIG_MACSEC */ ++ ++ + /* Helper macros for network block parser */ + + #ifdef OFFSET +@@ -2062,6 +2125,8 @@ static const struct parse_data ssid_fields[] = { + { INT(beacon_int) }, + #ifdef CONFIG_MACSEC + { INT_RANGE(macsec_policy, 0, 1) }, ++ { FUNC_KEY(mka_cak) }, ++ { FUNC_KEY(mka_ckn) }, + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + { INT(update_identifier) }, +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index 7ae1654..172508e 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -662,6 +662,40 @@ static void write_psk_list(FILE *f, struct wpa_ssid *ssid) + #endif /* CONFIG_P2P */ + + ++#ifdef CONFIG_MACSEC ++ ++static void write_mka_cak(FILE *f, struct wpa_ssid *ssid) ++{ ++ char *value; ++ ++ if (!(ssid->mka_psk_set & MKA_PSK_SET_CAK)) ++ return; ++ ++ value = wpa_config_get(ssid, "mka_cak"); ++ if (!value) ++ return; ++ fprintf(f, "\tmka_cak=%s\n", value); ++ os_free(value); ++} ++ ++ ++static void write_mka_ckn(FILE *f, struct wpa_ssid *ssid) ++{ ++ char *value; ++ ++ if (!(ssid->mka_psk_set & MKA_PSK_SET_CKN)) ++ return; ++ ++ value = wpa_config_get(ssid, "mka_ckn"); ++ if (!value) ++ return; ++ fprintf(f, "\tmka_ckn=%s\n", value); ++ os_free(value); ++} ++ ++#endif /* CONFIG_MACSEC */ ++ ++ + static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + { + int i; +@@ -772,6 +806,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + INT(beacon_int); + #ifdef CONFIG_MACSEC + INT(macsec_policy); ++ write_mka_cak(f, ssid); ++ write_mka_ckn(f, ssid); + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + INT(update_identifier); +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index 010b594..a530cda 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -728,6 +728,26 @@ struct wpa_ssid { + * determine whether to use a secure session or not. + */ + int macsec_policy; ++ ++ /** ++ * mka_ckn - MKA pre-shared CKN ++ */ ++#define MACSEC_CKN_LEN 32 ++ u8 mka_ckn[MACSEC_CKN_LEN]; ++ ++ /** ++ * mka_cak - MKA pre-shared CAK ++ */ ++#define MACSEC_CAK_LEN 16 ++ u8 mka_cak[MACSEC_CAK_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 */ + + #ifdef CONFIG_HS20 +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 5d6326a..0bfc39d 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -329,7 +329,12 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s) + + eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); + +- ieee802_1x_alloc_kay_sm(wpa_s, ssid); ++#ifdef CONFIG_MACSEC ++ if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE && ssid->mka_psk_set) ++ ieee802_1x_create_preshared_mka(wpa_s, ssid); ++ else ++ ieee802_1x_alloc_kay_sm(wpa_s, ssid); ++#endif /* CONFIG_MACSEC */ + #endif /* IEEE8021X_EAPOL */ + } + +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index 047ca90..8fa740b 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -892,6 +892,14 @@ fast_reauth=1 + # 1: MACsec enabled - Should secure, accept key server's advice to + # determine whether to use a secure session or not. + # ++# mka_cak and mka_ckn: IEEE 802.1X/MACsec pre-shared authentication mode ++# This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. ++# In this mode, instances of wpa_supplicant can act as peers, one of ++# which will become the key server and start distributing SAKs. ++# mka_cak (CAK = Secure Connectivity Association Key) takes a 16-bytes (128 bit) ++# hex-string (32 hex-digits) ++# mka_ckn (CKN = CAK Name) takes a 32-bytes (256 bit) hex-string (64 hex-digits) ++# + # mixed_cell: This option can be used to configure whether so called mixed + # cells, i.e., networks that use both plaintext and encryption in the same + # SSID, are allowed when selecting a BSS from scan results. +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index e032330..80b98d9 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -371,3 +371,51 @@ fail: + + return res; + } ++ ++ ++void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, ++ struct wpa_ssid *ssid) ++{ ++ struct mka_key *cak; ++ struct mka_key_name *ckn; ++ void *res; ++ ++ if ((ssid->mka_psk_set & MKA_PSK_SET) != MKA_PSK_SET) ++ return NULL; ++ ++ if (ieee802_1x_alloc_kay_sm(wpa_s, ssid) < 0) ++ return NULL; ++ ++ if (!wpa_s->kay || wpa_s->kay->policy == DO_NOT_SECURE) ++ return NULL; ++ ++ ckn = os_zalloc(sizeof(*ckn)); ++ if (!ckn) ++ goto dealloc; ++ ++ cak = os_zalloc(sizeof(*cak)); ++ if (!cak) ++ goto free_ckn; ++ ++ cak->len = MACSEC_CAK_LEN; ++ os_memcpy(cak->key, ssid->mka_cak, cak->len); ++ ++ ckn->len = MACSEC_CKN_LEN; ++ os_memcpy(ckn->name, ssid->mka_ckn, ckn->len); ++ ++ res = ieee802_1x_kay_create_mka(wpa_s->kay, ckn, cak, 0, PSK, FALSE); ++ if (res) ++ return res; ++ ++ /* Failed to create MKA */ ++ os_free(cak); ++ ++ /* fallthrough */ ++ ++free_ckn: ++ os_free(ckn); ++dealloc: ++ ieee802_1x_dealloc_kay_sm(wpa_s); ++ ++ return NULL; ++} +diff --git a/wpa_supplicant/wpas_kay.h b/wpa_supplicant/wpas_kay.h +index b7236d0..81f8e0c 100644 +--- a/wpa_supplicant/wpas_kay.h ++++ b/wpa_supplicant/wpas_kay.h +@@ -17,6 +17,9 @@ void * ieee802_1x_notify_create_actor(struct wpa_supplicant *wpa_s, + const u8 *peer_addr); + void ieee802_1x_dealloc_kay_sm(struct wpa_supplicant *wpa_s); + ++void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, ++ struct wpa_ssid *ssid); ++ + #else /* CONFIG_MACSEC */ + + static inline int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, +@@ -36,6 +39,13 @@ static inline void ieee802_1x_dealloc_kay_sm(struct wpa_supplicant *wpa_s) + { + } + ++static inline void * ++ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, ++ struct wpa_ssid *ssid) ++{ ++ return 0; ++} ++ + #endif /* CONFIG_MACSEC */ + + #endif /* WPAS_KAY_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0014-mka-Disable-peer-detection-timeout-for-PSK-mode.patch b/SOURCES/macsec-0014-mka-Disable-peer-detection-timeout-for-PSK-mode.patch new file mode 100644 index 0000000..0dfdf64 --- /dev/null +++ b/SOURCES/macsec-0014-mka-Disable-peer-detection-timeout-for-PSK-mode.patch @@ -0,0 +1,42 @@ +From 008e224dbb518f44aac46b0c8e55448bd907e43d Mon Sep 17 00:00:00 2001 +Message-Id: <008e224dbb518f44aac46b0c8e55448bd907e43d.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Wed, 2 Nov 2016 16:38:36 +0100 +Subject: [PATCH] mka: Disable peer detection timeout for PSK mode + +The first peer may take a long time to come up. In PSK mode we are +basically in a p2p system, and we cannot know when a peer will join the +key exchange. Wait indefinitely, and let the administrator decide if +they want to abort. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 2841b10..19b2c2f 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3339,8 +3339,16 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn, + usecs = os_random() % (MKA_HELLO_TIME * 1000); + eloop_register_timeout(0, usecs, ieee802_1x_participant_timer, + participant, NULL); +- participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + +- usecs / 1000000; ++ ++ /* Disable MKA lifetime for PSK mode. ++ * The peer(s) can take a long time to come up, because we ++ * create a "standby" MKA, and we need it to remain live until ++ * some peer appears. ++ */ ++ if (mode != PSK) { ++ participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + ++ usecs / 1000000; ++ } + + return participant; + +-- +2.7.4 + diff --git a/SOURCES/macsec-0015-wpa_supplicant-Add-macsec_integ_only-setting-for-MKA.patch b/SOURCES/macsec-0015-wpa_supplicant-Add-macsec_integ_only-setting-for-MKA.patch new file mode 100644 index 0000000..b9a620a --- /dev/null +++ b/SOURCES/macsec-0015-wpa_supplicant-Add-macsec_integ_only-setting-for-MKA.patch @@ -0,0 +1,165 @@ +From 7b4d546e3dae57a39e50a91e47b8fcf3447b4978 Mon Sep 17 00:00:00 2001 +Message-Id: <7b4d546e3dae57a39e50a91e47b8fcf3447b4978.1488376601.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Wed, 2 Nov 2016 16:38:37 +0100 +Subject: [PATCH] wpa_supplicant: Add macsec_integ_only setting for MKA + +So that the user can turn encryption on (MACsec provides +confidentiality+integrity) or off (MACsec provides integrity only). This +commit adds the configuration parameter while the actual behavior change +to disable encryption in the driver is handled in the following commit. + +Signed-off-by: Sabrina Dubroca +--- + src/common/ieee802_1x_defs.h | 6 ++++++ + src/pae/ieee802_1x_kay.c | 1 + + src/pae/ieee802_1x_kay.h | 1 + + wpa_supplicant/config.c | 1 + + wpa_supplicant/config_file.c | 1 + + wpa_supplicant/config_ssid.h | 12 ++++++++++++ + wpa_supplicant/wpa_cli.c | 1 + + wpa_supplicant/wpa_supplicant.conf | 7 +++++++ + wpa_supplicant/wpas_kay.c | 9 ++++++++- + 9 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/src/common/ieee802_1x_defs.h b/src/common/ieee802_1x_defs.h +index a0c1d1b..280c439 100644 +--- a/src/common/ieee802_1x_defs.h ++++ b/src/common/ieee802_1x_defs.h +@@ -25,6 +25,12 @@ enum macsec_policy { + * Disabled MACsec - do not secure sessions. + */ + DO_NOT_SECURE, ++ ++ /** ++ * Should secure sessions, and try to use encryption. ++ * Like @SHOULD_SECURE, this follows the key server's decision. ++ */ ++ SHOULD_ENCRYPT, + }; + + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 19b2c2f..7664e2d 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3129,6 +3129,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + } else { + kay->macsec_desired = TRUE; + kay->macsec_protect = TRUE; ++ kay->macsec_encrypt = policy == SHOULD_ENCRYPT; + kay->macsec_validate = Strict; + kay->macsec_replay_protect = FALSE; + kay->macsec_replay_window = 0; +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 576a8a0..618e45b 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -181,6 +181,7 @@ struct ieee802_1x_kay { + enum macsec_cap macsec_capable; + Boolean macsec_desired; + Boolean macsec_protect; ++ Boolean macsec_encrypt; + Boolean macsec_replay_protect; + u32 macsec_replay_window; + enum validate_frames macsec_validate; +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index 9011389..afb631e 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -2125,6 +2125,7 @@ static const struct parse_data ssid_fields[] = { + { INT(beacon_int) }, + #ifdef CONFIG_MACSEC + { INT_RANGE(macsec_policy, 0, 1) }, ++ { INT_RANGE(macsec_integ_only, 0, 1) }, + { FUNC_KEY(mka_cak) }, + { FUNC_KEY(mka_ckn) }, + #endif /* CONFIG_MACSEC */ +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index 172508e..f605fa9 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -808,6 +808,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + INT(macsec_policy); + write_mka_cak(f, ssid); + write_mka_ckn(f, ssid); ++ INT(macsec_integ_only); + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + INT(update_identifier); +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index a530cda..b8c3192 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -730,6 +730,18 @@ struct wpa_ssid { + 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; ++ ++ /** + * mka_ckn - MKA pre-shared CKN + */ + #define MACSEC_CKN_LEN 32 +diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c +index 4877989..aed95e6 100644 +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -1390,6 +1390,7 @@ static const char *network_fields[] = { + "ap_max_inactivity", "dtim_period", "beacon_int", + #ifdef CONFIG_MACSEC + "macsec_policy", ++ "macsec_integ_only", + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + "update_identifier", +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index 8fa740b..b23c5e6 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -892,6 +892,13 @@ fast_reauth=1 + # 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 ++# + # mka_cak and mka_ckn: IEEE 802.1X/MACsec pre-shared authentication mode + # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. + # In this mode, instances of wpa_supplicant can act as peers, one of +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 80b98d9..6343154 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -187,7 +187,14 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + if (!ssid || ssid->macsec_policy == 0) + return 0; + +- policy = ssid->macsec_policy == 1 ? SHOULD_SECURE : DO_NOT_SECURE; ++ if (ssid->macsec_policy == 1) { ++ if (ssid->macsec_integ_only == 1) ++ policy = SHOULD_SECURE; ++ else ++ policy = SHOULD_ENCRYPT; ++ } else { ++ policy = DO_NOT_SECURE; ++ } + + kay_ctx = os_zalloc(sizeof(*kay_ctx)); + if (!kay_ctx) +-- +2.7.4 + diff --git a/SOURCES/macsec-0016-mka-Add-enable_encrypt-op-and-call-it-from-CP-state-.patch b/SOURCES/macsec-0016-mka-Add-enable_encrypt-op-and-call-it-from-CP-state-.patch new file mode 100644 index 0000000..7dc92ca --- /dev/null +++ b/SOURCES/macsec-0016-mka-Add-enable_encrypt-op-and-call-it-from-CP-state-.patch @@ -0,0 +1,177 @@ +From 1d3d0666a6ed345da39886426c4416a4debfd094 Mon Sep 17 00:00:00 2001 +Message-Id: <1d3d0666a6ed345da39886426c4416a4debfd094.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Wed, 2 Nov 2016 16:38:38 +0100 +Subject: [PATCH] mka: Add enable_encrypt op and call it from CP state machine + +This allows MKA to turn encryption on/off down to the driver. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 9 +++++++++ + src/pae/ieee802_1x_cp.c | 4 ++++ + src/pae/ieee802_1x_kay.h | 1 + + src/pae/ieee802_1x_secy_ops.c | 20 ++++++++++++++++++++ + src/pae/ieee802_1x_secy_ops.h | 1 + + wpa_supplicant/driver_i.h | 8 ++++++++ + wpa_supplicant/wpas_kay.c | 7 +++++++ + 7 files changed, 50 insertions(+) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index 9a6db90..0cb68ba 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -3339,6 +3339,15 @@ struct wpa_driver_ops { + int (*enable_protect_frames)(void *priv, Boolean enabled); + + /** ++ * enable_encrypt - Set encryption status ++ * @priv: Private driver interface data ++ * @enabled: TRUE = encrypt outgoing traffic ++ * FALSE = integrity-only protection on outgoing traffic ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++ int (*enable_encrypt)(void *priv, Boolean enabled); ++ ++ /** + * set_replay_protect - Set replay protect status and window size + * @priv: Private driver interface data + * @enabled: TRUE = replay protect enabled +diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c +index e294e64..360fcd3 100644 +--- a/src/pae/ieee802_1x_cp.c ++++ b/src/pae/ieee802_1x_cp.c +@@ -159,6 +159,7 @@ SM_STATE(CP, ALLOWED) + + secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); + secy_cp_control_protect_frames(sm->kay, sm->protect_frames); ++ secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); + secy_cp_control_validate_frames(sm->kay, sm->validate_frames); + secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + } +@@ -177,6 +178,7 @@ SM_STATE(CP, AUTHENTICATED) + + secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); + secy_cp_control_protect_frames(sm->kay, sm->protect_frames); ++ secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); + secy_cp_control_validate_frames(sm->kay, sm->validate_frames); + secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + } +@@ -203,6 +205,7 @@ SM_STATE(CP, SECURED) + secy_cp_control_confidentiality_offset(sm->kay, + sm->confidentiality_offset); + secy_cp_control_protect_frames(sm->kay, sm->protect_frames); ++ secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); + secy_cp_control_validate_frames(sm->kay, sm->validate_frames); + secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + } +@@ -466,6 +469,7 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay) + wpa_printf(MSG_DEBUG, "CP: state machine created"); + + secy_cp_control_protect_frames(sm->kay, sm->protect_frames); ++ secy_cp_control_encrypt(sm->kay, sm->kay->macsec_encrypt); + secy_cp_control_validate_frames(sm->kay, sm->validate_frames); + secy_cp_control_replay(sm->kay, sm->replay_protect, sm->replay_window); + secy_cp_control_enable_port(sm->kay, sm->controlled_port_enabled); +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 618e45b..fb49f62 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -142,6 +142,7 @@ struct ieee802_1x_kay_ctx { + int (*macsec_deinit)(void *ctx); + int (*macsec_get_capability)(void *priv, enum macsec_cap *cap); + int (*enable_protect_frames)(void *ctx, Boolean enabled); ++ int (*enable_encrypt)(void *ctx, Boolean enabled); + int (*set_replay_protect)(void *ctx, Boolean enabled, u32 window); + int (*set_current_cipher_suite)(void *ctx, u64 cs); + int (*enable_controlled_port)(void *ctx, Boolean enabled); +diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c +index b1a9d22..ab5339b 100644 +--- a/src/pae/ieee802_1x_secy_ops.c ++++ b/src/pae/ieee802_1x_secy_ops.c +@@ -45,6 +45,26 @@ int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean enabled) + } + + ++int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, Boolean enabled) ++{ ++ struct ieee802_1x_kay_ctx *ops; ++ ++ if (!kay) { ++ wpa_printf(MSG_ERROR, "KaY: %s params invalid", __func__); ++ return -1; ++ } ++ ++ ops = kay->ctx; ++ if (!ops || !ops->enable_encrypt) { ++ wpa_printf(MSG_ERROR, ++ "KaY: secy enable_encrypt operation not supported"); ++ return -1; ++ } ++ ++ return ops->enable_encrypt(ops->ctx, enabled); ++} ++ ++ + int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean enabled, u32 win) + { + struct ieee802_1x_kay_ctx *ops; +diff --git a/src/pae/ieee802_1x_secy_ops.h b/src/pae/ieee802_1x_secy_ops.h +index 477120b..9fb29c3 100644 +--- a/src/pae/ieee802_1x_secy_ops.h ++++ b/src/pae/ieee802_1x_secy_ops.h +@@ -21,6 +21,7 @@ int secy_deinit_macsec(struct ieee802_1x_kay *kay); + int secy_cp_control_validate_frames(struct ieee802_1x_kay *kay, + enum validate_frames vf); + int secy_cp_control_protect_frames(struct ieee802_1x_kay *kay, Boolean flag); ++int secy_cp_control_encrypt(struct ieee802_1x_kay *kay, Boolean enabled); + int secy_cp_control_replay(struct ieee802_1x_kay *kay, Boolean flag, u32 win); + int secy_cp_control_current_cipher_suite(struct ieee802_1x_kay *kay, u64 cs); + int secy_cp_control_confidentiality_offset(struct ieee802_1x_kay *kay, +diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h +index c9bb20d..cf08556 100644 +--- a/wpa_supplicant/driver_i.h ++++ b/wpa_supplicant/driver_i.h +@@ -731,6 +731,14 @@ static inline int wpa_drv_enable_protect_frames(struct wpa_supplicant *wpa_s, + return wpa_s->driver->enable_protect_frames(wpa_s->drv_priv, enabled); + } + ++static inline int wpa_drv_enable_encrypt(struct wpa_supplicant *wpa_s, ++ Boolean enabled) ++{ ++ if (!wpa_s->driver->enable_encrypt) ++ return -1; ++ return wpa_s->driver->enable_encrypt(wpa_s->drv_priv, enabled); ++} ++ + static inline int wpa_drv_set_replay_protect(struct wpa_supplicant *wpa_s, + Boolean enabled, u32 window) + { +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 6343154..2ff4895 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -50,6 +50,12 @@ static int wpas_enable_protect_frames(void *wpa_s, Boolean enabled) + } + + ++static int wpas_enable_encrypt(void *wpa_s, Boolean enabled) ++{ ++ return wpa_drv_enable_encrypt(wpa_s, enabled); ++} ++ ++ + static int wpas_set_replay_protect(void *wpa_s, Boolean enabled, u32 window) + { + return wpa_drv_set_replay_protect(wpa_s, enabled, window); +@@ -206,6 +212,7 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + kay_ctx->macsec_deinit = wpas_macsec_deinit; + kay_ctx->macsec_get_capability = wpas_macsec_get_capability; + kay_ctx->enable_protect_frames = wpas_enable_protect_frames; ++ kay_ctx->enable_encrypt = wpas_enable_encrypt; + kay_ctx->set_replay_protect = wpas_set_replay_protect; + kay_ctx->set_current_cipher_suite = wpas_set_current_cipher_suite; + kay_ctx->enable_controlled_port = wpas_enable_controlled_port; +-- +2.7.4 + diff --git a/SOURCES/macsec-0017-wpa_supplicant-Allow-configuring-the-MACsec-port-for.patch b/SOURCES/macsec-0017-wpa_supplicant-Allow-configuring-the-MACsec-port-for.patch new file mode 100644 index 0000000..d3a7dc0 --- /dev/null +++ b/SOURCES/macsec-0017-wpa_supplicant-Allow-configuring-the-MACsec-port-for.patch @@ -0,0 +1,145 @@ +From e0d9fd344d20bb35efcd5c37ece0a5d67632439d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Wed, 2 Nov 2016 16:38:39 +0100 +Subject: [PATCH] wpa_supplicant: Allow configuring the MACsec port for MKA + +Previously, wpa_supplicant only supported hardcoded port == 1 in the +SCI, but users may want to choose a different port. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.c | 4 ++-- + src/pae/ieee802_1x_kay.h | 2 +- + wpa_supplicant/config.c | 1 + + wpa_supplicant/config_file.c | 1 + + wpa_supplicant/config_ssid.h | 9 +++++++++ + wpa_supplicant/wpa_cli.c | 1 + + wpa_supplicant/wpa_supplicant.conf | 4 ++++ + wpa_supplicant/wpas_kay.c | 4 ++-- + 8 files changed, 21 insertions(+), 5 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 7664e2d..3a495ca 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3071,7 +3071,7 @@ static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, + */ + struct ieee802_1x_kay * + ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, +- const char *ifname, const u8 *addr) ++ u16 port, const char *ifname, const u8 *addr) + { + struct ieee802_1x_kay *kay; + +@@ -3093,7 +3093,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + + os_strlcpy(kay->if_name, ifname, IFNAMSIZ); + os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN); +- kay->actor_sci.port = host_to_be16(0x0001); ++ kay->actor_sci.port = host_to_be16(port ? port : 0x0001); + kay->actor_priority = DEFAULT_PRIO_NOT_KEY_SERVER; + + /* While actor acts as a key server, shall distribute sakey */ +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index fb49f62..ea5a0dd 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -233,7 +233,7 @@ struct ieee802_1x_kay { + + struct ieee802_1x_kay * + ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, +- const char *ifname, const u8 *addr); ++ u16 port, const char *ifname, const u8 *addr); + void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); + + struct ieee802_1x_mka_participant * +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index afb631e..2120a6e 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -2126,6 +2126,7 @@ static const struct parse_data ssid_fields[] = { + #ifdef CONFIG_MACSEC + { INT_RANGE(macsec_policy, 0, 1) }, + { INT_RANGE(macsec_integ_only, 0, 1) }, ++ { INT_RANGE(macsec_port, 1, 65534) }, + { FUNC_KEY(mka_cak) }, + { FUNC_KEY(mka_ckn) }, + #endif /* CONFIG_MACSEC */ +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index f605fa9..2e3d57e 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -809,6 +809,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + write_mka_cak(f, ssid); + write_mka_ckn(f, ssid); + INT(macsec_integ_only); ++ INT(macsec_port); + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + INT(update_identifier); +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index b8c3192..fe0f7fa 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -742,6 +742,15 @@ struct wpa_ssid { + int macsec_integ_only; + + /** ++ * macsec_port - MACsec port (in SCI) ++ * ++ * Port component of the SCI. ++ * ++ * Range: 1-65534 (default: 1) ++ */ ++ int macsec_port; ++ ++ /** + * mka_ckn - MKA pre-shared CKN + */ + #define MACSEC_CKN_LEN 32 +diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c +index aed95e6..f11028a 100644 +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -1391,6 +1391,7 @@ static const char *network_fields[] = { + #ifdef CONFIG_MACSEC + "macsec_policy", + "macsec_integ_only", ++ "macsec_port", + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + "update_identifier", +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index b23c5e6..82aa24e 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -899,6 +899,10 @@ fast_reauth=1 + # 0: Encrypt traffic (default) + # 1: Integrity only + # ++# macsec_port: IEEE 802.1X/MACsec port ++# Port component of the SCI ++# Range: 1-65534 (default: 1) ++# + # mka_cak and mka_ckn: IEEE 802.1X/MACsec pre-shared authentication mode + # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. + # In this mode, instances of wpa_supplicant can act as peers, one of +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 2ff4895..d3fefda 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -232,8 +232,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + kay_ctx->enable_transmit_sa = wpas_enable_transmit_sa; + kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; + +- res = ieee802_1x_kay_init(kay_ctx, policy, wpa_s->ifname, +- wpa_s->own_addr); ++ res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_port, ++ wpa_s->ifname, wpa_s->own_addr); + if (res == NULL) { + os_free(kay_ctx); + return -1; +-- +2.7.4 + diff --git a/SOURCES/macsec-0018-drivers-Move-common-definitions-for-wired-drivers-ou.patch b/SOURCES/macsec-0018-drivers-Move-common-definitions-for-wired-drivers-ou.patch new file mode 100644 index 0000000..da0d23c --- /dev/null +++ b/SOURCES/macsec-0018-drivers-Move-common-definitions-for-wired-drivers-ou.patch @@ -0,0 +1,459 @@ +From 0abc8d10cc357d71fff74470c613442f9070ae93 Mon Sep 17 00:00:00 2001 +Message-Id: <0abc8d10cc357d71fff74470c613442f9070ae93.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:44 +0100 +Subject: [PATCH] drivers: Move common definitions for wired drivers out + +Refactor the common parts of wired drivers code into a shared file, so +that they can be reused by other drivers. The macsec_qca driver already +contains a lot of code duplication from the wired driver, and the +macsec_linux driver would do the same. A structure to hold data common +to all wired drivers is added and used in all these drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 65 ++++++++++++------------- + src/drivers/driver_wired.c | 99 +++++++++++++++++++-------------------- + src/drivers/driver_wired_common.h | 25 ++++++++++ + 3 files changed, 103 insertions(+), 86 deletions(-) + create mode 100644 src/drivers/driver_wired_common.h + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 22d414c..6391e08 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -31,6 +31,7 @@ + #include "common/ieee802_1x_defs.h" + #include "pae/ieee802_1x_kay.h" + #include "driver.h" ++#include "driver_wired_common.h" + + #include "nss_macsec_secy.h" + #include "nss_macsec_secy_rx.h" +@@ -53,21 +54,14 @@ + #pragma pack(pop) + #endif /* _MSC_VER */ + +-static const u8 pae_group_addr[ETH_ALEN] = +-{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; +- + struct channel_map { + struct ieee802_1x_mka_sci sci; + }; + + struct macsec_qca_data { +- char ifname[IFNAMSIZ + 1]; +- u32 secy_id; +- void *ctx; ++ struct driver_wired_common_data common; + +- int sock; /* raw packet socket for driver access */ +- int pf_sock; +- int membership, multi, iff_allmulti, iff_up; ++ u32 secy_id; + + /* shadow */ + Boolean always_include_sci; +@@ -322,43 +316,43 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + drv = os_zalloc(sizeof(*drv)); + if (drv == NULL) + return NULL; +- os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); +- drv->ctx = ctx; ++ os_strlcpy(drv->common.ifname, ifname, sizeof(drv->common.ifname)); ++ drv->common.ctx = ctx; + + /* Board specific settings */ +- if (os_memcmp("eth2", drv->ifname, 4) == 0) ++ if (os_memcmp("eth2", drv->common.ifname, 4) == 0) + drv->secy_id = 1; +- else if (os_memcmp("eth3", drv->ifname, 4) == 0) ++ else if (os_memcmp("eth3", drv->common.ifname, 4) == 0) + drv->secy_id = 2; + else + drv->secy_id = -1; + + #ifdef __linux__ +- drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); +- if (drv->pf_sock < 0) ++ drv->common.pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); ++ if (drv->common.pf_sock < 0) + wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); + #else /* __linux__ */ +- drv->pf_sock = -1; ++ drv->common.pf_sock = -1; + #endif /* __linux__ */ + + if (macsec_qca_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && + macsec_qca_set_ifflags(ifname, flags | IFF_UP) == 0) { +- drv->iff_up = 1; ++ drv->common.iff_up = 1; + } + +- if (macsec_qca_multicast_membership(drv->pf_sock, +- if_nametoindex(drv->ifname), ++ if (macsec_qca_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), + pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, + "%s: Added multicast membership with packet socket", + __func__); +- drv->membership = 1; ++ drv->common.membership = 1; + } else if (macsec_qca_multi(ifname, pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, + "%s: Added multicast membership with SIOCADDMULTI", + __func__); +- drv->multi = 1; ++ drv->common.multi = 1; + } else if (macsec_qca_get_ifflags(ifname, &flags) < 0) { + wpa_printf(MSG_INFO, "%s: Could not get interface flags", + __func__); +@@ -375,7 +369,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + return NULL; + } else { + wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", __func__); +- drv->iff_allmulti = 1; ++ drv->common.iff_allmulti = 1; + } + #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + { +@@ -397,39 +391,40 @@ static void macsec_qca_deinit(void *priv) + struct macsec_qca_data *drv = priv; + int flags; + +- if (drv->membership && +- macsec_qca_multicast_membership(drv->pf_sock, +- if_nametoindex(drv->ifname), ++ if (drv->common.membership && ++ macsec_qca_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), + pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, + "%s: Failed to remove PAE multicast group (PACKET)", + __func__); + } + +- if (drv->multi && +- macsec_qca_multi(drv->ifname, pae_group_addr, 0) < 0) { ++ if (drv->common.multi && ++ macsec_qca_multi(drv->common.ifname, pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, + "%s: Failed to remove PAE multicast group (SIOCDELMULTI)", + __func__); + } + +- if (drv->iff_allmulti && +- (macsec_qca_get_ifflags(drv->ifname, &flags) < 0 || +- macsec_qca_set_ifflags(drv->ifname, flags & ~IFF_ALLMULTI) < 0)) { ++ if (drv->common.iff_allmulti && ++ (macsec_qca_get_ifflags(drv->common.ifname, &flags) < 0 || ++ macsec_qca_set_ifflags(drv->common.ifname, ++ flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", + __func__); + } + +- if (drv->iff_up && +- macsec_qca_get_ifflags(drv->ifname, &flags) == 0 && ++ if (drv->common.iff_up && ++ macsec_qca_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && +- macsec_qca_set_ifflags(drv->ifname, flags & ~IFF_UP) < 0) { ++ macsec_qca_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", + __func__); + } + +- if (drv->pf_sock != -1) +- close(drv->pf_sock); ++ if (drv->common.pf_sock != -1) ++ close(drv->common.pf_sock); + + os_free(drv); + } +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 422a220..b6f79e3 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -12,6 +12,7 @@ + #include "common.h" + #include "eloop.h" + #include "driver.h" ++#include "driver_wired_common.h" + + #include + #undef IFNAMSIZ +@@ -42,20 +43,12 @@ struct ieee8023_hdr { + #pragma pack(pop) + #endif /* _MSC_VER */ + +-static const u8 pae_group_addr[ETH_ALEN] = +-{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; +- + + struct wpa_driver_wired_data { +- char ifname[IFNAMSIZ + 1]; +- void *ctx; ++ struct driver_wired_common_data common; + +- int sock; /* raw packet socket for driver access */ + int dhcp_sock; /* socket for dhcp packets */ + int use_pae_group_addr; +- +- int pf_sock; +- int membership, multi, iff_allmulti, iff_up; + }; + + +@@ -208,21 +201,22 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) + struct sockaddr_in addr2; + int n = 1; + +- drv->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE)); +- if (drv->sock < 0) { ++ drv->common.sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_PAE)); ++ if (drv->common.sock < 0) { + wpa_printf(MSG_ERROR, "socket[PF_PACKET,SOCK_RAW]: %s", + strerror(errno)); + return -1; + } + +- if (eloop_register_read_sock(drv->sock, handle_read, drv->ctx, NULL)) { ++ if (eloop_register_read_sock(drv->common.sock, handle_read, ++ drv->common.ctx, NULL)) { + wpa_printf(MSG_INFO, "Could not register read socket"); + return -1; + } + + os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); +- if (ioctl(drv->sock, SIOCGIFINDEX, &ifr) != 0) { ++ os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name)); ++ if (ioctl(drv->common.sock, SIOCGIFINDEX, &ifr) != 0) { + wpa_printf(MSG_ERROR, "ioctl(SIOCGIFINDEX): %s", + strerror(errno)); + return -1; +@@ -234,13 +228,14 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) + wpa_printf(MSG_DEBUG, "Opening raw packet socket for ifindex %d", + addr.sll_ifindex); + +- if (bind(drv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { ++ if (bind(drv->common.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) ++ { + wpa_printf(MSG_ERROR, "bind: %s", strerror(errno)); + return -1; + } + + /* filter multicast address */ +- if (wired_multicast_membership(drv->sock, ifr.ifr_ifindex, ++ if (wired_multicast_membership(drv->common.sock, ifr.ifr_ifindex, + pae_group_addr, 1) < 0) { + wpa_printf(MSG_ERROR, "wired: Failed to add multicast group " + "membership"); +@@ -248,8 +243,8 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) + } + + os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); +- if (ioctl(drv->sock, SIOCGIFHWADDR, &ifr) != 0) { ++ os_strlcpy(ifr.ifr_name, drv->common.ifname, sizeof(ifr.ifr_name)); ++ if (ioctl(drv->common.sock, SIOCGIFHWADDR, &ifr) != 0) { + wpa_printf(MSG_ERROR, "ioctl(SIOCGIFHWADDR): %s", + strerror(errno)); + return -1; +@@ -269,8 +264,8 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) + return -1; + } + +- if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp, drv->ctx, +- NULL)) { ++ if (eloop_register_read_sock(drv->dhcp_sock, handle_dhcp, ++ drv->common.ctx, NULL)) { + wpa_printf(MSG_INFO, "Could not register read socket"); + return -1; + } +@@ -294,7 +289,7 @@ static int wired_init_sockets(struct wpa_driver_wired_data *drv, u8 *own_addr) + } + + os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_ifrn.ifrn_name, drv->ifname, IFNAMSIZ); ++ os_strlcpy(ifr.ifr_ifrn.ifrn_name, drv->common.ifname, IFNAMSIZ); + if (setsockopt(drv->dhcp_sock, SOL_SOCKET, SO_BINDTODEVICE, + (char *) &ifr, sizeof(ifr)) < 0) { + wpa_printf(MSG_ERROR, +@@ -343,7 +338,7 @@ static int wired_send_eapol(void *priv, const u8 *addr, + pos = (u8 *) (hdr + 1); + os_memcpy(pos, data, data_len); + +- res = send(drv->sock, (u8 *) hdr, len, 0); ++ res = send(drv->common.sock, (u8 *) hdr, len, 0); + os_free(hdr); + + if (res < 0) { +@@ -368,8 +363,9 @@ static void * wired_driver_hapd_init(struct hostapd_data *hapd, + return NULL; + } + +- drv->ctx = hapd; +- os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); ++ drv->common.ctx = hapd; ++ os_strlcpy(drv->common.ifname, params->ifname, ++ sizeof(drv->common.ifname)); + drv->use_pae_group_addr = params->use_pae_group_addr; + + if (wired_init_sockets(drv, params->own_addr)) { +@@ -385,9 +381,9 @@ static void wired_driver_hapd_deinit(void *priv) + { + struct wpa_driver_wired_data *drv = priv; + +- if (drv->sock >= 0) { +- eloop_unregister_read_sock(drv->sock); +- close(drv->sock); ++ if (drv->common.sock >= 0) { ++ eloop_unregister_read_sock(drv->common.sock); ++ close(drv->common.sock); + } + + if (drv->dhcp_sock >= 0) { +@@ -564,33 +560,33 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + drv = os_zalloc(sizeof(*drv)); + if (drv == NULL) + return NULL; +- os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); +- drv->ctx = ctx; ++ os_strlcpy(drv->common.ifname, ifname, sizeof(drv->common.ifname)); ++ drv->common.ctx = ctx; + + #ifdef __linux__ +- drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); +- if (drv->pf_sock < 0) ++ drv->common.pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); ++ if (drv->common.pf_sock < 0) + wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); + #else /* __linux__ */ +- drv->pf_sock = -1; ++ drv->common.pf_sock = -1; + #endif /* __linux__ */ + + if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && + wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { +- drv->iff_up = 1; ++ drv->common.iff_up = 1; + } + +- if (wired_multicast_membership(drv->pf_sock, +- if_nametoindex(drv->ifname), ++ if (wired_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), + pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " + "packet socket", __func__); +- drv->membership = 1; ++ drv->common.membership = 1; + } else if (wpa_driver_wired_multi(ifname, pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " + "SIOCADDMULTI", __func__); +- drv->multi = 1; ++ drv->common.multi = 1; + } else if (wpa_driver_wired_get_ifflags(ifname, &flags) < 0) { + wpa_printf(MSG_INFO, "%s: Could not get interface " + "flags", __func__); +@@ -608,7 +604,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + } else { + wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", + __func__); +- drv->iff_allmulti = 1; ++ drv->common.iff_allmulti = 1; + } + #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + { +@@ -630,38 +626,39 @@ static void wpa_driver_wired_deinit(void *priv) + struct wpa_driver_wired_data *drv = priv; + int flags; + +- if (drv->membership && +- wired_multicast_membership(drv->pf_sock, +- if_nametoindex(drv->ifname), ++ if (drv->common.membership && ++ wired_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), + pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " + "group (PACKET)", __func__); + } + +- if (drv->multi && +- wpa_driver_wired_multi(drv->ifname, pae_group_addr, 0) < 0) { ++ if (drv->common.multi && ++ wpa_driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " + "group (SIOCDELMULTI)", __func__); + } + +- if (drv->iff_allmulti && +- (wpa_driver_wired_get_ifflags(drv->ifname, &flags) < 0 || +- wpa_driver_wired_set_ifflags(drv->ifname, ++ if (drv->common.iff_allmulti && ++ (wpa_driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || ++ wpa_driver_wired_set_ifflags(drv->common.ifname, + flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", + __func__); + } + +- if (drv->iff_up && +- wpa_driver_wired_get_ifflags(drv->ifname, &flags) == 0 && ++ if (drv->common.iff_up && ++ wpa_driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && +- wpa_driver_wired_set_ifflags(drv->ifname, flags & ~IFF_UP) < 0) { ++ wpa_driver_wired_set_ifflags(drv->common.ifname, ++ flags & ~IFF_UP) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", + __func__); + } + +- if (drv->pf_sock != -1) +- close(drv->pf_sock); ++ if (drv->common.pf_sock != -1) ++ close(drv->common.pf_sock); + + os_free(drv); + } +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +new file mode 100644 +index 0000000..8d9dd37 +--- /dev/null ++++ b/src/drivers/driver_wired_common.h +@@ -0,0 +1,25 @@ ++/* ++ * Common definitions for Wired Ethernet driver interfaces ++ * Copyright (c) 2005-2009, Jouni Malinen ++ * Copyright (c) 2004, Gunter Burchardt ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++ ++#ifndef DRIVER_WIRED_COMMON_H ++#define DRIVER_WIRED_COMMON_H ++ ++struct driver_wired_common_data { ++ char ifname[IFNAMSIZ + 1]; ++ void *ctx; ++ ++ int sock; /* raw packet socket for driver access */ ++ int pf_sock; ++ int membership, multi, iff_allmulti, iff_up; ++}; ++ ++static const u8 pae_group_addr[ETH_ALEN] = ++{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; ++ ++#endif /* DRIVER_WIRED_COMMON_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0019-drivers-Move-wired_multicast_membership-to-a-common-.patch b/SOURCES/macsec-0019-drivers-Move-wired_multicast_membership-to-a-common-.patch new file mode 100644 index 0000000..299a7e2 --- /dev/null +++ b/SOURCES/macsec-0019-drivers-Move-wired_multicast_membership-to-a-common-.patch @@ -0,0 +1,239 @@ +From b0906ef770ec5a74221bcb4e63dbbc8682f49d5a Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:45 +0100 +Subject: [PATCH] drivers: Move wired_multicast_membership() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 40 +++++---------------------- + src/drivers/driver_wired.c | 28 ------------------- + src/drivers/driver_wired_common.c | 57 +++++++++++++++++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 2 ++ + src/drivers/drivers.mak | 6 +++++ + src/drivers/drivers.mk | 5 ++++ + 6 files changed, 76 insertions(+), 62 deletions(-) + create mode 100644 src/drivers/driver_wired_common.c + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 6391e08..e04fb0f 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -76,34 +76,6 @@ struct macsec_qca_data { + }; + + +-static int macsec_qca_multicast_membership(int sock, int ifindex, +- const u8 *addr, int add) +-{ +-#ifdef __linux__ +- struct packet_mreq mreq; +- +- if (sock < 0) +- return -1; +- +- os_memset(&mreq, 0, sizeof(mreq)); +- mreq.mr_ifindex = ifindex; +- mreq.mr_type = PACKET_MR_MULTICAST; +- mreq.mr_alen = ETH_ALEN; +- os_memcpy(mreq.mr_address, addr, ETH_ALEN); +- +- if (setsockopt(sock, SOL_PACKET, +- add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, +- &mreq, sizeof(mreq)) < 0) { +- wpa_printf(MSG_ERROR, "setsockopt: %s", strerror(errno)); +- return -1; +- } +- return 0; +-#else /* __linux__ */ +- return -1; +-#endif /* __linux__ */ +-} +- +- + static int macsec_qca_get_ssid(void *priv, u8 *ssid) + { + ssid[0] = 0; +@@ -341,9 +313,9 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + drv->common.iff_up = 1; + } + +- if (macsec_qca_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 1) == 0) { ++ if (wired_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), ++ pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, + "%s: Added multicast membership with packet socket", + __func__); +@@ -392,9 +364,9 @@ static void macsec_qca_deinit(void *priv) + int flags; + + if (drv->common.membership && +- macsec_qca_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 0) < 0) { ++ wired_multicast_membership(drv->common.pf_sock, ++ if_nametoindex(drv->common.ifname), ++ pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, + "%s: Failed to remove PAE multicast group (PACKET)", + __func__); +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index b6f79e3..68c55fd 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -76,34 +76,6 @@ struct dhcp_message { + }; + + +-static int wired_multicast_membership(int sock, int ifindex, +- const u8 *addr, int add) +-{ +-#ifdef __linux__ +- struct packet_mreq mreq; +- +- if (sock < 0) +- return -1; +- +- os_memset(&mreq, 0, sizeof(mreq)); +- mreq.mr_ifindex = ifindex; +- mreq.mr_type = PACKET_MR_MULTICAST; +- mreq.mr_alen = ETH_ALEN; +- os_memcpy(mreq.mr_address, addr, ETH_ALEN); +- +- if (setsockopt(sock, SOL_PACKET, +- add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, +- &mreq, sizeof(mreq)) < 0) { +- wpa_printf(MSG_ERROR, "setsockopt: %s", strerror(errno)); +- return -1; +- } +- return 0; +-#else /* __linux__ */ +- return -1; +-#endif /* __linux__ */ +-} +- +- + #ifdef __linux__ + static void handle_data(void *ctx, unsigned char *buf, size_t len) + { +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +new file mode 100644 +index 0000000..3969880 +--- /dev/null ++++ b/src/drivers/driver_wired_common.c +@@ -0,0 +1,57 @@ ++/* ++ * Common functions for Wired Ethernet driver interfaces ++ * Copyright (c) 2005-2009, Jouni Malinen ++ * Copyright (c) 2004, Gunter Burchardt ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++ ++#include "includes.h" ++ ++#include "common.h" ++#include "eloop.h" ++#include "driver.h" ++#include "driver_wired_common.h" ++ ++#include ++#include ++#ifdef __linux__ ++#include ++#include ++#include ++#endif /* __linux__ */ ++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) ++#include ++#include ++#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) */ ++#ifdef __sun__ ++#include ++#endif /* __sun__ */ ++ ++ ++int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) ++{ ++#ifdef __linux__ ++ struct packet_mreq mreq; ++ ++ if (sock < 0) ++ return -1; ++ ++ os_memset(&mreq, 0, sizeof(mreq)); ++ mreq.mr_ifindex = ifindex; ++ mreq.mr_type = PACKET_MR_MULTICAST; ++ mreq.mr_alen = ETH_ALEN; ++ os_memcpy(mreq.mr_address, addr, ETH_ALEN); ++ ++ if (setsockopt(sock, SOL_PACKET, ++ add ? PACKET_ADD_MEMBERSHIP : PACKET_DROP_MEMBERSHIP, ++ &mreq, sizeof(mreq)) < 0) { ++ wpa_printf(MSG_ERROR, "setsockopt: %s", strerror(errno)); ++ return -1; ++ } ++ return 0; ++#else /* __linux__ */ ++ return -1; ++#endif /* __linux__ */ ++} +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index 8d9dd37..39a57a6 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -22,4 +22,6 @@ struct driver_wired_common_data { + static const u8 pae_group_addr[ETH_ALEN] = + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + ++int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); ++ + #endif /* DRIVER_WIRED_COMMON_H */ +diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak +index c6d3f81..282da50 100644 +--- a/src/drivers/drivers.mak ++++ b/src/drivers/drivers.mak +@@ -15,11 +15,17 @@ DRV_AP_LIBS = + ifdef CONFIG_DRIVER_WIRED + DRV_CFLAGS += -DCONFIG_DRIVER_WIRED + DRV_OBJS += ../src/drivers/driver_wired.o ++NEED_DRV_WIRED_COMMON=1 + endif + + ifdef CONFIG_DRIVER_MACSEC_QCA + DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA + DRV_OBJS += ../src/drivers/driver_macsec_qca.o ++NEED_DRV_WIRED_COMMON=1 ++endif ++ ++ifdef NEED_DRV_WIRED_COMMON ++DRV_OBJS += ../src/drivers/driver_wired_common.o + endif + + ifdef CONFIG_DRIVER_NL80211 +diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk +index c6fe4c2..508f834 100644 +--- a/src/drivers/drivers.mk ++++ b/src/drivers/drivers.mk +@@ -15,6 +15,11 @@ DRV_AP_LIBS = + ifdef CONFIG_DRIVER_WIRED + DRV_CFLAGS += -DCONFIG_DRIVER_WIRED + DRV_OBJS += src/drivers/driver_wired.c ++NEED_DRV_WIRED_COMMON=1 ++endif ++ ++ifdef NEED_DRV_WIRED_COMMON ++DRV_OBJS += src/drivers/driver_wired_common.c + endif + + ifdef CONFIG_DRIVER_NL80211 +-- +2.7.4 + diff --git a/SOURCES/macsec-0020-drivers-Move-driver_wired_multi-to-a-common-file.patch b/SOURCES/macsec-0020-drivers-Move-driver_wired_multi-to-a-common-file.patch new file mode 100644 index 0000000..04ae056 --- /dev/null +++ b/SOURCES/macsec-0020-drivers-Move-driver_wired_multi-to-a-common-file.patch @@ -0,0 +1,268 @@ +From 693124a1e4f1c2be5ee67f412eb511c3b5b808bd Mon Sep 17 00:00:00 2001 +Message-Id: <693124a1e4f1c2be5ee67f412eb511c3b5b808bd.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:46 +0100 +Subject: [PATCH] drivers: Move driver_wired_multi() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 59 ++------------------------------------- + src/drivers/driver_wired.c | 59 ++------------------------------------- + src/drivers/driver_wired_common.c | 57 +++++++++++++++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 62 insertions(+), 114 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index e04fb0f..6c07e01 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -178,61 +178,6 @@ static int macsec_qca_get_ifstatus(const char *ifname, int *status) + #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ + + +-static int macsec_qca_multi(const char *ifname, const u8 *addr, int add) +-{ +- struct ifreq ifr; +- int s; +- +-#ifdef __sun__ +- return -1; +-#endif /* __sun__ */ +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +-#ifdef __linux__ +- ifr.ifr_hwaddr.sa_family = AF_UNSPEC; +- os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); +-#endif /* __linux__ */ +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +- { +- struct sockaddr_dl *dlp; +- dlp = (struct sockaddr_dl *) &ifr.ifr_addr; +- dlp->sdl_len = sizeof(struct sockaddr_dl); +- dlp->sdl_family = AF_LINK; +- dlp->sdl_index = 0; +- dlp->sdl_nlen = 0; +- dlp->sdl_alen = ETH_ALEN; +- dlp->sdl_slen = 0; +- os_memcpy(LLADDR(dlp), addr, ETH_ALEN); +- } +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ +-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +- { +- struct sockaddr *sap; +- sap = (struct sockaddr *) &ifr.ifr_addr; +- sap->sa_len = sizeof(struct sockaddr); +- sap->sa_family = AF_UNSPEC; +- os_memcpy(sap->sa_data, addr, ETH_ALEN); +- } +-#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */ +- +- if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOC{ADD/DEL}MULTI]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- return 0; +-} +- +- + static void __macsec_drv_init(struct macsec_qca_data *drv) + { + int ret = 0; +@@ -320,7 +265,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + "%s: Added multicast membership with packet socket", + __func__); + drv->common.membership = 1; +- } else if (macsec_qca_multi(ifname, pae_group_addr, 1) == 0) { ++ } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, + "%s: Added multicast membership with SIOCADDMULTI", + __func__); +@@ -373,7 +318,7 @@ static void macsec_qca_deinit(void *priv) + } + + if (drv->common.multi && +- macsec_qca_multi(drv->common.ifname, pae_group_addr, 0) < 0) { ++ driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, + "%s: Failed to remove PAE multicast group (SIOCDELMULTI)", + __func__); +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 68c55fd..20c66e3 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -469,61 +469,6 @@ static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status) + #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ + + +-static int wpa_driver_wired_multi(const char *ifname, const u8 *addr, int add) +-{ +- struct ifreq ifr; +- int s; +- +-#ifdef __sun__ +- return -1; +-#endif /* __sun__ */ +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +-#ifdef __linux__ +- ifr.ifr_hwaddr.sa_family = AF_UNSPEC; +- os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); +-#endif /* __linux__ */ +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +- { +- struct sockaddr_dl *dlp; +- dlp = (struct sockaddr_dl *) &ifr.ifr_addr; +- dlp->sdl_len = sizeof(struct sockaddr_dl); +- dlp->sdl_family = AF_LINK; +- dlp->sdl_index = 0; +- dlp->sdl_nlen = 0; +- dlp->sdl_alen = ETH_ALEN; +- dlp->sdl_slen = 0; +- os_memcpy(LLADDR(dlp), addr, ETH_ALEN); +- } +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ +-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) +- { +- struct sockaddr *sap; +- sap = (struct sockaddr *) &ifr.ifr_addr; +- sap->sa_len = sizeof(struct sockaddr); +- sap->sa_family = AF_UNSPEC; +- os_memcpy(sap->sa_data, addr, ETH_ALEN); +- } +-#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */ +- +- if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOC{ADD/DEL}MULTI]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- return 0; +-} +- +- + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +@@ -555,7 +500,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " + "packet socket", __func__); + drv->common.membership = 1; +- } else if (wpa_driver_wired_multi(ifname, pae_group_addr, 1) == 0) { ++ } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { + wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " + "SIOCADDMULTI", __func__); + drv->common.multi = 1; +@@ -607,7 +552,7 @@ static void wpa_driver_wired_deinit(void *priv) + } + + if (drv->common.multi && +- wpa_driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { ++ driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " + "group (SIOCDELMULTI)", __func__); + } +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index 3969880..4cb04da 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -30,6 +30,63 @@ + #endif /* __sun__ */ + + ++int driver_wired_multi(const char *ifname, const u8 *addr, int add) ++{ ++ struct ifreq ifr; ++ int s; ++ ++#ifdef __sun__ ++ return -1; ++#endif /* __sun__ */ ++ ++ s = socket(PF_INET, SOCK_DGRAM, 0); ++ if (s < 0) { ++ wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); ++ return -1; ++ } ++ ++ os_memset(&ifr, 0, sizeof(ifr)); ++ os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ++#ifdef __linux__ ++ ifr.ifr_hwaddr.sa_family = AF_UNSPEC; ++ os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN); ++#endif /* __linux__ */ ++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) ++ { ++ struct sockaddr_dl *dlp; ++ ++ dlp = (struct sockaddr_dl *) &ifr.ifr_addr; ++ dlp->sdl_len = sizeof(struct sockaddr_dl); ++ dlp->sdl_family = AF_LINK; ++ dlp->sdl_index = 0; ++ dlp->sdl_nlen = 0; ++ dlp->sdl_alen = ETH_ALEN; ++ dlp->sdl_slen = 0; ++ os_memcpy(LLADDR(dlp), addr, ETH_ALEN); ++ } ++#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ ++#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) ++ { ++ struct sockaddr *sap; ++ ++ sap = (struct sockaddr *) &ifr.ifr_addr; ++ sap->sa_len = sizeof(struct sockaddr); ++ sap->sa_family = AF_UNSPEC; ++ os_memcpy(sap->sa_data, addr, ETH_ALEN); ++ } ++#endif /* defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) */ ++ ++ if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) { ++ wpa_printf(MSG_ERROR, "ioctl[SIOC{ADD/DEL}MULTI]: %s", ++ strerror(errno)); ++ close(s); ++ return -1; ++ } ++ close(s); ++ return 0; ++} ++ ++ + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) + { + #ifdef __linux__ +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index 39a57a6..9bbe94f 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -22,6 +22,7 @@ struct driver_wired_common_data { + static const u8 pae_group_addr[ETH_ALEN] = + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + ++int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); + + #endif /* DRIVER_WIRED_COMMON_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0021-drivers-Move-driver_wired_get_ifflags-to-a-common-fi.patch b/SOURCES/macsec-0021-drivers-Move-driver_wired_get_ifflags-to-a-common-fi.patch new file mode 100644 index 0000000..a4ecec6 --- /dev/null +++ b/SOURCES/macsec-0021-drivers-Move-driver_wired_get_ifflags-to-a-common-fi.patch @@ -0,0 +1,212 @@ +From 567b7d4ec29cd5b97b00703b5afb03d023abb532 Mon Sep 17 00:00:00 2001 +Message-Id: <567b7d4ec29cd5b97b00703b5afb03d023abb532.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:47 +0100 +Subject: [PATCH] drivers: Move driver_wired_get_ifflags() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 33 ++++----------------------------- + src/drivers/driver_wired.c | 33 ++++----------------------------- + src/drivers/driver_wired_common.c | 25 +++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 34 insertions(+), 58 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 6c07e01..d0d4611 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -99,31 +99,6 @@ static int macsec_qca_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-static int macsec_qca_get_ifflags(const char *ifname, int *flags) +-{ +- struct ifreq ifr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +- if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- *flags = ifr.ifr_flags & 0xffff; +- return 0; +-} +- +- + static int macsec_qca_set_ifflags(const char *ifname, int flags) + { + struct ifreq ifr; +@@ -252,7 +227,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + drv->common.pf_sock = -1; + #endif /* __linux__ */ + +- if (macsec_qca_get_ifflags(ifname, &flags) == 0 && ++ if (driver_wired_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && + macsec_qca_set_ifflags(ifname, flags | IFF_UP) == 0) { + drv->common.iff_up = 1; +@@ -270,7 +245,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + "%s: Added multicast membership with SIOCADDMULTI", + __func__); + drv->common.multi = 1; +- } else if (macsec_qca_get_ifflags(ifname, &flags) < 0) { ++ } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { + wpa_printf(MSG_INFO, "%s: Could not get interface flags", + __func__); + os_free(drv); +@@ -325,7 +300,7 @@ static void macsec_qca_deinit(void *priv) + } + + if (drv->common.iff_allmulti && +- (macsec_qca_get_ifflags(drv->common.ifname, &flags) < 0 || ++ (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || + macsec_qca_set_ifflags(drv->common.ifname, + flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", +@@ -333,7 +308,7 @@ static void macsec_qca_deinit(void *priv) + } + + if (drv->common.iff_up && +- macsec_qca_get_ifflags(drv->common.ifname, &flags) == 0 && ++ driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && + macsec_qca_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 20c66e3..ad49eaf 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -390,31 +390,6 @@ static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-static int wpa_driver_wired_get_ifflags(const char *ifname, int *flags) +-{ +- struct ifreq ifr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +- if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- *flags = ifr.ifr_flags & 0xffff; +- return 0; +-} +- +- + static int wpa_driver_wired_set_ifflags(const char *ifname, int flags) + { + struct ifreq ifr; +@@ -488,7 +463,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + drv->common.pf_sock = -1; + #endif /* __linux__ */ + +- if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 && ++ if (driver_wired_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && + wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { + drv->common.iff_up = 1; +@@ -504,7 +479,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " + "SIOCADDMULTI", __func__); + drv->common.multi = 1; +- } else if (wpa_driver_wired_get_ifflags(ifname, &flags) < 0) { ++ } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { + wpa_printf(MSG_INFO, "%s: Could not get interface " + "flags", __func__); + os_free(drv); +@@ -558,7 +533,7 @@ static void wpa_driver_wired_deinit(void *priv) + } + + if (drv->common.iff_allmulti && +- (wpa_driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || ++ (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || + wpa_driver_wired_set_ifflags(drv->common.ifname, + flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", +@@ -566,7 +541,7 @@ static void wpa_driver_wired_deinit(void *priv) + } + + if (drv->common.iff_up && +- wpa_driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && ++ driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && + wpa_driver_wired_set_ifflags(drv->common.ifname, + flags & ~IFF_UP) < 0) { +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index 4cb04da..a84dcc7 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -30,6 +30,31 @@ + #endif /* __sun__ */ + + ++int driver_wired_get_ifflags(const char *ifname, int *flags) ++{ ++ struct ifreq ifr; ++ int s; ++ ++ s = socket(PF_INET, SOCK_DGRAM, 0); ++ if (s < 0) { ++ wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); ++ return -1; ++ } ++ ++ os_memset(&ifr, 0, sizeof(ifr)); ++ os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ++ if (ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { ++ wpa_printf(MSG_ERROR, "ioctl[SIOCGIFFLAGS]: %s", ++ strerror(errno)); ++ close(s); ++ return -1; ++ } ++ close(s); ++ *flags = ifr.ifr_flags & 0xffff; ++ return 0; ++} ++ ++ + int driver_wired_multi(const char *ifname, const u8 *addr, int add) + { + struct ifreq ifr; +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index 9bbe94f..b8ed0e0 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -22,6 +22,7 @@ struct driver_wired_common_data { + static const u8 pae_group_addr[ETH_ALEN] = + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + ++int driver_wired_get_ifflags(const char *ifname, int *flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); + +-- +2.7.4 + diff --git a/SOURCES/macsec-0022-drivers-Move-driver_wired_set_ifflags-to-a-common-fi.patch b/SOURCES/macsec-0022-drivers-Move-driver_wired_set_ifflags-to-a-common-fi.patch new file mode 100644 index 0000000..ef6bd1d --- /dev/null +++ b/SOURCES/macsec-0022-drivers-Move-driver_wired_set_ifflags-to-a-common-fi.patch @@ -0,0 +1,218 @@ +From d718a5d975de2309dc4478a62f3475cb0726f2a1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:48 +0100 +Subject: [PATCH] drivers: Move driver_wired_set_ifflags() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 35 +++++------------------------------ + src/drivers/driver_wired.c | 37 +++++-------------------------------- + src/drivers/driver_wired_common.c | 25 +++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 36 insertions(+), 62 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index d0d4611..31cb0dc 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -99,31 +99,6 @@ static int macsec_qca_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-static int macsec_qca_set_ifflags(const char *ifname, int flags) +-{ +- struct ifreq ifr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +- ifr.ifr_flags = flags & 0xffff; +- if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- return 0; +-} +- +- + #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + static int macsec_qca_get_ifstatus(const char *ifname, int *status) + { +@@ -229,7 +204,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + + if (driver_wired_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && +- macsec_qca_set_ifflags(ifname, flags | IFF_UP) == 0) { ++ driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { + drv->common.iff_up = 1; + } + +@@ -254,7 +229,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + wpa_printf(MSG_DEBUG, + "%s: Interface is already configured for multicast", + __func__); +- } else if (macsec_qca_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { ++ } else if (driver_wired_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { + wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", + __func__); + os_free(drv); +@@ -301,8 +276,8 @@ static void macsec_qca_deinit(void *priv) + + if (drv->common.iff_allmulti && + (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || +- macsec_qca_set_ifflags(drv->common.ifname, +- flags & ~IFF_ALLMULTI) < 0)) { ++ driver_wired_set_ifflags(drv->common.ifname, ++ flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", + __func__); + } +@@ -310,7 +285,7 @@ static void macsec_qca_deinit(void *priv) + if (drv->common.iff_up && + driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && +- macsec_qca_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { ++ driver_wired_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", + __func__); + } +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index ad49eaf..953fa3d 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -390,31 +390,6 @@ static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-static int wpa_driver_wired_set_ifflags(const char *ifname, int flags) +-{ +- struct ifreq ifr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifr, 0, sizeof(ifr)); +- os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); +- ifr.ifr_flags = flags & 0xffff; +- if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- return 0; +-} +- +- + #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status) + { +@@ -465,7 +440,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + + if (driver_wired_get_ifflags(ifname, &flags) == 0 && + !(flags & IFF_UP) && +- wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { ++ driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { + drv->common.iff_up = 1; + } + +@@ -487,8 +462,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + } else if (flags & IFF_ALLMULTI) { + wpa_printf(MSG_DEBUG, "%s: Interface is already configured " + "for multicast", __func__); +- } else if (wpa_driver_wired_set_ifflags(ifname, +- flags | IFF_ALLMULTI) < 0) { ++ } else if (driver_wired_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { + wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", + __func__); + os_free(drv); +@@ -534,8 +508,8 @@ static void wpa_driver_wired_deinit(void *priv) + + if (drv->common.iff_allmulti && + (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || +- wpa_driver_wired_set_ifflags(drv->common.ifname, +- flags & ~IFF_ALLMULTI) < 0)) { ++ driver_wired_set_ifflags(drv->common.ifname, ++ flags & ~IFF_ALLMULTI) < 0)) { + wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", + __func__); + } +@@ -543,8 +517,7 @@ static void wpa_driver_wired_deinit(void *priv) + if (drv->common.iff_up && + driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && + (flags & IFF_UP) && +- wpa_driver_wired_set_ifflags(drv->common.ifname, +- flags & ~IFF_UP) < 0) { ++ driver_wired_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { + wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", + __func__); + } +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index a84dcc7..52f22de 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -55,6 +55,31 @@ int driver_wired_get_ifflags(const char *ifname, int *flags) + } + + ++int driver_wired_set_ifflags(const char *ifname, int flags) ++{ ++ struct ifreq ifr; ++ int s; ++ ++ s = socket(PF_INET, SOCK_DGRAM, 0); ++ if (s < 0) { ++ wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); ++ return -1; ++ } ++ ++ os_memset(&ifr, 0, sizeof(ifr)); ++ os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); ++ ifr.ifr_flags = flags & 0xffff; ++ if (ioctl(s, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) { ++ wpa_printf(MSG_ERROR, "ioctl[SIOCSIFFLAGS]: %s", ++ strerror(errno)); ++ close(s); ++ return -1; ++ } ++ close(s); ++ return 0; ++} ++ ++ + int driver_wired_multi(const char *ifname, const u8 *addr, int add) + { + struct ifreq ifr; +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index b8ed0e0..e2d8bbe 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -23,6 +23,7 @@ static const u8 pae_group_addr[ETH_ALEN] = + { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; + + int driver_wired_get_ifflags(const char *ifname, int *flags); ++int driver_wired_set_ifflags(const char *ifname, int flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); + +-- +2.7.4 + diff --git a/SOURCES/macsec-0023-drivers-Move-driver_wired_get_ifstatus-to-a-common-f.patch b/SOURCES/macsec-0023-drivers-Move-driver_wired_get_ifstatus-to-a-common-f.patch new file mode 100644 index 0000000..e7d3cc3 --- /dev/null +++ b/SOURCES/macsec-0023-drivers-Move-driver_wired_get_ifstatus-to-a-common-f.patch @@ -0,0 +1,166 @@ +From 5a55ec38edd875fc6dc54c0483e1f96ad9cf8cf9 Mon Sep 17 00:00:00 2001 +Message-Id: <5a55ec38edd875fc6dc54c0483e1f96ad9cf8cf9.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:49 +0100 +Subject: [PATCH] drivers: Move driver_wired_get_ifstatus() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 31 +------------------------------ + src/drivers/driver_wired.c | 31 +------------------------------ + src/drivers/driver_wired_common.c | 29 +++++++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 32 insertions(+), 60 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 31cb0dc..786e2e8 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -99,35 +99,6 @@ static int macsec_qca_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +-static int macsec_qca_get_ifstatus(const char *ifname, int *status) +-{ +- struct ifmediareq ifmr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_print(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifmr, 0, sizeof(ifmr)); +- os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ); +- if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCGIFMEDIA]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- *status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) == +- (IFM_ACTIVE | IFM_AVALID); +- +- return 0; +-} +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ +- +- + static void __macsec_drv_init(struct macsec_qca_data *drv) + { + int ret = 0; +@@ -243,7 +214,7 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + int status; + wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", + __func__); +- while (macsec_qca_get_ifstatus(ifname, &status) == 0 && ++ while (driver_wired_get_ifstatus(ifname, &status) == 0 && + status == 0) + sleep(1); + } +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 953fa3d..db83683 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -390,35 +390,6 @@ static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) + } + + +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +-static int wpa_driver_wired_get_ifstatus(const char *ifname, int *status) +-{ +- struct ifmediareq ifmr; +- int s; +- +- s = socket(PF_INET, SOCK_DGRAM, 0); +- if (s < 0) { +- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); +- return -1; +- } +- +- os_memset(&ifmr, 0, sizeof(ifmr)); +- os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ); +- if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { +- wpa_printf(MSG_ERROR, "ioctl[SIOCGIFMEDIA]: %s", +- strerror(errno)); +- close(s); +- return -1; +- } +- close(s); +- *status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) == +- (IFM_ACTIVE | IFM_AVALID); +- +- return 0; +-} +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ +- +- + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +@@ -477,7 +448,7 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + int status; + wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", + __func__); +- while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 && ++ while (driver_wired_get_ifstatus(ifname, &status) == 0 && + status == 0) + sleep(1); + } +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index 52f22de..e55e2c7 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -162,3 +162,32 @@ int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) + return -1; + #endif /* __linux__ */ + } ++ ++ ++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) ++int driver_wired_get_ifstatus(const char *ifname, int *status) ++{ ++ struct ifmediareq ifmr; ++ int s; ++ ++ s = socket(PF_INET, SOCK_DGRAM, 0); ++ if (s < 0) { ++ wpa_printf(MSG_ERROR, "socket: %s", strerror(errno)); ++ return -1; ++ } ++ ++ os_memset(&ifmr, 0, sizeof(ifmr)); ++ os_strlcpy(ifmr.ifm_name, ifname, IFNAMSIZ); ++ if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) { ++ wpa_printf(MSG_ERROR, "ioctl[SIOCGIFMEDIA]: %s", ++ strerror(errno)); ++ close(s); ++ return -1; ++ } ++ close(s); ++ *status = (ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) == ++ (IFM_ACTIVE | IFM_AVALID); ++ ++ return 0; ++} ++#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index e2d8bbe..c8e347a 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -26,5 +26,6 @@ int driver_wired_get_ifflags(const char *ifname, int *flags); + int driver_wired_set_ifflags(const char *ifname, int flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); ++int driver_wired_get_ifstatus(const char *ifname, int *status); + + #endif /* DRIVER_WIRED_COMMON_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0024-drivers-Move-driver_wired_init_common-to-a-common-fi.patch b/SOURCES/macsec-0024-drivers-Move-driver_wired_init_common-to-a-common-fi.patch new file mode 100644 index 0000000..bacda4e --- /dev/null +++ b/SOURCES/macsec-0024-drivers-Move-driver_wired_init_common-to-a-common-fi.patch @@ -0,0 +1,261 @@ +From ed5ae6119307b981eb9d0eaff3fa2ca53e79e629 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:50 +0100 +Subject: [PATCH] drivers: Move driver_wired_init_common() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 59 ++--------------------------------- + src/drivers/driver_wired.c | 53 +------------------------------ + src/drivers/driver_wired_common.c | 65 +++++++++++++++++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 3 ++ + 4 files changed, 72 insertions(+), 108 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 786e2e8..26003b0 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -149,76 +149,23 @@ static void __macsec_drv_deinit(struct macsec_qca_data *drv) + static void * macsec_qca_init(void *ctx, const char *ifname) + { + struct macsec_qca_data *drv; +- int flags; + + drv = os_zalloc(sizeof(*drv)); + if (drv == NULL) + return NULL; +- os_strlcpy(drv->common.ifname, ifname, sizeof(drv->common.ifname)); +- drv->common.ctx = ctx; + + /* Board specific settings */ +- if (os_memcmp("eth2", drv->common.ifname, 4) == 0) ++ if (os_memcmp("eth2", ifname, 4) == 0) + drv->secy_id = 1; +- else if (os_memcmp("eth3", drv->common.ifname, 4) == 0) ++ else if (os_memcmp("eth3", ifname, 4) == 0) + drv->secy_id = 2; + else + drv->secy_id = -1; + +-#ifdef __linux__ +- drv->common.pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); +- if (drv->common.pf_sock < 0) +- wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); +-#else /* __linux__ */ +- drv->common.pf_sock = -1; +-#endif /* __linux__ */ +- +- if (driver_wired_get_ifflags(ifname, &flags) == 0 && +- !(flags & IFF_UP) && +- driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { +- drv->common.iff_up = 1; +- } +- +- if (wired_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 1) == 0) { +- wpa_printf(MSG_DEBUG, +- "%s: Added multicast membership with packet socket", +- __func__); +- drv->common.membership = 1; +- } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { +- wpa_printf(MSG_DEBUG, +- "%s: Added multicast membership with SIOCADDMULTI", +- __func__); +- drv->common.multi = 1; +- } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { +- wpa_printf(MSG_INFO, "%s: Could not get interface flags", +- __func__); +- os_free(drv); +- return NULL; +- } else if (flags & IFF_ALLMULTI) { +- wpa_printf(MSG_DEBUG, +- "%s: Interface is already configured for multicast", +- __func__); +- } else if (driver_wired_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { +- wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", +- __func__); ++ if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) { + os_free(drv); + return NULL; +- } else { +- wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", __func__); +- drv->common.iff_allmulti = 1; +- } +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +- { +- int status; +- wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", +- __func__); +- while (driver_wired_get_ifstatus(ifname, &status) == 0 && +- status == 0) +- sleep(1); + } +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ + + return drv; + } +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index db83683..38476af 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -393,66 +393,15 @@ static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +- int flags; + + drv = os_zalloc(sizeof(*drv)); + if (drv == NULL) + return NULL; +- os_strlcpy(drv->common.ifname, ifname, sizeof(drv->common.ifname)); +- drv->common.ctx = ctx; +- +-#ifdef __linux__ +- drv->common.pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); +- if (drv->common.pf_sock < 0) +- wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); +-#else /* __linux__ */ +- drv->common.pf_sock = -1; +-#endif /* __linux__ */ +- +- if (driver_wired_get_ifflags(ifname, &flags) == 0 && +- !(flags & IFF_UP) && +- driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { +- drv->common.iff_up = 1; +- } + +- if (wired_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 1) == 0) { +- wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " +- "packet socket", __func__); +- drv->common.membership = 1; +- } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { +- wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " +- "SIOCADDMULTI", __func__); +- drv->common.multi = 1; +- } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { +- wpa_printf(MSG_INFO, "%s: Could not get interface " +- "flags", __func__); ++ if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) { + os_free(drv); + return NULL; +- } else if (flags & IFF_ALLMULTI) { +- wpa_printf(MSG_DEBUG, "%s: Interface is already configured " +- "for multicast", __func__); +- } else if (driver_wired_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { +- wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", +- __func__); +- os_free(drv); +- return NULL; +- } else { +- wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", +- __func__); +- drv->common.iff_allmulti = 1; +- } +-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) +- { +- int status; +- wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", +- __func__); +- while (driver_wired_get_ifstatus(ifname, &status) == 0 && +- status == 0) +- sleep(1); + } +-#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ + + return drv; + } +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index e55e2c7..6f782c2 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -191,3 +191,68 @@ int driver_wired_get_ifstatus(const char *ifname, int *status) + return 0; + } + #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ ++ ++ ++int driver_wired_init_common(struct driver_wired_common_data *common, ++ const char *ifname, void *ctx) ++{ ++ int flags; ++ ++ os_strlcpy(common->ifname, ifname, sizeof(common->ifname)); ++ common->ctx = ctx; ++ ++#ifdef __linux__ ++ common->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); ++ if (common->pf_sock < 0) ++ wpa_printf(MSG_ERROR, "socket(PF_PACKET): %s", strerror(errno)); ++#else /* __linux__ */ ++ common->pf_sock = -1; ++#endif /* __linux__ */ ++ ++ if (driver_wired_get_ifflags(ifname, &flags) == 0 && ++ !(flags & IFF_UP) && ++ driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) ++ common->iff_up = 1; ++ ++ if (wired_multicast_membership(common->pf_sock, ++ if_nametoindex(common->ifname), ++ pae_group_addr, 1) == 0) { ++ wpa_printf(MSG_DEBUG, ++ "%s: Added multicast membership with packet socket", ++ __func__); ++ common->membership = 1; ++ } else if (driver_wired_multi(ifname, pae_group_addr, 1) == 0) { ++ wpa_printf(MSG_DEBUG, ++ "%s: Added multicast membership with SIOCADDMULTI", ++ __func__); ++ common->multi = 1; ++ } else if (driver_wired_get_ifflags(ifname, &flags) < 0) { ++ wpa_printf(MSG_INFO, "%s: Could not get interface flags", ++ __func__); ++ return -1; ++ } else if (flags & IFF_ALLMULTI) { ++ wpa_printf(MSG_DEBUG, ++ "%s: Interface is already configured for multicast", ++ __func__); ++ } else if (driver_wired_set_ifflags(ifname, ++ flags | IFF_ALLMULTI) < 0) { ++ wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", __func__); ++ return -1; ++ } else { ++ wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", __func__); ++ common->iff_allmulti = 1; ++ } ++#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) ++ { ++ int status; ++ ++ wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", ++ __func__); ++ while (driver_wired_get_ifstatus(ifname, &status) == 0 && ++ status == 0) ++ sleep(1); ++ } ++#endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ ++ ++ return 0; ++} +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index c8e347a..e4f54b9 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -28,4 +28,7 @@ int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); + int driver_wired_get_ifstatus(const char *ifname, int *status); + ++int driver_wired_init_common(struct driver_wired_common_data *common, ++ const char *ifname, void *ctx); ++ + #endif /* DRIVER_WIRED_COMMON_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0025-drivers-Move-driver_wired_deinit_common-to-a-common-.patch b/SOURCES/macsec-0025-drivers-Move-driver_wired_deinit_common-to-a-common-.patch new file mode 100644 index 0000000..731d5e9 --- /dev/null +++ b/SOURCES/macsec-0025-drivers-Move-driver_wired_deinit_common-to-a-common-.patch @@ -0,0 +1,176 @@ +From ec9cfb96c2db746f26ceaa577953cfc2dc9d0f49 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:51 +0100 +Subject: [PATCH] drivers: Move driver_wired_deinit_common() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 37 +---------------------------------- + src/drivers/driver_wired.c | 35 +-------------------------------- + src/drivers/driver_wired_common.c | 41 +++++++++++++++++++++++++++++++++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 44 insertions(+), 70 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 26003b0..30bf31c 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -174,43 +174,8 @@ static void * macsec_qca_init(void *ctx, const char *ifname) + static void macsec_qca_deinit(void *priv) + { + struct macsec_qca_data *drv = priv; +- int flags; +- +- if (drv->common.membership && +- wired_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 0) < 0) { +- wpa_printf(MSG_DEBUG, +- "%s: Failed to remove PAE multicast group (PACKET)", +- __func__); +- } +- +- if (drv->common.multi && +- driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { +- wpa_printf(MSG_DEBUG, +- "%s: Failed to remove PAE multicast group (SIOCDELMULTI)", +- __func__); +- } +- +- if (drv->common.iff_allmulti && +- (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || +- driver_wired_set_ifflags(drv->common.ifname, +- flags & ~IFF_ALLMULTI) < 0)) { +- wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", +- __func__); +- } +- +- if (drv->common.iff_up && +- driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && +- (flags & IFF_UP) && +- driver_wired_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { +- wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", +- __func__); +- } +- +- if (drv->common.pf_sock != -1) +- close(drv->common.pf_sock); + ++ driver_wired_deinit_common(&drv->common); + os_free(drv); + } + +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 38476af..54217bc 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -410,41 +410,8 @@ static void * wpa_driver_wired_init(void *ctx, const char *ifname) + static void wpa_driver_wired_deinit(void *priv) + { + struct wpa_driver_wired_data *drv = priv; +- int flags; +- +- if (drv->common.membership && +- wired_multicast_membership(drv->common.pf_sock, +- if_nametoindex(drv->common.ifname), +- pae_group_addr, 0) < 0) { +- wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " +- "group (PACKET)", __func__); +- } +- +- if (drv->common.multi && +- driver_wired_multi(drv->common.ifname, pae_group_addr, 0) < 0) { +- wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE multicast " +- "group (SIOCDELMULTI)", __func__); +- } +- +- if (drv->common.iff_allmulti && +- (driver_wired_get_ifflags(drv->common.ifname, &flags) < 0 || +- driver_wired_set_ifflags(drv->common.ifname, +- flags & ~IFF_ALLMULTI) < 0)) { +- wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", +- __func__); +- } +- +- if (drv->common.iff_up && +- driver_wired_get_ifflags(drv->common.ifname, &flags) == 0 && +- (flags & IFF_UP) && +- driver_wired_set_ifflags(drv->common.ifname, flags & ~IFF_UP) < 0) { +- wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", +- __func__); +- } +- +- if (drv->common.pf_sock != -1) +- close(drv->common.pf_sock); + ++ driver_wired_deinit_common(&drv->common); + os_free(drv); + } + +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index 6f782c2..73c2b1b 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -256,3 +256,44 @@ int driver_wired_init_common(struct driver_wired_common_data *common, + + return 0; + } ++ ++ ++void driver_wired_deinit_common(struct driver_wired_common_data *common) ++{ ++ int flags; ++ ++ if (common->membership && ++ wired_multicast_membership(common->pf_sock, ++ if_nametoindex(common->ifname), ++ pae_group_addr, 0) < 0) { ++ wpa_printf(MSG_DEBUG, ++ "%s: Failed to remove PAE multicast group (PACKET)", ++ __func__); ++ } ++ ++ if (common->multi && ++ driver_wired_multi(common->ifname, pae_group_addr, 0) < 0) { ++ wpa_printf(MSG_DEBUG, ++ "%s: Failed to remove PAE multicast group (SIOCDELMULTI)", ++ __func__); ++ } ++ ++ if (common->iff_allmulti && ++ (driver_wired_get_ifflags(common->ifname, &flags) < 0 || ++ driver_wired_set_ifflags(common->ifname, ++ flags & ~IFF_ALLMULTI) < 0)) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to disable allmulti mode", ++ __func__); ++ } ++ ++ if (common->iff_up && ++ driver_wired_get_ifflags(common->ifname, &flags) == 0 && ++ (flags & IFF_UP) && ++ driver_wired_set_ifflags(common->ifname, flags & ~IFF_UP) < 0) { ++ wpa_printf(MSG_DEBUG, "%s: Failed to set the interface down", ++ __func__); ++ } ++ ++ if (common->pf_sock != -1) ++ close(common->pf_sock); ++} +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index e4f54b9..f362dbd 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -30,5 +30,6 @@ int driver_wired_get_ifstatus(const char *ifname, int *status); + + int driver_wired_init_common(struct driver_wired_common_data *common, + const char *ifname, void *ctx); ++void driver_wired_deinit_common(struct driver_wired_common_data *common); + + #endif /* DRIVER_WIRED_COMMON_H */ +-- +2.7.4 + diff --git a/SOURCES/macsec-0026-drivers-Move-driver_wired_get_capa-to-a-common-file.patch b/SOURCES/macsec-0026-drivers-Move-driver_wired_get_capa-to-a-common-file.patch new file mode 100644 index 0000000..6435f50 --- /dev/null +++ b/SOURCES/macsec-0026-drivers-Move-driver_wired_get_capa-to-a-common-file.patch @@ -0,0 +1,107 @@ +From 9281e5c5ce83648d344808e08f213f4e11a44573 Mon Sep 17 00:00:00 2001 +Message-Id: <9281e5c5ce83648d344808e08f213f4e11a44573.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:52 +0100 +Subject: [PATCH] drivers: Move driver_wired_get_capa() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 10 +--------- + src/drivers/driver_wired.c | 10 +--------- + src/drivers/driver_wired_common.c | 8 ++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 11 insertions(+), 18 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 30bf31c..15ea4bd 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -91,14 +91,6 @@ static int macsec_qca_get_bssid(void *priv, u8 *bssid) + } + + +-static int macsec_qca_get_capa(void *priv, struct wpa_driver_capa *capa) +-{ +- os_memset(capa, 0, sizeof(*capa)); +- capa->flags = WPA_DRIVER_FLAGS_WIRED; +- return 0; +-} +- +- + static void __macsec_drv_init(struct macsec_qca_data *drv) + { + int ret = 0; +@@ -758,7 +750,7 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = { + .desc = "QCA MACsec Ethernet driver", + .get_ssid = macsec_qca_get_ssid, + .get_bssid = macsec_qca_get_bssid, +- .get_capa = macsec_qca_get_capa, ++ .get_capa = driver_wired_get_capa, + .init = macsec_qca_init, + .deinit = macsec_qca_deinit, + +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index 54217bc..fd8a7e3 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -382,14 +382,6 @@ static int wpa_driver_wired_get_bssid(void *priv, u8 *bssid) + } + + +-static int wpa_driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) +-{ +- os_memset(capa, 0, sizeof(*capa)); +- capa->flags = WPA_DRIVER_FLAGS_WIRED; +- return 0; +-} +- +- + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +@@ -424,7 +416,7 @@ const struct wpa_driver_ops wpa_driver_wired_ops = { + .hapd_send_eapol = wired_send_eapol, + .get_ssid = wpa_driver_wired_get_ssid, + .get_bssid = wpa_driver_wired_get_bssid, +- .get_capa = wpa_driver_wired_get_capa, ++ .get_capa = driver_wired_get_capa, + .init = wpa_driver_wired_init, + .deinit = wpa_driver_wired_deinit, + }; +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index 73c2b1b..b31474d 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -164,6 +164,14 @@ int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) + } + + ++int driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) ++{ ++ os_memset(capa, 0, sizeof(*capa)); ++ capa->flags = WPA_DRIVER_FLAGS_WIRED; ++ return 0; ++} ++ ++ + #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) + int driver_wired_get_ifstatus(const char *ifname, int *status) + { +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index f362dbd..b926d83 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -26,6 +26,7 @@ int driver_wired_get_ifflags(const char *ifname, int *flags); + int driver_wired_set_ifflags(const char *ifname, int flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); ++int driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa); + int driver_wired_get_ifstatus(const char *ifname, int *status); + + int driver_wired_init_common(struct driver_wired_common_data *common, +-- +2.7.4 + diff --git a/SOURCES/macsec-0027-drivers-Move-driver_wired_get_bssid-to-a-common-file.patch b/SOURCES/macsec-0027-drivers-Move-driver_wired_get_bssid-to-a-common-file.patch new file mode 100644 index 0000000..cd05ca4 --- /dev/null +++ b/SOURCES/macsec-0027-drivers-Move-driver_wired_get_bssid-to-a-common-file.patch @@ -0,0 +1,107 @@ +From d27c42baea5d52f3f4fdc36ed98c7d10289ad973 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:53 +0100 +Subject: [PATCH] drivers: Move driver_wired_get_bssid() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 10 +--------- + src/drivers/driver_wired.c | 10 +--------- + src/drivers/driver_wired_common.c | 8 ++++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 11 insertions(+), 18 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 15ea4bd..4bbc59f 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -83,14 +83,6 @@ static int macsec_qca_get_ssid(void *priv, u8 *ssid) + } + + +-static int macsec_qca_get_bssid(void *priv, u8 *bssid) +-{ +- /* Report PAE group address as the "BSSID" for macsec connection. */ +- os_memcpy(bssid, pae_group_addr, ETH_ALEN); +- return 0; +-} +- +- + static void __macsec_drv_init(struct macsec_qca_data *drv) + { + int ret = 0; +@@ -749,7 +741,7 @@ const struct wpa_driver_ops wpa_driver_macsec_qca_ops = { + .name = "macsec_qca", + .desc = "QCA MACsec Ethernet driver", + .get_ssid = macsec_qca_get_ssid, +- .get_bssid = macsec_qca_get_bssid, ++ .get_bssid = driver_wired_get_bssid, + .get_capa = driver_wired_get_capa, + .init = macsec_qca_init, + .deinit = macsec_qca_deinit, +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index fd8a7e3..ad34627 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -374,14 +374,6 @@ static int wpa_driver_wired_get_ssid(void *priv, u8 *ssid) + } + + +-static int wpa_driver_wired_get_bssid(void *priv, u8 *bssid) +-{ +- /* Report PAE group address as the "BSSID" for wired connection. */ +- os_memcpy(bssid, pae_group_addr, ETH_ALEN); +- return 0; +-} +- +- + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +@@ -415,7 +407,7 @@ const struct wpa_driver_ops wpa_driver_wired_ops = { + .hapd_deinit = wired_driver_hapd_deinit, + .hapd_send_eapol = wired_send_eapol, + .get_ssid = wpa_driver_wired_get_ssid, +- .get_bssid = wpa_driver_wired_get_bssid, ++ .get_bssid = driver_wired_get_bssid, + .get_capa = driver_wired_get_capa, + .init = wpa_driver_wired_init, + .deinit = wpa_driver_wired_deinit, +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index b31474d..d30d3a4 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -164,6 +164,14 @@ int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) + } + + ++int driver_wired_get_bssid(void *priv, u8 *bssid) ++{ ++ /* Report PAE group address as the "BSSID" for wired connection. */ ++ os_memcpy(bssid, pae_group_addr, ETH_ALEN); ++ return 0; ++} ++ ++ + int driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa) + { + os_memset(capa, 0, sizeof(*capa)); +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index b926d83..493987a 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -26,6 +26,7 @@ int driver_wired_get_ifflags(const char *ifname, int *flags); + int driver_wired_set_ifflags(const char *ifname, int flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); ++int driver_wired_get_bssid(void *priv, u8 *bssid); + int driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa); + int driver_wired_get_ifstatus(const char *ifname, int *status); + +-- +2.7.4 + diff --git a/SOURCES/macsec-0028-drivers-Move-driver_wired_get_ssid-to-a-common-file.patch b/SOURCES/macsec-0028-drivers-Move-driver_wired_get_ssid-to-a-common-file.patch new file mode 100644 index 0000000..dd9a914 --- /dev/null +++ b/SOURCES/macsec-0028-drivers-Move-driver_wired_get_ssid-to-a-common-file.patch @@ -0,0 +1,104 @@ +From 8618313b6ef1c40002836ffc56d70466ea80d44e Mon Sep 17 00:00:00 2001 +Message-Id: <8618313b6ef1c40002836ffc56d70466ea80d44e.1488376602.git.dcaratti@redhat.com> +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:54 +0100 +Subject: [PATCH] drivers: Move driver_wired_get_ssid() to a common file + +This continues refactoring of the common parts of wired drivers code +into a shared file, so that they can be reused by other drivers. + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver_macsec_qca.c | 9 +-------- + src/drivers/driver_wired.c | 9 +-------- + src/drivers/driver_wired_common.c | 7 +++++++ + src/drivers/driver_wired_common.h | 1 + + 4 files changed, 10 insertions(+), 16 deletions(-) + +diff --git a/src/drivers/driver_macsec_qca.c b/src/drivers/driver_macsec_qca.c +index 4bbc59f..d3be19c 100644 +--- a/src/drivers/driver_macsec_qca.c ++++ b/src/drivers/driver_macsec_qca.c +@@ -76,13 +76,6 @@ struct macsec_qca_data { + }; + + +-static int macsec_qca_get_ssid(void *priv, u8 *ssid) +-{ +- ssid[0] = 0; +- return 0; +-} +- +- + static void __macsec_drv_init(struct macsec_qca_data *drv) + { + int ret = 0; +@@ -740,7 +733,7 @@ static int macsec_qca_disable_transmit_sa(void *priv, struct transmit_sa *sa) + const struct wpa_driver_ops wpa_driver_macsec_qca_ops = { + .name = "macsec_qca", + .desc = "QCA MACsec Ethernet driver", +- .get_ssid = macsec_qca_get_ssid, ++ .get_ssid = driver_wired_get_ssid, + .get_bssid = driver_wired_get_bssid, + .get_capa = driver_wired_get_capa, + .init = macsec_qca_init, +diff --git a/src/drivers/driver_wired.c b/src/drivers/driver_wired.c +index ad34627..7e09dcf 100644 +--- a/src/drivers/driver_wired.c ++++ b/src/drivers/driver_wired.c +@@ -367,13 +367,6 @@ static void wired_driver_hapd_deinit(void *priv) + } + + +-static int wpa_driver_wired_get_ssid(void *priv, u8 *ssid) +-{ +- ssid[0] = 0; +- return 0; +-} +- +- + static void * wpa_driver_wired_init(void *ctx, const char *ifname) + { + struct wpa_driver_wired_data *drv; +@@ -406,7 +399,7 @@ const struct wpa_driver_ops wpa_driver_wired_ops = { + .hapd_init = wired_driver_hapd_init, + .hapd_deinit = wired_driver_hapd_deinit, + .hapd_send_eapol = wired_send_eapol, +- .get_ssid = wpa_driver_wired_get_ssid, ++ .get_ssid = driver_wired_get_ssid, + .get_bssid = driver_wired_get_bssid, + .get_capa = driver_wired_get_capa, + .init = wpa_driver_wired_init, +diff --git a/src/drivers/driver_wired_common.c b/src/drivers/driver_wired_common.c +index d30d3a4..2e169d7 100644 +--- a/src/drivers/driver_wired_common.c ++++ b/src/drivers/driver_wired_common.c +@@ -164,6 +164,13 @@ int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add) + } + + ++int driver_wired_get_ssid(void *priv, u8 *ssid) ++{ ++ ssid[0] = 0; ++ return 0; ++} ++ ++ + int driver_wired_get_bssid(void *priv, u8 *bssid) + { + /* Report PAE group address as the "BSSID" for wired connection. */ +diff --git a/src/drivers/driver_wired_common.h b/src/drivers/driver_wired_common.h +index 493987a..7e1a4ae 100644 +--- a/src/drivers/driver_wired_common.h ++++ b/src/drivers/driver_wired_common.h +@@ -26,6 +26,7 @@ int driver_wired_get_ifflags(const char *ifname, int *flags); + int driver_wired_set_ifflags(const char *ifname, int flags); + int driver_wired_multi(const char *ifname, const u8 *addr, int add); + int wired_multicast_membership(int sock, int ifindex, const u8 *addr, int add); ++int driver_wired_get_ssid(void *priv, u8 *ssid); + int driver_wired_get_bssid(void *priv, u8 *bssid); + int driver_wired_get_capa(void *priv, struct wpa_driver_capa *capa); + int driver_wired_get_ifstatus(const char *ifname, int *status); +-- +2.7.4 + diff --git a/SOURCES/macsec-0029-macsec_linux-Add-a-driver-for-macsec-on-Linux-kernel.patch b/SOURCES/macsec-0029-macsec_linux-Add-a-driver-for-macsec-on-Linux-kernel.patch new file mode 100644 index 0000000..04438a7 --- /dev/null +++ b/SOURCES/macsec-0029-macsec_linux-Add-a-driver-for-macsec-on-Linux-kernel.patch @@ -0,0 +1,1397 @@ +From f014d9dbf04d0637429f7eb85c915def87f2f7d8 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:55 +0100 +Subject: [PATCH] macsec_linux: Add a driver for macsec on Linux kernels + +This uses libnl3 to communicate with the macsec module available on +Linux. A recent enough version of libnl is needed for the macsec.h file +(which is not yet available in a formal libnl release at the time of +this commit). + +Signed-off-by: Sabrina Dubroca +--- + src/drivers/driver.h | 4 + + src/drivers/driver_macsec_linux.c | 1265 +++++++++++++++++++++++++++++++++++++ + src/drivers/drivers.c | 3 + + src/drivers/drivers.mak | 7 + + src/drivers/drivers.mk | 7 + + src/pae/ieee802_1x_kay.c | 11 + + src/pae/ieee802_1x_kay.h | 2 + + 7 files changed, 1299 insertions(+) + create mode 100644 src/drivers/driver_macsec_linux.c + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index ffe5560..71ad006 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -5050,6 +5050,10 @@ extern const struct wpa_driver_ops wpa_driver_wired_ops; /* driver_wired.c */ + /* driver_macsec_qca.c */ + extern const struct wpa_driver_ops wpa_driver_macsec_qca_ops; + #endif /* CONFIG_DRIVER_MACSEC_QCA */ ++#ifdef CONFIG_DRIVER_MACSEC_LINUX ++/* driver_macsec_linux.c */ ++extern const struct wpa_driver_ops wpa_driver_macsec_linux_ops; ++#endif /* CONFIG_DRIVER_MACSEC_LINUX */ + #ifdef CONFIG_DRIVER_ROBOSWITCH + /* driver_roboswitch.c */ + extern const struct wpa_driver_ops wpa_driver_roboswitch_ops; +diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c +new file mode 100644 +index 0000000..5dab77a +--- /dev/null ++++ b/src/drivers/driver_macsec_linux.c +@@ -0,0 +1,1265 @@ ++/* ++ * Driver interaction with Linux MACsec kernel module ++ * Copyright (c) 2016, Sabrina Dubroca and Red Hat, Inc. ++ * ++ * This software may be distributed under the terms of the BSD license. ++ * See README for more details. ++ */ ++ ++#include "includes.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "utils/common.h" ++#include "utils/eloop.h" ++#include "pae/ieee802_1x_kay.h" ++#include "driver.h" ++#include "driver_wired_common.h" ++ ++#define DRV_PREFIX "macsec_linux: " ++ ++#define UNUSED_SCI 0xffffffffffffffff ++ ++struct cb_arg { ++ struct macsec_drv_data *drv; ++ u32 *pn; ++ int ifindex; ++ u8 txsa; ++ u8 rxsa; ++ u64 rxsci; ++}; ++ ++struct macsec_genl_ctx { ++ struct nl_sock *sk; ++ int macsec_genl_id; ++ struct cb_arg cb_arg; ++}; ++ ++struct macsec_drv_data { ++ struct driver_wired_common_data common; ++ struct rtnl_link *link; ++ struct nl_cache *link_cache; ++ struct nl_sock *sk; ++ struct macsec_genl_ctx ctx; ++ ++ struct netlink_data *netlink; ++ struct nl_handle *nl; ++ char ifname[IFNAMSIZ + 1]; ++ int ifi; ++ int parent_ifi; ++ ++ Boolean created_link; ++ ++ Boolean controlled_port_enabled; ++ Boolean controlled_port_enabled_set; ++ ++ Boolean protect_frames; ++ Boolean protect_frames_set; ++ ++ Boolean encrypt; ++ Boolean encrypt_set; ++ ++ Boolean replay_protect; ++ Boolean replay_protect_set; ++ ++ u32 replay_window; ++ ++ u8 encoding_sa; ++ Boolean encoding_sa_set; ++}; ++ ++ ++static int dump_callback(struct nl_msg *msg, void *argp); ++ ++ ++static struct nl_msg * msg_prepare(enum macsec_nl_commands cmd, ++ const struct macsec_genl_ctx *ctx, ++ unsigned int ifindex) ++{ ++ struct nl_msg *msg; ++ ++ msg = nlmsg_alloc(); ++ if (!msg) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc message"); ++ return NULL; ++ } ++ ++ if (!genlmsg_put(msg, 0, 0, ctx->macsec_genl_id, 0, 0, cmd, 0)) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "failed to put header"); ++ goto nla_put_failure; ++ } ++ ++ NLA_PUT_U32(msg, MACSEC_ATTR_IFINDEX, ifindex); ++ ++ return msg; ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return NULL; ++} ++ ++ ++static int nla_put_rxsc_config(struct nl_msg *msg, u64 sci) ++{ ++ struct nlattr *nest = nla_nest_start(msg, MACSEC_ATTR_RXSC_CONFIG); ++ ++ if (!nest) ++ return -1; ++ ++ NLA_PUT_U64(msg, MACSEC_RXSC_ATTR_SCI, sci); ++ ++ nla_nest_end(msg, nest); ++ ++ return 0; ++ ++nla_put_failure: ++ return -1; ++} ++ ++ ++static int init_genl_ctx(struct macsec_drv_data *drv) ++{ ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ ++ ctx->sk = nl_socket_alloc(); ++ if (!ctx->sk) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "failed to alloc genl socket"); ++ return -1; ++ } ++ ++ if (genl_connect(ctx->sk) < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "connection to genl socket failed"); ++ goto out_free; ++ } ++ ++ ctx->macsec_genl_id = genl_ctrl_resolve(ctx->sk, "macsec"); ++ if (ctx->macsec_genl_id < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "genl resolve failed"); ++ goto out_free; ++ } ++ ++ memset(&ctx->cb_arg, 0, sizeof(ctx->cb_arg)); ++ ctx->cb_arg.drv = drv; ++ ++ nl_socket_modify_cb(ctx->sk, NL_CB_VALID, NL_CB_CUSTOM, dump_callback, ++ &ctx->cb_arg); ++ ++ return 0; ++ ++out_free: ++ nl_socket_free(ctx->sk); ++ ctx->sk = NULL; ++ return -1; ++} ++ ++ ++static int try_commit(struct macsec_drv_data *drv) ++{ ++ int err; ++ ++ if (!drv->link) ++ return 0; ++ ++ if (drv->controlled_port_enabled_set) { ++ struct rtnl_link *change = rtnl_link_alloc(); ++ ++ if (!change) ++ return -1; ++ ++ rtnl_link_set_name(change, drv->ifname); ++ ++ if (drv->controlled_port_enabled) ++ rtnl_link_set_flags(change, IFF_UP); ++ else ++ rtnl_link_unset_flags(change, IFF_UP); ++ ++ err = rtnl_link_change(drv->sk, change, change, 0); ++ if (err < 0) ++ return err; ++ ++ rtnl_link_put(change); ++ ++ drv->controlled_port_enabled_set = FALSE; ++ } ++ ++ if (drv->protect_frames_set) ++ rtnl_link_macsec_set_protect(drv->link, drv->protect_frames); ++ ++ if (drv->encrypt_set) ++ rtnl_link_macsec_set_encrypt(drv->link, drv->encrypt); ++ ++ if (drv->replay_protect_set) { ++ rtnl_link_macsec_set_replay_protect(drv->link, ++ drv->replay_protect); ++ if (drv->replay_protect) ++ rtnl_link_macsec_set_window(drv->link, ++ drv->replay_window); ++ } ++ ++ if (drv->encoding_sa_set) ++ rtnl_link_macsec_set_encoding_sa(drv->link, drv->encoding_sa); ++ ++ err = rtnl_link_add(drv->sk, drv->link, 0); ++ if (err < 0) ++ return err; ++ ++ drv->protect_frames_set = FALSE; ++ drv->encrypt_set = FALSE; ++ drv->replay_protect_set = FALSE; ++ ++ return 0; ++} ++ ++ ++static void macsec_drv_wpa_deinit(void *priv) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ driver_wired_deinit_common(&drv->common); ++ os_free(drv); ++} ++ ++ ++static void * macsec_drv_wpa_init(void *ctx, const char *ifname) ++{ ++ struct macsec_drv_data *drv; ++ ++ drv = os_zalloc(sizeof(*drv)); ++ if (!drv) ++ return NULL; ++ ++ if (driver_wired_init_common(&drv->common, ifname, ctx) < 0) { ++ os_free(drv); ++ return NULL; ++ } ++ ++ return drv; ++} ++ ++ ++static int macsec_drv_macsec_init(void *priv, struct macsec_init_params *params) ++{ ++ struct macsec_drv_data *drv = priv; ++ int err; ++ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ drv->sk = nl_socket_alloc(); ++ if (!drv->sk) ++ return -1; ++ ++ err = nl_connect(drv->sk, NETLINK_ROUTE); ++ if (err < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX ++ "Unable to connect NETLINK_ROUTE socket: %s", ++ strerror(errno)); ++ goto sock; ++ } ++ ++ err = rtnl_link_alloc_cache(drv->sk, AF_UNSPEC, &drv->link_cache); ++ if (err < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "Unable to get link cache: %s", ++ strerror(errno)); ++ goto sock; ++ } ++ ++ drv->parent_ifi = rtnl_link_name2i(drv->link_cache, drv->common.ifname); ++ if (drv->parent_ifi == 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX ++ "couldn't find ifindex for interface %s", ++ drv->common.ifname); ++ goto cache; ++ } ++ ++ err = init_genl_ctx(drv); ++ if (err < 0) ++ goto cache; ++ ++ return 0; ++ ++cache: ++ nl_cache_free(drv->link_cache); ++ drv->link_cache = NULL; ++sock: ++ nl_socket_free(drv->sk); ++ drv->sk = NULL; ++ return -1; ++} ++ ++ ++static int macsec_drv_macsec_deinit(void *priv) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ if (drv->sk) ++ nl_socket_free(drv->sk); ++ drv->sk = NULL; ++ ++ if (drv->link_cache) ++ nl_cache_free(drv->link_cache); ++ drv->link_cache = NULL; ++ ++ if (drv->ctx.sk) ++ nl_socket_free(drv->ctx.sk); ++ ++ return 0; ++} ++ ++ ++static int macsec_drv_get_capability(void *priv, enum macsec_cap *cap) ++{ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ *cap = MACSEC_CAP_INTEG_AND_CONF; ++ ++ return 0; ++} ++ ++ ++/** ++ * macsec_drv_enable_protect_frames - Set protect frames status ++ * @priv: Private driver interface data ++ * @enabled: TRUE = protect frames enabled ++ * FALSE = protect frames disabled ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_enable_protect_frames(void *priv, Boolean enabled) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); ++ ++ drv->protect_frames_set = TRUE; ++ drv->protect_frames = enabled; ++ ++ return try_commit(drv); ++} ++ ++ ++/** ++ * macsec_drv_enable_encrypt - Set protect frames status ++ * @priv: Private driver interface data ++ * @enabled: TRUE = protect frames enabled ++ * FALSE = protect frames disabled ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_enable_encrypt(void *priv, Boolean enabled) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); ++ ++ drv->encrypt_set = TRUE; ++ drv->encrypt = enabled; ++ ++ return try_commit(drv); ++} ++ ++ ++/** ++ * macsec_drv_set_replay_protect - Set replay protect status and window size ++ * @priv: Private driver interface data ++ * @enabled: TRUE = replay protect enabled ++ * FALSE = replay protect disabled ++ * @window: replay window size, valid only when replay protect enabled ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_set_replay_protect(void *priv, Boolean enabled, ++ u32 window) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %s, %u", __func__, ++ enabled ? "TRUE" : "FALSE", window); ++ ++ drv->replay_protect_set = TRUE; ++ drv->replay_protect = enabled; ++ if (enabled) ++ drv->replay_window = window; ++ ++ return try_commit(drv); ++} ++ ++ ++/** ++ * macsec_drv_set_current_cipher_suite - Set current cipher suite ++ * @priv: Private driver interface data ++ * @cs: EUI64 identifier ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_set_current_cipher_suite(void *priv, u64 cs) ++{ ++ wpa_printf(MSG_DEBUG, "%s -> %016" PRIx64, __func__, cs); ++ return 0; ++} ++ ++ ++/** ++ * macsec_drv_enable_controlled_port - Set controlled port status ++ * @priv: Private driver interface data ++ * @enabled: TRUE = controlled port enabled ++ * FALSE = controlled port disabled ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_enable_controlled_port(void *priv, Boolean enabled) ++{ ++ struct macsec_drv_data *drv = priv; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %s", __func__, enabled ? "TRUE" : "FALSE"); ++ ++ drv->controlled_port_enabled = enabled; ++ drv->controlled_port_enabled_set = TRUE; ++ ++ return try_commit(drv); ++} ++ ++ ++static struct nla_policy sa_policy[MACSEC_SA_ATTR_MAX + 1] = { ++ [MACSEC_SA_ATTR_AN] = { .type = NLA_U8 }, ++ [MACSEC_SA_ATTR_ACTIVE] = { .type = NLA_U8 }, ++ [MACSEC_SA_ATTR_PN] = { .type = NLA_U32 }, ++ [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY }, ++}; ++ ++static struct nla_policy sc_policy[MACSEC_RXSC_ATTR_MAX + 1] = { ++ [MACSEC_RXSC_ATTR_SCI] = { .type = NLA_U64 }, ++ [MACSEC_RXSC_ATTR_ACTIVE] = { .type = NLA_U8 }, ++ [MACSEC_RXSC_ATTR_SA_LIST] = { .type = NLA_NESTED }, ++}; ++ ++static struct nla_policy main_policy[MACSEC_ATTR_MAX + 1] = { ++ [MACSEC_ATTR_IFINDEX] = { .type = NLA_U32 }, ++ [MACSEC_ATTR_SECY] = { .type = NLA_NESTED }, ++ [MACSEC_ATTR_TXSA_LIST] = { .type = NLA_NESTED }, ++ [MACSEC_ATTR_RXSC_LIST] = { .type = NLA_NESTED }, ++}; ++ ++static int dump_callback(struct nl_msg *msg, void *argp) ++{ ++ struct nlmsghdr *ret_hdr = nlmsg_hdr(msg); ++ struct nlattr *tb_msg[MACSEC_ATTR_MAX + 1]; ++ struct cb_arg *arg = (struct cb_arg *) argp; ++ struct genlmsghdr *gnlh = (struct genlmsghdr *) nlmsg_data(ret_hdr); ++ int err; ++ ++ if (ret_hdr->nlmsg_type != arg->drv->ctx.macsec_genl_id) ++ return 0; ++ ++ err = nla_parse(tb_msg, MACSEC_ATTR_MAX, genlmsg_attrdata(gnlh, 0), ++ genlmsg_attrlen(gnlh, 0), main_policy); ++ if (err < 0) ++ return 0; ++ ++ if (!tb_msg[MACSEC_ATTR_IFINDEX]) ++ return 0; ++ ++ if (nla_get_u32(tb_msg[MACSEC_ATTR_IFINDEX]) != (u32) arg->ifindex) ++ return 0; ++ ++ if (arg->txsa < 4 && !tb_msg[MACSEC_ATTR_TXSA_LIST]) { ++ return 0; ++ } else if (arg->txsa < 4) { ++ struct nlattr *nla; ++ int rem; ++ ++ nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_TXSA_LIST], rem) { ++ struct nlattr *tb[MACSEC_SA_ATTR_MAX + 1]; ++ ++ err = nla_parse_nested(tb, MACSEC_SA_ATTR_MAX, nla, ++ sa_policy); ++ if (err < 0) ++ continue; ++ if (!tb[MACSEC_SA_ATTR_AN]) ++ continue; ++ if (nla_get_u8(tb[MACSEC_SA_ATTR_AN]) != arg->txsa) ++ continue; ++ if (!tb[MACSEC_SA_ATTR_PN]) ++ return 0; ++ *arg->pn = nla_get_u32(tb[MACSEC_SA_ATTR_PN]); ++ return 0; ++ } ++ ++ return 0; ++ } ++ ++ if (arg->rxsci == UNUSED_SCI) ++ return 0; ++ ++ if (tb_msg[MACSEC_ATTR_RXSC_LIST]) { ++ struct nlattr *nla; ++ int rem; ++ ++ nla_for_each_nested(nla, tb_msg[MACSEC_ATTR_RXSC_LIST], rem) { ++ struct nlattr *tb[MACSEC_RXSC_ATTR_MAX + 1]; ++ ++ err = nla_parse_nested(tb, MACSEC_RXSC_ATTR_MAX, nla, ++ sc_policy); ++ if (err < 0) ++ return 0; ++ if (!tb[MACSEC_RXSC_ATTR_SCI]) ++ continue; ++ if (nla_get_u64(tb[MACSEC_RXSC_ATTR_SCI]) != arg->rxsci) ++ continue; ++ if (!tb[MACSEC_RXSC_ATTR_SA_LIST]) ++ return 0; ++ ++ nla_for_each_nested(nla, tb[MACSEC_RXSC_ATTR_SA_LIST], ++ rem) { ++ struct nlattr *tb_sa[MACSEC_SA_ATTR_MAX + 1]; ++ ++ err = nla_parse_nested(tb_sa, ++ MACSEC_SA_ATTR_MAX, nla, ++ sa_policy); ++ if (err < 0) ++ continue; ++ if (!tb_sa[MACSEC_SA_ATTR_AN]) ++ continue; ++ if (nla_get_u8(tb_sa[MACSEC_SA_ATTR_AN]) != ++ arg->rxsa) ++ continue; ++ if (!tb_sa[MACSEC_SA_ATTR_PN]) ++ return 0; ++ *arg->pn = ++ nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]); ++ ++ return 0; ++ } ++ ++ return 0; ++ } ++ ++ return 0; ++ } ++ ++ return 0; ++} ++ ++ ++static int nl_send_recv(struct nl_sock *sk, struct nl_msg *msg) ++{ ++ int ret; ++ ++ ret = nl_send_auto_complete(sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to send: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ return ret; ++ } ++ ++ ret = nl_recvmsgs_default(sk); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to recv: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++ return ret; ++} ++ ++ ++static int do_dump(struct macsec_drv_data *drv, u8 txsa, u64 rxsci, u8 rxsa, ++ u32 *pn) ++{ ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ int ret = 1; ++ ++ ctx->cb_arg.ifindex = drv->ifi; ++ ctx->cb_arg.rxsci = rxsci; ++ ctx->cb_arg.rxsa = rxsa; ++ ctx->cb_arg.txsa = txsa; ++ ctx->cb_arg.pn = pn; ++ ++ msg = nlmsg_alloc(); ++ if (!msg) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to alloc message", ++ __func__); ++ return 1; ++ } ++ ++ if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->macsec_genl_id, 0, ++ NLM_F_DUMP, MACSEC_CMD_GET_TXSC, 0)) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "%s: failed to put header", ++ __func__); ++ goto out_free_msg; ++ } ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "failed to communicate: %d (%s)", ++ ret, nl_geterror(-ret)); ++ ++ ctx->cb_arg.pn = 0; ++ ++out_free_msg: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_get_receive_lowest_pn - Get receive lowest PN ++ * @priv: Private driver interface data ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ int err; ++ ++ wpa_printf(MSG_DEBUG, DRV_PREFIX "%s", __func__); ++ ++ err = do_dump(drv, 0xff, mka_sci_u64(&sa->sc->sci), sa->an, ++ &sa->lowest_pn); ++ wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: result %d", __func__, ++ sa->lowest_pn); ++ ++ return err; ++} ++ ++ ++/** ++ * macsec_drv_get_transmit_next_pn - Get transmit next PN ++ * @priv: Private driver interface data ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_get_transmit_next_pn(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ int err; ++ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ err = do_dump(drv, sa->an, UNUSED_SCI, 0xff, &sa->next_pn); ++ wpa_printf(MSG_DEBUG, DRV_PREFIX "%s: err %d result %d", __func__, err, ++ sa->next_pn); ++ return err; ++} ++ ++ ++/** ++ * macsec_drv_set_transmit_next_pn - Set transmit next pn ++ * @priv: Private driver interface data ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_set_transmit_next_pn(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d: %d", __func__, sa->an, sa->next_pn); ++ ++ msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); ++ NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "failed to communicate: %d (%s)", ++ ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++#define SCISTR MACSTR "::%hx" ++#define SCI2STR(addr, port) MAC2STR(addr), htons(port) ++ ++/** ++ * macsec_drv_create_receive_sc - Create secure channel for receiving ++ * @priv: Private driver interface data ++ * @sc: secure channel ++ * @sci_addr: secure channel identifier - address ++ * @sci_port: secure channel identifier - port ++ * @conf_offset: confidentiality offset (0, 30, or 50) ++ * @validation: frame validation policy (0 = Disabled, 1 = Checked, ++ * 2 = Strict) ++ * Returns: 0 on success, -1 on failure (or if not supported) ++ */ ++static int macsec_drv_create_receive_sc(void *priv, struct receive_sc *sc, ++ unsigned int conf_offset, ++ int validation) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__, ++ SCI2STR(sc->sci.addr, sc->sci.port)); ++ ++ msg = msg_prepare(MACSEC_CMD_ADD_RXSC, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci))) ++ goto nla_put_failure; ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_delete_receive_sc - Delete secure connection for receiving ++ * @priv: private driver interface data from init() ++ * @sc: secure channel ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_delete_receive_sc(void *priv, struct receive_sc *sc) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> " SCISTR, __func__, ++ SCI2STR(sc->sci.addr, sc->sci.port)); ++ ++ msg = msg_prepare(MACSEC_CMD_DEL_RXSC, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ if (nla_put_rxsc_config(msg, mka_sci_u64(&sc->sci))) ++ goto nla_put_failure; ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_create_receive_sa - Create secure association for receive ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_create_receive_sa(void *priv, struct receive_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, ++ SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); ++ ++ msg = msg_prepare(MACSEC_CMD_ADD_RXSA, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci))) ++ goto nla_put_failure; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_receive); ++ NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); ++ NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier), ++ &sa->pkey->key_identifier); ++ NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_delete_receive_sa - Delete secure association for receive ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_delete_receive_sa(void *priv, struct receive_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, ++ SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); ++ ++ msg = msg_prepare(MACSEC_CMD_DEL_RXSA, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ if (nla_put_rxsc_config(msg, mka_sci_u64(&sa->sc->sci))) ++ goto nla_put_failure; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++static int set_active_rx_sa(const struct macsec_genl_ctx *ctx, int ifindex, ++ u64 sci, unsigned char an, Boolean state) ++{ ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ msg = msg_prepare(MACSEC_CMD_UPD_RXSA, ctx, ifindex); ++ if (!msg) ++ return ret; ++ ++ if (nla_put_rxsc_config(msg, sci)) ++ goto nla_put_failure; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an); ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_enable_receive_sa - Enable the SA for receive ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_enable_receive_sa(void *priv, struct receive_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, ++ SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); ++ ++ return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci), ++ sa->an, TRUE); ++} ++ ++ ++/** ++ * macsec_drv_disable_receive_sa - Disable SA for receive ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_disable_receive_sa(void *priv, struct receive_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d on " SCISTR, __func__, sa->an, ++ SCI2STR(sa->sc->sci.addr, sa->sc->sci.port)); ++ ++ return set_active_rx_sa(ctx, drv->ifi, mka_sci_u64(&sa->sc->sci), ++ sa->an, FALSE); ++} ++ ++ ++static struct rtnl_link * lookup_sc(struct nl_cache *cache, int parent, u64 sci) ++{ ++ struct rtnl_link *needle; ++ void *match; ++ ++ needle = rtnl_link_macsec_alloc(); ++ if (!needle) ++ return NULL; ++ ++ rtnl_link_set_link(needle, parent); ++ rtnl_link_macsec_set_sci(needle, sci); ++ ++ match = nl_cache_find(cache, (struct nl_object *) needle); ++ rtnl_link_put(needle); ++ ++ return (struct rtnl_link *) match; ++} ++ ++ ++/** ++ * macsec_drv_create_transmit_sc - Create secure connection for transmit ++ * @priv: private driver interface data from init() ++ * @sc: secure channel ++ * @conf_offset: confidentiality offset ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_create_transmit_sc( ++ void *priv, struct transmit_sc *sc, ++ enum confidentiality_offset conf_offset) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct rtnl_link *link; ++ char *ifname; ++ u64 sci; ++ int err; ++ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ link = rtnl_link_macsec_alloc(); ++ if (!link) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link"); ++ return -1; ++ } ++ ++ rtnl_link_set_link(link, drv->parent_ifi); ++ ++ sci = mka_sci_u64(&sc->sci); ++ rtnl_link_macsec_set_sci(link, sci); ++ ++ drv->created_link = TRUE; ++ ++ err = rtnl_link_add(drv->sk, link, NLM_F_CREATE); ++ if (err == -NLE_BUSY) { ++ wpa_printf(MSG_INFO, ++ DRV_PREFIX "link already exists, using it"); ++ drv->created_link = FALSE; ++ } else if (err < 0) { ++ rtnl_link_put(link); ++ wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't create link: err %d", ++ err); ++ return err; ++ } ++ ++ rtnl_link_put(link); ++ ++ nl_cache_refill(drv->sk, drv->link_cache); ++ link = lookup_sc(drv->link_cache, drv->parent_ifi, sci); ++ if (!link) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't find link"); ++ return -1; ++ } ++ ++ drv->ifi = rtnl_link_get_ifindex(link); ++ ifname = rtnl_link_get_name(link); ++ os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); ++ rtnl_link_put(link); ++ ++ drv->link = rtnl_link_macsec_alloc(); ++ if (!drv->link) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link"); ++ return -1; ++ } ++ ++ rtnl_link_set_name(drv->link, drv->ifname); ++ ++ /* In case some settings have already been done but we couldn't apply ++ * them. */ ++ return try_commit(drv); ++} ++ ++ ++/** ++ * macsec_drv_delete_transmit_sc - Delete secure connection for transmit ++ * @priv: private driver interface data from init() ++ * @sc: secure channel ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc) ++{ ++ struct macsec_drv_data *drv = priv; ++ int err; ++ ++ wpa_printf(MSG_DEBUG, "%s", __func__); ++ ++ if (!drv->created_link) { ++ rtnl_link_put(drv->link); ++ drv->link = NULL; ++ wpa_printf(MSG_DEBUG, DRV_PREFIX ++ "we didn't create the link, leave it alone"); ++ return 0; ++ } ++ ++ err = rtnl_link_delete(drv->sk, drv->link); ++ if (err < 0) ++ wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't delete link"); ++ rtnl_link_put(drv->link); ++ drv->link = NULL; ++ ++ return err; ++} ++ ++ ++/** ++ * macsec_drv_create_transmit_sa - Create secure association for transmit ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_create_transmit_sa(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); ++ ++ msg = msg_prepare(MACSEC_CMD_ADD_TXSA, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); ++ NLA_PUT_U32(msg, MACSEC_SA_ATTR_PN, sa->next_pn); ++ NLA_PUT(msg, MACSEC_SA_ATTR_KEYID, sizeof(sa->pkey->key_identifier), ++ &sa->pkey->key_identifier); ++ NLA_PUT(msg, MACSEC_SA_ATTR_KEY, sa->pkey->key_len, sa->pkey->key); ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, sa->enable_transmit); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_delete_transmit_sa - Delete secure association for transmit ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_delete_transmit_sa(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); ++ ++ msg = msg_prepare(MACSEC_CMD_DEL_TXSA, ctx, drv->ifi); ++ if (!msg) ++ return ret; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, sa->an); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++static int set_active_tx_sa(const struct macsec_genl_ctx *ctx, int ifindex, ++ unsigned char an, Boolean state) ++{ ++ struct nl_msg *msg; ++ struct nlattr *nest; ++ int ret = -1; ++ ++ msg = msg_prepare(MACSEC_CMD_UPD_TXSA, ctx, ifindex); ++ if (!msg) ++ return ret; ++ ++ nest = nla_nest_start(msg, MACSEC_ATTR_SA_CONFIG); ++ if (!nest) ++ goto nla_put_failure; ++ ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_AN, an); ++ NLA_PUT_U8(msg, MACSEC_SA_ATTR_ACTIVE, !!state); ++ ++ nla_nest_end(msg, nest); ++ ++ ret = nl_send_recv(ctx->sk, msg); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, ++ DRV_PREFIX "%s: failed to communicate: %d (%s)", ++ __func__, ret, nl_geterror(-ret)); ++ } ++ ++nla_put_failure: ++ nlmsg_free(msg); ++ return ret; ++} ++ ++ ++/** ++ * macsec_drv_enable_transmit_sa - Enable SA for transmit ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_enable_transmit_sa(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ int ret; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); ++ ++ ret = set_active_tx_sa(ctx, drv->ifi, sa->an, TRUE); ++ if (ret < 0) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "failed to enable txsa"); ++ return ret; ++ } ++ ++ drv->encoding_sa_set = TRUE; ++ drv->encoding_sa = sa->an; ++ ++ return try_commit(drv); ++} ++ ++ ++/** ++ * macsec_drv_disable_transmit_sa - Disable SA for transmit ++ * @priv: private driver interface data from init() ++ * @sa: secure association ++ * Returns: 0 on success, -1 on failure ++ */ ++static int macsec_drv_disable_transmit_sa(void *priv, struct transmit_sa *sa) ++{ ++ struct macsec_drv_data *drv = priv; ++ struct macsec_genl_ctx *ctx = &drv->ctx; ++ ++ wpa_printf(MSG_DEBUG, "%s -> %d", __func__, sa->an); ++ ++ return set_active_tx_sa(ctx, drv->ifi, sa->an, FALSE); ++} ++ ++ ++const struct wpa_driver_ops wpa_driver_macsec_linux_ops = { ++ .name = "macsec_linux", ++ .desc = "MACsec Ethernet driver for Linux", ++ .get_ssid = driver_wired_get_ssid, ++ .get_bssid = driver_wired_get_bssid, ++ .get_capa = driver_wired_get_capa, ++ .init = macsec_drv_wpa_init, ++ .deinit = macsec_drv_wpa_deinit, ++ ++ .macsec_init = macsec_drv_macsec_init, ++ .macsec_deinit = macsec_drv_macsec_deinit, ++ .macsec_get_capability = macsec_drv_get_capability, ++ .enable_protect_frames = macsec_drv_enable_protect_frames, ++ .enable_encrypt = macsec_drv_enable_encrypt, ++ .set_replay_protect = macsec_drv_set_replay_protect, ++ .set_current_cipher_suite = macsec_drv_set_current_cipher_suite, ++ .enable_controlled_port = macsec_drv_enable_controlled_port, ++ .get_receive_lowest_pn = macsec_drv_get_receive_lowest_pn, ++ .get_transmit_next_pn = macsec_drv_get_transmit_next_pn, ++ .set_transmit_next_pn = macsec_drv_set_transmit_next_pn, ++ .create_receive_sc = macsec_drv_create_receive_sc, ++ .delete_receive_sc = macsec_drv_delete_receive_sc, ++ .create_receive_sa = macsec_drv_create_receive_sa, ++ .delete_receive_sa = macsec_drv_delete_receive_sa, ++ .enable_receive_sa = macsec_drv_enable_receive_sa, ++ .disable_receive_sa = macsec_drv_disable_receive_sa, ++ .create_transmit_sc = macsec_drv_create_transmit_sc, ++ .delete_transmit_sc = macsec_drv_delete_transmit_sc, ++ .create_transmit_sa = macsec_drv_create_transmit_sa, ++ .delete_transmit_sa = macsec_drv_delete_transmit_sa, ++ .enable_transmit_sa = macsec_drv_enable_transmit_sa, ++ .disable_transmit_sa = macsec_drv_disable_transmit_sa, ++}; +diff --git a/src/drivers/drivers.c b/src/drivers/drivers.c +index 00773a7..e95df6d 100644 +--- a/src/drivers/drivers.c ++++ b/src/drivers/drivers.c +@@ -34,6 +34,9 @@ const struct wpa_driver_ops *const wpa_drivers[] = + #ifdef CONFIG_DRIVER_WIRED + &wpa_driver_wired_ops, + #endif /* CONFIG_DRIVER_WIRED */ ++#ifdef CONFIG_DRIVER_MACSEC_LINUX ++ &wpa_driver_macsec_linux_ops, ++#endif /* CONFIG_DRIVER_MACSEC_LINUX */ + #ifdef CONFIG_DRIVER_MACSEC_QCA + &wpa_driver_macsec_qca_ops, + #endif /* CONFIG_DRIVER_MACSEC_QCA */ +diff --git a/src/drivers/drivers.mak b/src/drivers/drivers.mak +index 282da50..1496b47 100644 +--- a/src/drivers/drivers.mak ++++ b/src/drivers/drivers.mak +@@ -18,6 +18,13 @@ DRV_OBJS += ../src/drivers/driver_wired.o + NEED_DRV_WIRED_COMMON=1 + endif + ++ifdef CONFIG_DRIVER_MACSEC_LINUX ++DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_LINUX ++DRV_OBJS += ../src/drivers/driver_macsec_linux.o ++NEED_DRV_WIRED_COMMON=1 ++CONFIG_LIBNL3_ROUTE=y ++endif ++ + ifdef CONFIG_DRIVER_MACSEC_QCA + DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_QCA + DRV_OBJS += ../src/drivers/driver_macsec_qca.o +diff --git a/src/drivers/drivers.mk b/src/drivers/drivers.mk +index 508f834..cd25133 100644 +--- a/src/drivers/drivers.mk ++++ b/src/drivers/drivers.mk +@@ -18,6 +18,13 @@ DRV_OBJS += src/drivers/driver_wired.c + NEED_DRV_WIRED_COMMON=1 + endif + ++ifdef CONFIG_DRIVER_MACSEC_LINUX ++DRV_CFLAGS += -DCONFIG_DRIVER_MACSEC_LINUX ++DRV_OBJS += src/drivers/driver_macsec_linux.c ++NEED_DRV_WIRED_COMMON=1 ++CONFIG_LIBNL3_ROUTE=y ++endif ++ + ifdef NEED_DRV_WIRED_COMMON + DRV_OBJS += src/drivers/driver_wired_common.c + endif +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 3a495ca..1d6d9a9 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -379,6 +379,17 @@ ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant, + } + + ++u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci) ++{ ++ struct ieee802_1x_mka_sci tmp; ++ ++ os_memcpy(tmp.addr, sci->addr, ETH_ALEN); ++ tmp.port = sci->port; ++ ++ return *((u64 *) &tmp); ++} ++ ++ + static Boolean sci_equal(const struct ieee802_1x_mka_sci *a, + const struct ieee802_1x_mka_sci *b) + { +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index ea5a0dd..9a92d1c 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -231,6 +231,8 @@ struct ieee802_1x_kay { + }; + + ++u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci); ++ + struct ieee802_1x_kay * + ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + u16 port, const char *ifname, const u8 *addr); +-- +2.7.4 + diff --git a/SOURCES/macsec-0030-mka-Remove-references-to-macsec_qca-from-wpa_supplic.patch b/SOURCES/macsec-0030-mka-Remove-references-to-macsec_qca-from-wpa_supplic.patch new file mode 100644 index 0000000..8822602 --- /dev/null +++ b/SOURCES/macsec-0030-mka-Remove-references-to-macsec_qca-from-wpa_supplic.patch @@ -0,0 +1,49 @@ +From ba5ea116873a2f4046e4d3f37ab8215a3846f614 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Sabrina Dubroca +Date: Sun, 27 Nov 2016 20:08:56 +0100 +Subject: [PATCH] mka: Remove references to macsec_qca from wpa_supplicant.conf + +Make the documentation generic, as this is no longer the only macsec +driver. + +Signed-off-by: Sabrina Dubroca +--- + wpa_supplicant/wpa_supplicant.conf | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index 82aa24e..edb230d 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -98,9 +98,7 @@ eapol_version=1 + # parameters (e.g., WPA IE generation); this mode can also be used with + # non-WPA drivers when using IEEE 802.1X mode; do not try to associate with + # APs (i.e., external program needs to control association). This mode must +-# also be used when using wired Ethernet drivers. +-# Note: macsec_qca driver is one type of Ethernet driver which implements +-# macsec feature. ++# also be used when using wired Ethernet drivers (including MACsec). + # 2: like 0, but associate with APs using security policy and SSID (but not + # BSSID); this can be used, e.g., with ndiswrapper and NDIS drivers to + # enable operation with hidden SSIDs and optimized roaming; in this mode, +@@ -881,13 +879,13 @@ fast_reauth=1 + # bit0 (1): require dynamically generated unicast WEP key + # bit1 (2): require dynamically generated broadcast WEP key + # (3 = require both keys; default) +-# Note: When using wired authentication (including macsec_qca driver), ++# Note: When using wired authentication (including MACsec drivers), + # eapol_flags must be set to 0 for the authentication to be completed + # successfully. + # + # macsec_policy: IEEE 802.1X/MACsec options +-# This determines how sessions are secured with MACsec. It is currently +-# applicable only when using the macsec_qca driver interface. ++# 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. +-- +2.7.4 + diff --git a/SOURCES/macsec-0031-PAE-Make-KaY-specific-details-available-via-control-.patch b/SOURCES/macsec-0031-PAE-Make-KaY-specific-details-available-via-control-.patch new file mode 100644 index 0000000..2263315 --- /dev/null +++ b/SOURCES/macsec-0031-PAE-Make-KaY-specific-details-available-via-control-.patch @@ -0,0 +1,120 @@ +From 7508c2ad99cef6d0691190063ec7735b7759f836 Mon Sep 17 00:00:00 2001 +Message-Id: <7508c2ad99cef6d0691190063ec7735b7759f836.1488376602.git.dcaratti@redhat.com> +From: Badrish Adiga H R +Date: Fri, 16 Dec 2016 01:40:53 +0530 +Subject: [PATCH] PAE: Make KaY specific details available via control + interface + +Add KaY details to the STATUS command output. + +Signed-off-by: Badrish Adiga H R +--- + src/pae/ieee802_1x_kay.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ + src/pae/ieee802_1x_kay.h | 3 +++ + wpa_supplicant/ctrl_iface.c | 6 ++++++ + 3 files changed, 58 insertions(+) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 1d6d9a9..cf5782a 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -1641,6 +1641,7 @@ ieee802_1x_mka_decode_dist_sak_body( + ieee802_1x_cp_signal_newsak(kay->cp); + ieee802_1x_cp_sm_step(kay->cp); + ++ kay->rcvd_keys++; + participant->to_use_sak = TRUE; + + return 0; +@@ -3519,3 +3520,51 @@ ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, + + return 0; + } ++ ++ ++#ifdef CONFIG_CTRL_IFACE ++/** ++ * ieee802_1x_kay_get_status - Get IEEE 802.1X KaY status details ++ * @sm: Pointer to KaY allocated with ieee802_1x_kay_init() ++ * @buf: Buffer for status information ++ * @buflen: Maximum buffer length ++ * @verbose: Whether to include verbose status information ++ * Returns: Number of bytes written to buf. ++ * ++ * Query KAY status information. This function fills in a text area with current ++ * status information. If the buffer (buf) is not large enough, status ++ * information will be truncated to fit the buffer. ++ */ ++int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf, ++ size_t buflen) ++{ ++ int len; ++ ++ if (!kay) ++ return 0; ++ ++ len = os_snprintf(buf, buflen, ++ "PAE KaY status=%s\n" ++ "Authenticated=%s\n" ++ "Secured=%s\n" ++ "Failed=%s\n" ++ "Actor Priority=%u\n" ++ "Key Server Priority=%u\n" ++ "Is Key Server=%s\n" ++ "Number of Keys Distributed=%u\n" ++ "Number of Keys Received=%u\n", ++ kay->active ? "Active" : "Not-Active", ++ kay->authenticated ? "Yes" : "No", ++ kay->secured ? "Yes" : "No", ++ kay->failed ? "Yes" : "No", ++ kay->actor_priority, ++ kay->key_server_priority, ++ kay->is_key_server ? "Yes" : "No", ++ kay->dist_kn - 1, ++ kay->rcvd_keys); ++ if (os_snprintf_error(buflen, len)) ++ return 0; ++ ++ return len; ++} ++#endif /* CONFIG_CTRL_IFACE */ +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index 9a92d1c..b38e814 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -208,6 +208,7 @@ struct ieee802_1x_kay { + int mka_algindex; /* MKA alg table index */ + + u32 dist_kn; ++ u32 rcvd_keys; + u8 dist_an; + time_t dist_time; + +@@ -267,5 +268,7 @@ int ieee802_1x_kay_enable_tx_sas(struct ieee802_1x_kay *kay, + int ieee802_1x_kay_enable_rx_sas(struct ieee802_1x_kay *kay, + struct ieee802_1x_mka_ki *lki); + int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay); ++int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf, ++ size_t buflen); + + #endif /* IEEE802_1X_KAY_H */ +diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c +index c943dee..624e894 100644 +--- a/wpa_supplicant/ctrl_iface.c ++++ b/wpa_supplicant/ctrl_iface.c +@@ -2050,6 +2050,12 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s, + pos += res; + } + ++#ifdef CONFIG_MACSEC ++ res = ieee802_1x_kay_get_status(wpa_s->kay, pos, end - pos); ++ if (res > 0) ++ pos += res; ++#endif /* CONFIG_MACSEC */ ++ + sess_id = eapol_sm_get_session_id(wpa_s->eapol, &sess_id_len); + if (sess_id) { + char *start = pos; +-- +2.7.4 + diff --git a/SOURCES/macsec-0032-mka-Make-MKA-actor-priority-configurable.patch b/SOURCES/macsec-0032-mka-Make-MKA-actor-priority-configurable.patch new file mode 100644 index 0000000..5c22764 --- /dev/null +++ b/SOURCES/macsec-0032-mka-Make-MKA-actor-priority-configurable.patch @@ -0,0 +1,176 @@ +From 65dfa872862641c17e4f6276c56fad0a6c18d219 Mon Sep 17 00:00:00 2001 +Message-Id: <65dfa872862641c17e4f6276c56fad0a6c18d219.1488376602.git.dcaratti@redhat.com> +From: Badrish Adiga H R +Date: Mon, 5 Dec 2016 06:53:55 -0800 +Subject: [PATCH] mka: Make MKA actor priority configurable + +This adds a new wpa_supplicant network profile parameter +mka_priority=0..255 to set the priority of the MKA Actor. + +Signed-off-by: Badrish Adiga H R +--- + src/pae/ieee802_1x_kay.c | 4 ++-- + src/pae/ieee802_1x_kay.h | 2 +- + wpa_supplicant/config.c | 5 +++++ + wpa_supplicant/config_file.c | 2 ++ + wpa_supplicant/config_ssid.h | 7 +++++++ + wpa_supplicant/wpa_cli.c | 1 + + wpa_supplicant/wpa_supplicant.conf | 8 +++++--- + wpa_supplicant/wpas_kay.c | 3 ++- + 8 files changed, 25 insertions(+), 7 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index cf5782a..1004b32 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3083,7 +3083,7 @@ static void kay_l2_receive(void *ctx, const u8 *src_addr, const u8 *buf, + */ + struct ieee802_1x_kay * + ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, +- u16 port, const char *ifname, const u8 *addr) ++ u16 port, u8 priority, const char *ifname, const u8 *addr) + { + struct ieee802_1x_kay *kay; + +@@ -3106,7 +3106,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + os_strlcpy(kay->if_name, ifname, IFNAMSIZ); + os_memcpy(kay->actor_sci.addr, addr, ETH_ALEN); + kay->actor_sci.port = host_to_be16(port ? port : 0x0001); +- kay->actor_priority = DEFAULT_PRIO_NOT_KEY_SERVER; ++ kay->actor_priority = priority; + + /* While actor acts as a key server, shall distribute sakey */ + kay->dist_kn = 1; +diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h +index b38e814..8f394fd 100644 +--- a/src/pae/ieee802_1x_kay.h ++++ b/src/pae/ieee802_1x_kay.h +@@ -236,7 +236,7 @@ u64 mka_sci_u64(struct ieee802_1x_mka_sci *sci); + + struct ieee802_1x_kay * + ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, +- u16 port, const char *ifname, const u8 *addr); ++ u16 port, u8 priority, const char *ifname, const u8 *addr); + void ieee802_1x_kay_deinit(struct ieee802_1x_kay *kay); + + struct ieee802_1x_mka_participant * +diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c +index 2120a6e..2a26d2d 100644 +--- a/wpa_supplicant/config.c ++++ b/wpa_supplicant/config.c +@@ -11,6 +11,7 @@ + #include "common.h" + #include "utils/uuid.h" + #include "utils/ip_addr.h" ++#include "common/ieee802_1x_defs.h" + #include "crypto/sha1.h" + #include "rsn_supp/wpa.h" + #include "eap_peer/eap.h" +@@ -2127,6 +2128,7 @@ static const struct parse_data ssid_fields[] = { + { INT_RANGE(macsec_policy, 0, 1) }, + { INT_RANGE(macsec_integ_only, 0, 1) }, + { INT_RANGE(macsec_port, 1, 65534) }, ++ { INT_RANGE(mka_priority, 0, 255) }, + { FUNC_KEY(mka_cak) }, + { FUNC_KEY(mka_ckn) }, + #endif /* CONFIG_MACSEC */ +@@ -2617,6 +2619,9 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid) + #ifdef CONFIG_IEEE80211W + ssid->ieee80211w = MGMT_FRAME_PROTECTION_DEFAULT; + #endif /* CONFIG_IEEE80211W */ ++#ifdef CONFIG_MACSEC ++ ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER; ++#endif /* CONFIG_MACSEC */ + ssid->mac_addr = -1; + } + +diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c +index b9b1d4d..98e3591 100644 +--- a/wpa_supplicant/config_file.c ++++ b/wpa_supplicant/config_file.c +@@ -19,6 +19,7 @@ + #include "config.h" + #include "base64.h" + #include "uuid.h" ++#include "common/ieee802_1x_defs.h" + #include "p2p/p2p.h" + #include "eap_peer/eap_methods.h" + #include "eap_peer/eap.h" +@@ -813,6 +814,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) + write_mka_ckn(f, ssid); + INT(macsec_integ_only); + INT(macsec_port); ++ INT_DEF(mka_priority, DEFAULT_PRIO_NOT_KEY_SERVER); + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + INT(update_identifier); +diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h +index fe0f7fa..69ace37 100644 +--- a/wpa_supplicant/config_ssid.h ++++ b/wpa_supplicant/config_ssid.h +@@ -751,6 +751,13 @@ struct wpa_ssid { + 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_LEN 32 +diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c +index f11028a..21adc17 100644 +--- a/wpa_supplicant/wpa_cli.c ++++ b/wpa_supplicant/wpa_cli.c +@@ -1392,6 +1392,7 @@ static const char *network_fields[] = { + "macsec_policy", + "macsec_integ_only", + "macsec_port", ++ "mka_priority", + #endif /* CONFIG_MACSEC */ + #ifdef CONFIG_HS20 + "update_identifier", +diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf +index edb230d..94cef4a 100644 +--- a/wpa_supplicant/wpa_supplicant.conf ++++ b/wpa_supplicant/wpa_supplicant.conf +@@ -901,13 +901,15 @@ fast_reauth=1 + # Port component of the SCI + # Range: 1-65534 (default: 1) + # +-# mka_cak and mka_ckn: IEEE 802.1X/MACsec pre-shared authentication mode ++# 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 wpa_supplicant can act as peers, one of +-# which will become the key server and start distributing SAKs. ++# In this mode, instances of wpa_supplicant 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-bytes (128 bit) + # hex-string (32 hex-digits) + # mka_ckn (CKN = CAK Name) takes a 32-bytes (256 bit) hex-string (64 hex-digits) ++# mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being ++# default priority + # + # mixed_cell: This option can be used to configure whether so called mixed + # cells, i.e., networks that use both plaintext and encryption in the same +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index d3fefda..d087e00 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -233,7 +233,8 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + kay_ctx->disable_transmit_sa = wpas_disable_transmit_sa; + + res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_port, +- wpa_s->ifname, wpa_s->own_addr); ++ ssid->mka_priority, wpa_s->ifname, ++ wpa_s->own_addr); + if (res == NULL) { + os_free(kay_ctx); + return -1; +-- +2.7.4 + diff --git a/SOURCES/macsec-0033-mka-Fix-an-incorrect-update-of-participant-to_use_sa.patch b/SOURCES/macsec-0033-mka-Fix-an-incorrect-update-of-participant-to_use_sa.patch new file mode 100644 index 0000000..a7c28c3 --- /dev/null +++ b/SOURCES/macsec-0033-mka-Fix-an-incorrect-update-of-participant-to_use_sa.patch @@ -0,0 +1,34 @@ +From 7faf403f9fb39fea9a0545025cc284ef05e022a7 Mon Sep 17 00:00:00 2001 +Message-Id: <7faf403f9fb39fea9a0545025cc284ef05e022a7.1488376602.git.dcaratti@redhat.com> +From: Badrish Adiga H R +Date: Fri, 6 Jan 2017 17:47:51 +0530 +Subject: [PATCH] mka: Fix an incorrect update of participant->to_use_sak + +API ieee802_1x_mka_decode_dist_sak_body() wrongly puts +participant->to_use_sak to TRUE, if Distributed SAK Parameter Set of +length 0 is received. In MACsec PSK mode, this stale incorrect value can +create problems while re-establishing CA. In MACsec PSK mode, CA goes +down if interface goes down and ideally we should be able to +re-establish the CA once interface comes up. + +Signed-off-by: Badrish Adiga H R +--- + src/pae/ieee802_1x_kay.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 1004b32..79a6878 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -1559,7 +1559,7 @@ ieee802_1x_mka_decode_dist_sak_body( + ieee802_1x_cp_connect_authenticated(kay->cp); + ieee802_1x_cp_sm_step(kay->cp); + wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec"); +- participant->to_use_sak = TRUE; ++ participant->to_use_sak = FALSE; + return 0; + } + +-- +2.7.4 + diff --git a/SOURCES/macsec-0034-mka-Some-bug-fixes-for-MACsec-in-PSK-mode.patch b/SOURCES/macsec-0034-mka-Some-bug-fixes-for-MACsec-in-PSK-mode.patch new file mode 100644 index 0000000..71dc4fe --- /dev/null +++ b/SOURCES/macsec-0034-mka-Some-bug-fixes-for-MACsec-in-PSK-mode.patch @@ -0,0 +1,51 @@ +From e54691106b29f41aa3081b00eb4f48e411cebc72 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Badrish Adiga H R +Date: Fri, 6 Jan 2017 15:27:10 +0530 +Subject: [PATCH] mka: Some bug fixes for MACsec in PSK mode + +Issue: +------ +The test setup has 2 peers running MACsec in PSK mode, Peer A with +MAC address higher than MAC Address of peer B. Test sequence is +1. Peer B starts with actor_priority 255 +2. Peer A starts with priority 16, becomes key server. +3. Peer A stops.. +4. Peer A restarts with priority 255, but because of the stale values +participant->is_key_server(=TRUE) and participant->is_elected(=TRUE) +it continues to remain as Key Server. +5. For peer B, key server election happens and since it has lower MAC +address as compared to MAC address of A, it becomes the key server. +Now we have 2 key servers in CA and is not correct. + +Root-cause & fix: +----------------- +When number of live peers become 0, the flags such lrx, ltx, orx, +otx, etc. need to be cleared. In MACsec PSK mode, these stale values +create problems while re-establishing CA. + +Signed-off-by: Badrish Adiga H R +--- + src/pae/ieee802_1x_kay.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 79a6878..92fd7ba 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -2378,6 +2378,12 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) + participant->advised_capability = + MACSEC_CAP_NOT_IMPLEMENTED; + participant->to_use_sak = FALSE; ++ participant->ltx = FALSE; ++ participant->lrx = FALSE; ++ participant->otx = FALSE; ++ participant->orx = FALSE; ++ participant->is_key_server = FALSE; ++ participant->is_elected = FALSE; + kay->authenticated = TRUE; + kay->secured = FALSE; + kay->failed = FALSE; +-- +2.7.4 + diff --git a/SOURCES/macsec-0035-mka-Send-MKPDUs-forever-if-mode-is-PSK.patch b/SOURCES/macsec-0035-mka-Send-MKPDUs-forever-if-mode-is-PSK.patch new file mode 100644 index 0000000..3ee3ab5 --- /dev/null +++ b/SOURCES/macsec-0035-mka-Send-MKPDUs-forever-if-mode-is-PSK.patch @@ -0,0 +1,70 @@ +From 37e9f511eb0072dbce190cb21e2d48f022173b03 Mon Sep 17 00:00:00 2001 +Message-Id: <37e9f511eb0072dbce190cb21e2d48f022173b03.1488376602.git.dcaratti@redhat.com> +From: Badrish Adiga H R +Date: Tue, 7 Feb 2017 14:28:31 +0530 +Subject: [PATCH] mka: Send MKPDUs forever if mode is PSK + +Issue: When 2 peers are running MACsec in PSK mode with CA +established, if the interface goes down and comes up after +time > 10 seconds, CA does not get re-established. + +Root cause: This is because retry_count of both the peers +would have reached MAX_RETRY_CNT and stays idle for other to +respond. This is clear deadlock situation where peer A waits +for MKA packets from peer B to wake up and vice-versa. + +Fix: If MACsec is running in PSK mode, we should send MKPDUs +forever for every 2 seconds. + +Signed-off-by: Badrish Adiga H R +--- + src/pae/ieee802_1x_kay.c | 6 ++++-- + src/pae/ieee802_1x_kay_i.h | 1 + + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index 92fd7ba..e420fc1 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -2428,7 +2428,8 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx) + participant->new_sak = FALSE; + } + +- if (participant->retry_count < MAX_RETRY_CNT) { ++ if (participant->retry_count < MAX_RETRY_CNT || ++ participant->mode == PSK) { + ieee802_1x_participant_send_mkpdu(participant); + participant->retry_count++; + } +@@ -2828,7 +2829,7 @@ int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay) + if (!principal) + return -1; + +- if (principal->retry_count < MAX_RETRY_CNT) { ++ if (principal->retry_count < MAX_RETRY_CNT || principal->mode == PSK) { + ieee802_1x_participant_send_mkpdu(principal); + principal->retry_count++; + } +@@ -3368,6 +3369,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn, + participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) + + usecs / 1000000; + } ++ participant->mode = mode; + + return participant; + +diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h +index 0c4bb8e..bc522d8 100644 +--- a/src/pae/ieee802_1x_kay_i.h ++++ b/src/pae/ieee802_1x_kay_i.h +@@ -93,6 +93,7 @@ struct ieee802_1x_mka_participant { + Boolean active; + Boolean participant; + Boolean retain; ++ enum mka_created_mode mode; + + enum { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate; + +-- +2.7.4 + diff --git a/SOURCES/rh1434434-wpa_supplicant-Don-t-reply-to-EAPOL-if-pkt_type-is-P.patch b/SOURCES/rh1434434-wpa_supplicant-Don-t-reply-to-EAPOL-if-pkt_type-is-P.patch new file mode 100644 index 0000000..205b4b8 --- /dev/null +++ b/SOURCES/rh1434434-wpa_supplicant-Don-t-reply-to-EAPOL-if-pkt_type-is-P.patch @@ -0,0 +1,96 @@ +From d89edb6112f54fb65036c31eba291bda5fcad2b3 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Davide Caratti +Date: Wed, 28 Mar 2018 16:34:56 +0200 +Subject: [PATCH] wpa_supplicant: Don't reply to EAPOL if pkt_type is + PACKET_OTHERHOST + +When wpa_supplicant is running on a Linux interface that is configured in +promiscuous mode, and it is not a member of a bridge, incoming EAPOL +packets are processed regardless of the Destination Address in the frame. +As a consequence, there are situations where wpa_supplicant replies to +EAPOL packets that are not destined for it. + +This behavior seems undesired (see IEEE Std 802.1X-2010, 11.4.a), and can +be avoided by attaching a BPF filter that lets the kernel discard packets +having pkt_type equal to PACKET_OTHERHOST. + +Signed-off-by: Davide Caratti +--- + src/l2_packet/l2_packet.h | 1 + + src/l2_packet/l2_packet_linux.c | 23 +++++++++++++++++++++++ + wpa_supplicant/wpa_supplicant.c | 5 +++++ + 3 files changed, 29 insertions(+) + +diff --git a/src/l2_packet/l2_packet.h b/src/l2_packet/l2_packet.h +index 2a4524582..53871774b 100644 +--- a/src/l2_packet/l2_packet.h ++++ b/src/l2_packet/l2_packet.h +@@ -42,6 +42,7 @@ struct l2_ethhdr { + enum l2_packet_filter_type { + L2_PACKET_FILTER_DHCP, + L2_PACKET_FILTER_NDISC, ++ L2_PACKET_FILTER_PKTTYPE, + }; + + /** +diff --git a/src/l2_packet/l2_packet_linux.c b/src/l2_packet/l2_packet_linux.c +index 65b490679..291c9dd26 100644 +--- a/src/l2_packet/l2_packet_linux.c ++++ b/src/l2_packet/l2_packet_linux.c +@@ -84,6 +84,26 @@ static const struct sock_fprog ndisc_sock_filter = { + .filter = ndisc_sock_filter_insns, + }; + ++/* drop packet if skb->pkt_type is PACKET_OTHERHOST (0x03). Generated by: ++ * $ bpfc - < ldb #type ++ * > jeq #0x03, drop ++ * > pass: ret #-1 ++ * > drop: ret #0 ++ * > EOF ++ */ ++static struct sock_filter pkt_type_filter_insns[] = { ++ { 0x30, 0, 0, 0xfffff004 }, ++ { 0x15, 1, 0, 0x00000003 }, ++ { 0x6, 0, 0, 0xffffffff }, ++ { 0x6, 0, 0, 0x00000000 }, ++}; ++ ++static const struct sock_fprog pkt_type_sock_filter = { ++ .len = ARRAY_SIZE(pkt_type_filter_insns), ++ .filter = pkt_type_filter_insns, ++}; ++ + + int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr) + { +@@ -471,6 +491,9 @@ int l2_packet_set_packet_filter(struct l2_packet_data *l2, + case L2_PACKET_FILTER_NDISC: + sock_filter = &ndisc_sock_filter; + break; ++ case L2_PACKET_FILTER_PKTTYPE: ++ sock_filter = &pkt_type_sock_filter; ++ break; + default: + return -1; + } +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index 2a05ef910..dcec68a03 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -4014,6 +4014,11 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s) + wpa_supplicant_rx_eapol, wpa_s, 0); + if (wpa_s->l2 == NULL) + return -1; ++ ++ if (l2_packet_set_packet_filter(wpa_s->l2, ++ L2_PACKET_FILTER_PKTTYPE)) ++ wpa_dbg(wpa_s, MSG_DEBUG, ++ "Failed to attach pkt_type filter"); + } else { + const u8 *addr = wpa_drv_get_mac_addr(wpa_s); + if (addr) +-- +2.14.3 + diff --git a/SOURCES/rh1440646-macsec_linux-Fix-NULL-pointer-dereference-on-error-c.patch b/SOURCES/rh1440646-macsec_linux-Fix-NULL-pointer-dereference-on-error-c.patch new file mode 100644 index 0000000..cb6e696 --- /dev/null +++ b/SOURCES/rh1440646-macsec_linux-Fix-NULL-pointer-dereference-on-error-c.patch @@ -0,0 +1,74 @@ +From 5db86df6a849684fda6a7ee53978a1ba931848cb Mon Sep 17 00:00:00 2001 +Message-Id: <5db86df6a849684fda6a7ee53978a1ba931848cb.1495014490.git.davide.caratti@gmail.com> +From: Davide Caratti +Date: Fri, 24 Mar 2017 10:25:24 +0100 +Subject: [PATCH] macsec_linux: Fix NULL pointer dereference on error cases + +In case wpa_supplicant is using driver_macsec_linux, but macsec module +is not (yet) loaded in the kernel, nl_socket_alloc() fails and drv->sk +is NULL. In this case, don't call libnl functions rntl_link_add() or +rtnl_link_change() using such NULL pointer, to prevent program from +getting segmentation faults like: + + Program received signal SIGSEGV, Segmentation fault. + nl_socket_get_local_port (sk=sk@entry=0x0) at socket.c:365 + 365 if (sk->s_local.nl_pid == 0) { + (gdb) p sk + $1 = (const struct nl_sock *) 0x0 + (gdb) bt + #0 nl_socket_get_local_port (sk=sk@entry=0x0) at socket.c:365 + #1 0x00007ffff79c56a0 in nl_complete_msg (sk=sk@entry=0x0, + msg=msg@entry=0x55555595a1f0) at nl.c:491 + #2 0x00007ffff79c56d1 in nl_send_auto (sk=sk@entry=0x0, + msg=msg@entry=0x55555595a1f0) at nl.c:522 + #3 0x00007ffff79c652f in nl_send_sync (sk=sk@entry=0x0, + msg=0x55555595a1f0) at nl.c:556 + #4 0x00007ffff755faf5 in rtnl_link_add (sk=0x0, + link=link@entry=0x55555595b0f0, flags=flags@entry=1024) at route/link.c:1548 + #5 0x000055555567a298 in macsec_drv_create_transmit_sc (priv=0x55555593b130, + sc=0x55555593b320, conf_offset=) at ../src/drivers/driver_macsec_linux.c:998 + +Signed-off-by: Davide Caratti +--- + src/drivers/driver_macsec_linux.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c +index 5dab77a..0694e60 100644 +--- a/src/drivers/driver_macsec_linux.c ++++ b/src/drivers/driver_macsec_linux.c +@@ -168,6 +168,9 @@ static int try_commit(struct macsec_drv_data *drv) + { + int err; + ++ if (!drv->sk) ++ return 0; ++ + if (!drv->link) + return 0; + +@@ -982,6 +985,11 @@ static int macsec_drv_create_transmit_sc( + + wpa_printf(MSG_DEBUG, "%s", __func__); + ++ if (!drv->sk) { ++ wpa_printf(MSG_ERROR, DRV_PREFIX "NULL rtnl socket"); ++ return -1; ++ } ++ + link = rtnl_link_macsec_alloc(); + if (!link) { + wpa_printf(MSG_ERROR, DRV_PREFIX "couldn't allocate link"); +@@ -1048,6 +1056,9 @@ static int macsec_drv_delete_transmit_sc(void *priv, struct transmit_sc *sc) + + wpa_printf(MSG_DEBUG, "%s", __func__); + ++ if (!drv->sk) ++ return 0; ++ + if (!drv->created_link) { + rtnl_link_put(drv->link); + drv->link = NULL; +-- +2.7.4 + diff --git a/SOURCES/rh1447073-nl80211-Fix-race-condition-in-detecting-MAC-change.patch b/SOURCES/rh1447073-nl80211-Fix-race-condition-in-detecting-MAC-change.patch new file mode 100644 index 0000000..0c03e1d --- /dev/null +++ b/SOURCES/rh1447073-nl80211-Fix-race-condition-in-detecting-MAC-change.patch @@ -0,0 +1,99 @@ +From 290834df69556b903b49f2a45671cc62b44f13bb Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Fri, 28 Apr 2017 17:59:30 +0200 +Subject: [PATCH] nl80211: Fix race condition in detecting MAC change + +Commit 3e0272ca00ce1df35b45e7d739dd7e935f13fd84 ('nl80211: Re-read MAC +address on RTM_NEWLINK') added the detection of external changes to MAC +address when the interface is brought up. + +If the interface state is changed quickly enough, wpa_supplicant may +receive the netlink message for the !IFF_UP event when the interface +has already been brought up and would ignore the next netlink IFF_UP +message, missing the MAC change. + +Fix this by also reloading the MAC address when a !IFF_UP event is +received with the interface up, because this implies that the +interface went down and up again, possibly changing the address. + +Signed-off-by: Beniamino Galvani +--- + src/drivers/driver_nl80211.c | 47 +++++++++++++++++++++++++------------------- + 1 file changed, 27 insertions(+), 20 deletions(-) + +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index af1cb84..24fad29 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -933,6 +933,30 @@ nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len) + } + + ++static void nl80211_refresh_mac(struct wpa_driver_nl80211_data *drv, ++ int ifindex) ++{ ++ struct i802_bss *bss; ++ u8 addr[ETH_ALEN]; ++ ++ bss = get_bss_ifindex(drv, ifindex); ++ if (bss && ++ linux_get_ifhwaddr(drv->global->ioctl_sock, ++ bss->ifname, addr) < 0) { ++ wpa_printf(MSG_DEBUG, ++ "nl80211: %s: failed to re-read MAC address", ++ bss->ifname); ++ } else if (bss && os_memcmp(addr, bss->addr, ETH_ALEN) != 0) { ++ wpa_printf(MSG_DEBUG, ++ "nl80211: Own MAC address on ifindex %d (%s) changed from " ++ MACSTR " to " MACSTR, ++ ifindex, bss->ifname, ++ MAC2STR(bss->addr), MAC2STR(addr)); ++ os_memcpy(bss->addr, addr, ETH_ALEN); ++ } ++} ++ ++ + static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, + struct ifinfomsg *ifi, + u8 *buf, size_t len) +@@ -997,6 +1021,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, + namebuf[0] = '\0'; + if (if_indextoname(ifi->ifi_index, namebuf) && + linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) { ++ /* Re-read MAC address as it may have changed */ ++ nl80211_refresh_mac(drv, ifi->ifi_index); + wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down " + "event since interface %s is up", namebuf); + drv->ignore_if_down_event = 0; +@@ -1044,27 +1070,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, + "event since interface %s is marked " + "removed", drv->first_bss->ifname); + } else { +- struct i802_bss *bss; +- u8 addr[ETH_ALEN]; +- + /* Re-read MAC address as it may have changed */ +- bss = get_bss_ifindex(drv, ifi->ifi_index); +- if (bss && +- linux_get_ifhwaddr(drv->global->ioctl_sock, +- bss->ifname, addr) < 0) { +- wpa_printf(MSG_DEBUG, +- "nl80211: %s: failed to re-read MAC address", +- bss->ifname); +- } else if (bss && +- os_memcmp(addr, bss->addr, ETH_ALEN) != 0) { +- wpa_printf(MSG_DEBUG, +- "nl80211: Own MAC address on ifindex %d (%s) changed from " +- MACSTR " to " MACSTR, +- ifi->ifi_index, bss->ifname, +- MAC2STR(bss->addr), +- MAC2STR(addr)); +- os_memcpy(bss->addr, addr, ETH_ALEN); +- } ++ nl80211_refresh_mac(drv, ifi->ifi_index); + + wpa_printf(MSG_DEBUG, "nl80211: Interface up"); + drv->if_disabled = 0; +-- +2.9.3 + diff --git a/SOURCES/rh1489919-mka-Add-error-handling-for-secy_init_macsec-calls.patch b/SOURCES/rh1489919-mka-Add-error-handling-for-secy_init_macsec-calls.patch new file mode 100644 index 0000000..da6f70b --- /dev/null +++ b/SOURCES/rh1489919-mka-Add-error-handling-for-secy_init_macsec-calls.patch @@ -0,0 +1,107 @@ +From 7612e65b9bdfe03e5a018e3c897f4a3292c42ee4 Mon Sep 17 00:00:00 2001 +Message-Id: <7612e65b9bdfe03e5a018e3c897f4a3292c42ee4.1506941240.git.davide.caratti@gmail.com> +From: Sabrina Dubroca +Date: Tue, 22 Aug 2017 10:34:19 +0200 +Subject: [PATCH] mka: Add error handling for secy_init_macsec() calls + +secy_init_macsec() can fail (if ->macsec_init fails), and +ieee802_1x_kay_init() should handle this and not let MKA run any +further, because nothing is going to work anyway. + +On failure, ieee802_1x_kay_init() must deinit its kay, which will free +kay->ctx, so ieee802_1x_kay_init callers (only ieee802_1x_alloc_kay_sm) +must not do it. Before this patch there is a double-free of the ctx +argument when ieee802_1x_kay_deinit() was called. + +Signed-off-by: Sabrina Dubroca +--- + src/pae/ieee802_1x_kay.c | 25 ++++++++++++++----------- + wpa_supplicant/wpas_kay.c | 5 ++--- + 2 files changed, 16 insertions(+), 14 deletions(-) + +diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c +index ff55f88b8..c4bfcbc63 100644 +--- a/src/pae/ieee802_1x_kay.c ++++ b/src/pae/ieee802_1x_kay.c +@@ -3100,6 +3100,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + kay = os_zalloc(sizeof(*kay)); + if (!kay) { + wpa_printf(MSG_ERROR, "KaY-%s: out of memory", __func__); ++ os_free(ctx); + return NULL; + } + +@@ -3134,10 +3135,8 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + dl_list_init(&kay->participant_list); + + if (policy != DO_NOT_SECURE && +- secy_get_capability(kay, &kay->macsec_capable) < 0) { +- os_free(kay); +- return NULL; +- } ++ secy_get_capability(kay, &kay->macsec_capable) < 0) ++ goto error; + + if (policy == DO_NOT_SECURE || + kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) { +@@ -3164,16 +3163,17 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + wpa_printf(MSG_DEBUG, "KaY: state machine created"); + + /* Initialize the SecY must be prio to CP, as CP will control SecY */ +- secy_init_macsec(kay); ++ if (secy_init_macsec(kay) < 0) { ++ wpa_printf(MSG_DEBUG, "KaY: Could not initialize MACsec"); ++ goto error; ++ } + + wpa_printf(MSG_DEBUG, "KaY: secy init macsec done"); + + /* init CP */ + kay->cp = ieee802_1x_cp_sm_init(kay); +- if (kay->cp == NULL) { +- ieee802_1x_kay_deinit(kay); +- return NULL; +- } ++ if (kay->cp == NULL) ++ goto error; + + if (policy == DO_NOT_SECURE) { + ieee802_1x_cp_connect_authenticated(kay->cp); +@@ -3184,12 +3184,15 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy, + if (kay->l2_mka == NULL) { + wpa_printf(MSG_WARNING, + "KaY: Failed to initialize L2 packet processing for MKA packet"); +- ieee802_1x_kay_deinit(kay); +- return NULL; ++ goto error; + } + } + + return kay; ++ ++error: ++ ieee802_1x_kay_deinit(kay); ++ return NULL; + } + + +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index d087e00ad..587e5c3dd 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -235,10 +235,9 @@ int ieee802_1x_alloc_kay_sm(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) + res = ieee802_1x_kay_init(kay_ctx, policy, ssid->macsec_port, + ssid->mka_priority, wpa_s->ifname, + wpa_s->own_addr); +- if (res == NULL) { +- os_free(kay_ctx); ++ /* ieee802_1x_kay_init() frees kay_ctx on failure */ ++ if (res == NULL) + return -1; +- } + + wpa_s->kay = res; + +-- +2.13.5 + diff --git a/SOURCES/rh1490885-fix-auth-failure-when-the-mac-is-updated-externally.patch b/SOURCES/rh1490885-fix-auth-failure-when-the-mac-is-updated-externally.patch new file mode 100644 index 0000000..eea000a --- /dev/null +++ b/SOURCES/rh1490885-fix-auth-failure-when-the-mac-is-updated-externally.patch @@ -0,0 +1,158 @@ +From 175c8ec5f46fbe544eb71b80d83ed517a3c81ba4 Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Thu, 15 Feb 2018 11:50:01 +0100 +Subject: [PATCH] wpa_supplicant: Fix auth failure when the MAC is updated + externally + +When connecting to a WPA-EAP network and the MAC address is changed +just before the association (for example by NetworkManager, which sets +a random MAC during scans), the authentication sometimes fails in the +following way ('####' logs added by me): + +wpa_supplicant logs: + wlan0: WPA: RX message 1 of 4-Way Handshake from 02:00:00:00:01:00 (ver=1) + RSN: msg 1/4 key data - hexdump(len=22): dd 14 00 0f ac 04 d8 21 9d a5 73 98 88 26 ef 03 d2 ce f7 04 7d 23 + WPA: PMKID in EAPOL-Key - hexdump(len=22): dd 14 00 0f ac 04 d8 21 9d a5 73 98 88 26 ef 03 d2 ce f7 04 7d 23 + RSN: PMKID from Authenticator - hexdump(len=16): d8 21 9d a5 73 98 88 26 ef 03 d2 ce f7 04 7d 23 + wlan0: RSN: no matching PMKID found + EAPOL: Successfully fetched key (len=32) + WPA: PMK from EAPOL state machines - hexdump(len=32): [REMOVED] + #### WPA: rsn_pmkid(): + #### WPA: aa - hexdump(len=6): 02 00 00 00 01 00 + #### WPA: spa - hexdump(len=6): 66 20 cf ab 8c dc + #### WPA: PMK - hexdump(len=32): b5 24 76 4f 6f 50 8c f6 a1 2e 24 b8 07 4e 9a 13 1b 94 c4 a8 1f 7e 22 d6 ed fc 7d 43 c7 77 b6 f7 + #### WPA: computed PMKID - hexdump(len=16): ea 73 67 b1 8e 5f 18 43 58 24 e8 1c 47 23 87 71 + RSN: Replace PMKSA entry for the current AP and any PMKSA cache entry that was based on the old PMK + nl80211: Delete PMKID for 02:00:00:00:01:00 + wlan0: RSN: PMKSA cache entry free_cb: 02:00:00:00:01:00 reason=1 + RSN: Added PMKSA cache entry for 02:00:00:00:01:00 network_ctx=0x5630bf85a270 + nl80211: Add PMKID for 02:00:00:00:01:00 + wlan0: RSN: PMKID mismatch - authentication server may have derived different MSK?! + +hostapd logs: + WPA: PMK from EAPOL state machine (MSK len=64 PMK len=32) + WPA: 02:00:00:00:00:00 WPA_PTK entering state PTKSTART + wlan1: STA 02:00:00:00:00:00 WPA: sending 1/4 msg of 4-Way Handshake + #### WPA: rsn_pmkid(): + #### WPA: aa - hexdump(len=6): 02 00 00 00 01 00 + #### WPA: spa - hexdump(len=6): 02 00 00 00 00 00 + #### WPA: PMK - hexdump(len=32): b5 24 76 4f 6f 50 8c f6 a1 2e 24 b8 07 4e 9a 13 1b 94 c4 a8 1f 7e 22 d6 ed fc 7d 43 c7 77 b6 f7 + #### WPA: computed PMKID - hexdump(len=16): d8 21 9d a5 73 98 88 26 ef 03 d2 ce f7 04 7d 23 + WPA: Send EAPOL(version=1 secure=0 mic=0 ack=1 install=0 pairwise=1 kde_len=22 keyidx=0 encr=0) + +That's because wpa_supplicant computed the PMKID using the wrong (old) +MAC address used during the scan. wpa_supplicant updates own_addr when +the interface goes up, as the MAC can only change while the interface +is down. However, drivers don't report all interface state changes: +for example the nl80211 driver may ignore a down-up cycle if the down +message is processed later, when the interface is already up. In such +cases, wpa_supplicant (and in particular, the EAP state machine) would +continue to use the old MAC. + +Add a new driver event that notifies of MAC address changes while the +interface is active. + +Signed-off-by: Beniamino Galvani +(cherry picked from commit 77a020a118168e05e7cc0d28a7bf661772e531af) +--- + src/drivers/driver.h | 9 +++++++++ + src/drivers/driver_common.c | 1 + + src/drivers/driver_nl80211.c | 11 +++++++---- + wpa_supplicant/events.c | 3 +++ + 4 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/drivers/driver.h b/src/drivers/driver.h +index df996dc21..f8d556133 100644 +--- a/src/drivers/driver.h ++++ b/src/drivers/driver.h +@@ -4106,6 +4106,15 @@ enum wpa_event_type { + * EVENT_P2P_LO_STOP - Notify that P2P listen offload is stopped + */ + EVENT_P2P_LO_STOP, ++ ++ /** ++ * EVENT_INTERFACE_MAC_CHANGED - Notify that interface MAC changed ++ * ++ * This event is emitted when the MAC changes while the interface is ++ * enabled. When an interface was disabled and becomes enabled, it ++ * must be always assumed that the MAC possibly changed. ++ */ ++ EVENT_INTERFACE_MAC_CHANGED, + }; + + +diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c +index c7107ba89..bdddc0a48 100644 +--- a/src/drivers/driver_common.c ++++ b/src/drivers/driver_common.c +@@ -81,6 +81,7 @@ const char * event_to_string(enum wpa_event_type event) + E2S(ACS_CHANNEL_SELECTED); + E2S(DFS_CAC_STARTED); + E2S(P2P_LO_STOP); ++ E2S(INTERFACE_MAC_CHANGED); + } + + return "UNKNOWN"; +diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c +index f7f3cfebc..d4a879836 100644 +--- a/src/drivers/driver_nl80211.c ++++ b/src/drivers/driver_nl80211.c +@@ -923,7 +923,7 @@ nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len) + + + static void nl80211_refresh_mac(struct wpa_driver_nl80211_data *drv, +- int ifindex) ++ int ifindex, int notify) + { + struct i802_bss *bss; + u8 addr[ETH_ALEN]; +@@ -942,6 +942,9 @@ static void nl80211_refresh_mac(struct wpa_driver_nl80211_data *drv, + ifindex, bss->ifname, + MAC2STR(bss->addr), MAC2STR(addr)); + os_memcpy(bss->addr, addr, ETH_ALEN); ++ if (notify) ++ wpa_supplicant_event(drv->ctx, ++ EVENT_INTERFACE_MAC_CHANGED, NULL); + } + } + +@@ -1010,11 +1013,11 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, + namebuf[0] = '\0'; + if (if_indextoname(ifi->ifi_index, namebuf) && + linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) { +- /* Re-read MAC address as it may have changed */ +- nl80211_refresh_mac(drv, ifi->ifi_index); + wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down " + "event since interface %s is up", namebuf); + drv->ignore_if_down_event = 0; ++ /* Re-read MAC address as it may have changed */ ++ nl80211_refresh_mac(drv, ifi->ifi_index, 1); + return; + } + wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)", +@@ -1060,7 +1063,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx, + "removed", drv->first_bss->ifname); + } else { + /* Re-read MAC address as it may have changed */ +- nl80211_refresh_mac(drv, ifi->ifi_index); ++ nl80211_refresh_mac(drv, ifi->ifi_index, 0); + + wpa_printf(MSG_DEBUG, "nl80211: Interface up"); + drv->if_disabled = 0; +diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c +index 4dc044c2b..6eb35104c 100644 +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -3927,6 +3927,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, + data->signal_change.current_noise, + data->signal_change.current_txrate); + break; ++ case EVENT_INTERFACE_MAC_CHANGED: ++ wpa_supplicant_update_mac_addr(wpa_s); ++ break; + case EVENT_INTERFACE_ENABLED: + wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled"); + if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { +-- +2.14.3 + diff --git a/SOURCES/rh1495527-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch b/SOURCES/rh1495527-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch new file mode 100644 index 0000000..7276848 --- /dev/null +++ b/SOURCES/rh1495527-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch @@ -0,0 +1,174 @@ +From cf4cab804c7afd5c45505528a8d16e46163243a2 Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Fri, 14 Jul 2017 15:15:35 +0200 +Subject: [PATCH 1/8] hostapd: Avoid key reinstallation in FT handshake + +Do not reinstall TK to the driver during Reassociation Response frame +processing if the first attempt of setting the TK succeeded. This avoids +issues related to clearing the TX/RX PN that could result in reusing +same PN values for transmitted frames (e.g., due to CCM nonce reuse and +also hitting replay protection on the receiver) and accepting replayed +frames on RX side. + +This issue was introduced by the commit +0e84c25434e6a1f283c7b4e62e483729085b78d2 ('FT: Fix PTK configuration in +authenticator') which allowed wpa_ft_install_ptk() to be called multiple +times with the same PTK. While the second configuration attempt is +needed with some drivers, it must be done only if the first attempt +failed. + +Signed-off-by: Mathy Vanhoef +--- + src/ap/ieee802_11.c | 16 +++++++++++++--- + src/ap/wpa_auth.c | 11 +++++++++++ + src/ap/wpa_auth.h | 3 ++- + src/ap/wpa_auth_ft.c | 10 ++++++++++ + src/ap/wpa_auth_i.h | 1 + + 5 files changed, 37 insertions(+), 4 deletions(-) + +diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c +index 4e04169..333035f 100644 +--- a/src/ap/ieee802_11.c ++++ b/src/ap/ieee802_11.c +@@ -1841,6 +1841,7 @@ static int add_associated_sta(struct hostapd_data *hapd, + { + struct ieee80211_ht_capabilities ht_cap; + struct ieee80211_vht_capabilities vht_cap; ++ int set = 1; + + /* + * Remove the STA entry to ensure the STA PS state gets cleared and +@@ -1848,9 +1849,18 @@ static int add_associated_sta(struct hostapd_data *hapd, + * FT-over-the-DS, where a station re-associates back to the same AP but + * skips the authentication flow, or if working with a driver that + * does not support full AP client state. ++ * ++ * Skip this if the STA has already completed FT reassociation and the ++ * TK has been configured since the TX/RX PN must not be reset to 0 for ++ * the same key. + */ +- if (!sta->added_unassoc) ++ if (!sta->added_unassoc && ++ (!(sta->flags & WLAN_STA_AUTHORIZED) || ++ !wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) { + hostapd_drv_sta_remove(hapd, sta->addr); ++ wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); ++ set = 0; ++ } + + #ifdef CONFIG_IEEE80211N + if (sta->flags & WLAN_STA_HT) +@@ -1873,11 +1883,11 @@ static int add_associated_sta(struct hostapd_data *hapd, + sta->flags & WLAN_STA_VHT ? &vht_cap : NULL, + sta->flags | WLAN_STA_ASSOC, sta->qosinfo, + sta->vht_opmode, sta->p2p_ie ? 1 : 0, +- sta->added_unassoc)) { ++ set)) { + hostapd_logger(hapd, sta->addr, + HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, + "Could not %s STA to kernel driver", +- sta->added_unassoc ? "set" : "add"); ++ set ? "set" : "add"); + + if (sta->added_unassoc) { + hostapd_drv_sta_remove(hapd, sta->addr); +diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c +index 3587086..707971d 100644 +--- a/src/ap/wpa_auth.c ++++ b/src/ap/wpa_auth.c +@@ -1745,6 +1745,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event) + #else /* CONFIG_IEEE80211R */ + break; + #endif /* CONFIG_IEEE80211R */ ++ case WPA_DRV_STA_REMOVED: ++ sm->tk_already_set = FALSE; ++ return 0; + } + + #ifdef CONFIG_IEEE80211R +@@ -3250,6 +3253,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) + } + + ++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm) ++{ ++ if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt)) ++ return 0; ++ return sm->tk_already_set; ++} ++ ++ + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, + struct rsn_pmksa_cache_entry *entry) + { +diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h +index 0de8d97..97461b0 100644 +--- a/src/ap/wpa_auth.h ++++ b/src/ap/wpa_auth.h +@@ -267,7 +267,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, + u8 *data, size_t data_len); + enum wpa_event { + WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH, +- WPA_REAUTH_EAPOL, WPA_ASSOC_FT ++ WPA_REAUTH_EAPOL, WPA_ASSOC_FT, WPA_DRV_STA_REMOVED + }; + void wpa_remove_ptk(struct wpa_state_machine *sm); + int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event); +@@ -280,6 +280,7 @@ int wpa_auth_pairwise_set(struct wpa_state_machine *sm); + int wpa_auth_get_pairwise(struct wpa_state_machine *sm); + int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm); + int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm); ++int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm); + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, + struct rsn_pmksa_cache_entry *entry); + struct rsn_pmksa_cache_entry * +diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c +index 42242a5..e63b99a 100644 +--- a/src/ap/wpa_auth_ft.c ++++ b/src/ap/wpa_auth_ft.c +@@ -780,6 +780,14 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) + return; + } + ++ if (sm->tk_already_set) { ++ /* Must avoid TK reconfiguration to prevent clearing of TX/RX ++ * PN in the driver */ ++ wpa_printf(MSG_DEBUG, ++ "FT: Do not re-install same PTK to the driver"); ++ return; ++ } ++ + /* FIX: add STA entry to kernel/driver here? The set_key will fail + * most likely without this.. At the moment, STA entry is added only + * after association has been completed. This function will be called +@@ -792,6 +800,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) + + /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ + sm->pairwise_set = TRUE; ++ sm->tk_already_set = TRUE; + } + + +@@ -898,6 +907,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, + + sm->pairwise = pairwise; + sm->PTK_valid = TRUE; ++ sm->tk_already_set = FALSE; + wpa_ft_install_ptk(sm); + + buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + +diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h +index 72b7eb3..7fd8f05 100644 +--- a/src/ap/wpa_auth_i.h ++++ b/src/ap/wpa_auth_i.h +@@ -65,6 +65,7 @@ struct wpa_state_machine { + struct wpa_ptk PTK; + Boolean PTK_valid; + Boolean pairwise_set; ++ Boolean tk_already_set; + int keycount; + Boolean Pair; + struct wpa_key_replay_counter { +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch b/SOURCES/rh1495527-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch new file mode 100644 index 0000000..1802d66 --- /dev/null +++ b/SOURCES/rh1495527-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch @@ -0,0 +1,250 @@ +From 927f891007c402fefd1ff384645b3f07597c3ede Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Wed, 12 Jul 2017 16:03:24 +0200 +Subject: [PATCH 2/8] Prevent reinstallation of an already in-use group key + +Track the current GTK and IGTK that is in use and when receiving a +(possibly retransmitted) Group Message 1 or WNM-Sleep Mode Response, do +not install the given key if it is already in use. This prevents an +attacker from trying to trick the client into resetting or lowering the +sequence counter associated to the group key. + +Signed-off-by: Mathy Vanhoef +--- + src/common/wpa_common.h | 11 +++++ + src/rsn_supp/wpa.c | 116 ++++++++++++++++++++++++++++++------------------ + src/rsn_supp/wpa_i.h | 4 ++ + 3 files changed, 87 insertions(+), 44 deletions(-) + +diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h +index af1d0f0..d200285 100644 +--- a/src/common/wpa_common.h ++++ b/src/common/wpa_common.h +@@ -217,6 +217,17 @@ struct wpa_ptk { + size_t tk_len; + }; + ++struct wpa_gtk { ++ u8 gtk[WPA_GTK_MAX_LEN]; ++ size_t gtk_len; ++}; ++ ++#ifdef CONFIG_IEEE80211W ++struct wpa_igtk { ++ u8 igtk[WPA_IGTK_MAX_LEN]; ++ size_t igtk_len; ++}; ++#endif /* CONFIG_IEEE80211W */ + + /* WPA IE version 1 + * 00-50-f2:1 (OUI:OUI type) +diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c +index 3c47879..95bd7be 100644 +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -714,6 +714,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, + const u8 *_gtk = gd->gtk; + u8 gtk_buf[32]; + ++ /* Detect possible key reinstallation */ ++ if (sm->gtk.gtk_len == (size_t) gd->gtk_len && ++ os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", ++ gd->keyidx, gd->tx, gd->gtk_len); ++ return 0; ++ } ++ + wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)", +@@ -748,6 +757,9 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, + } + os_memset(gtk_buf, 0, sizeof(gtk_buf)); + ++ sm->gtk.gtk_len = gd->gtk_len; ++ os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); ++ + return 0; + } + +@@ -854,6 +866,48 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, + } + + ++#ifdef CONFIG_IEEE80211W ++static int wpa_supplicant_install_igtk(struct wpa_sm *sm, ++ const struct wpa_igtk_kde *igtk) ++{ ++ size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); ++ u16 keyidx = WPA_GET_LE16(igtk->keyid); ++ ++ /* Detect possible key reinstallation */ ++ if (sm->igtk.igtk_len == len && ++ os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", ++ keyidx); ++ return 0; ++ } ++ ++ wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, ++ "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", ++ keyidx, MAC2STR(igtk->pn)); ++ wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); ++ if (keyidx > 4095) { ++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, ++ "WPA: Invalid IGTK KeyID %d", keyidx); ++ return -1; ++ } ++ if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), ++ broadcast_ether_addr, ++ keyidx, 0, igtk->pn, sizeof(igtk->pn), ++ igtk->igtk, len) < 0) { ++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, ++ "WPA: Failed to configure IGTK to the driver"); ++ return -1; ++ } ++ ++ sm->igtk.igtk_len = len; ++ os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); ++ ++ return 0; ++} ++#endif /* CONFIG_IEEE80211W */ ++ ++ + static int ieee80211w_set_keys(struct wpa_sm *sm, + struct wpa_eapol_ie_parse *ie) + { +@@ -864,30 +918,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm, + if (ie->igtk) { + size_t len; + const struct wpa_igtk_kde *igtk; +- u16 keyidx; ++ + len = wpa_cipher_key_len(sm->mgmt_group_cipher); + if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len) + return -1; ++ + igtk = (const struct wpa_igtk_kde *) ie->igtk; +- keyidx = WPA_GET_LE16(igtk->keyid); +- wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d " +- "pn %02x%02x%02x%02x%02x%02x", +- keyidx, MAC2STR(igtk->pn)); +- wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", +- igtk->igtk, len); +- if (keyidx > 4095) { +- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, +- "WPA: Invalid IGTK KeyID %d", keyidx); +- return -1; +- } +- if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), +- broadcast_ether_addr, +- keyidx, 0, igtk->pn, sizeof(igtk->pn), +- igtk->igtk, len) < 0) { +- wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, +- "WPA: Failed to configure IGTK to the driver"); ++ if (wpa_supplicant_install_igtk(sm, igtk) < 0) + return -1; +- } + } + + return 0; +@@ -2307,7 +2345,7 @@ void wpa_sm_deinit(struct wpa_sm *sm) + */ + void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) + { +- int clear_ptk = 1; ++ int clear_keys = 1; + + if (sm == NULL) + return; +@@ -2333,11 +2371,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) + /* Prepare for the next transition */ + wpa_ft_prepare_auth_request(sm, NULL); + +- clear_ptk = 0; ++ clear_keys = 0; + } + #endif /* CONFIG_IEEE80211R */ + +- if (clear_ptk) { ++ if (clear_keys) { + /* + * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if + * this is not part of a Fast BSS Transition. +@@ -2347,6 +2385,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + sm->tptk_set = 0; + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); ++ os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++#ifdef CONFIG_IEEE80211W ++ os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++#endif /* CONFIG_IEEE80211W */ + } + + #ifdef CONFIG_TDLS +@@ -2877,6 +2919,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) + os_memset(sm->pmk, 0, sizeof(sm->pmk)); + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); ++ os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++#ifdef CONFIG_IEEE80211W ++ os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++#endif /* CONFIG_IEEE80211W */ + #ifdef CONFIG_IEEE80211R + os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); + os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0)); +@@ -2949,29 +2995,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) + os_memset(&gd, 0, sizeof(gd)); + #ifdef CONFIG_IEEE80211W + } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { +- struct wpa_igtk_kde igd; +- u16 keyidx; +- +- os_memset(&igd, 0, sizeof(igd)); +- keylen = wpa_cipher_key_len(sm->mgmt_group_cipher); +- os_memcpy(igd.keyid, buf + 2, 2); +- os_memcpy(igd.pn, buf + 4, 6); +- +- keyidx = WPA_GET_LE16(igd.keyid); +- os_memcpy(igd.igtk, buf + 10, keylen); +- +- wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)", +- igd.igtk, keylen); +- if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), +- broadcast_ether_addr, +- keyidx, 0, igd.pn, sizeof(igd.pn), +- igd.igtk, keylen) < 0) { +- wpa_printf(MSG_DEBUG, "Failed to install the IGTK in " +- "WNM mode"); +- os_memset(&igd, 0, sizeof(igd)); ++ const struct wpa_igtk_kde *igtk; ++ ++ igtk = (const struct wpa_igtk_kde *) (buf + 2); ++ if (wpa_supplicant_install_igtk(sm, igtk) < 0) + return -1; +- } +- os_memset(&igd, 0, sizeof(igd)); + #endif /* CONFIG_IEEE80211W */ + } else { + wpa_printf(MSG_DEBUG, "Unknown element id"); +diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h +index f653ba6..afc9e37 100644 +--- a/src/rsn_supp/wpa_i.h ++++ b/src/rsn_supp/wpa_i.h +@@ -31,6 +31,10 @@ struct wpa_sm { + u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; + int rx_replay_counter_set; + u8 request_counter[WPA_REPLAY_COUNTER_LEN]; ++ struct wpa_gtk gtk; ++#ifdef CONFIG_IEEE80211W ++ struct wpa_igtk igtk; ++#endif /* CONFIG_IEEE80211W */ + + struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ + +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch b/SOURCES/rh1495527-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch new file mode 100644 index 0000000..e2937b8 --- /dev/null +++ b/SOURCES/rh1495527-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch @@ -0,0 +1,184 @@ +From 8280294e74846ea342389a0cd17215050fa5afe8 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sun, 1 Oct 2017 12:12:24 +0300 +Subject: [PATCH 3/8] Extend protection of GTK/IGTK reinstallation of WNM-Sleep + Mode cases + +This extends the protection to track last configured GTK/IGTK value +separately from EAPOL-Key frames and WNM-Sleep Mode frames to cover a +corner case where these two different mechanisms may get used when the +GTK/IGTK has changed and tracking a single value is not sufficient to +detect a possible key reconfiguration. + +Signed-off-by: Jouni Malinen +--- + src/rsn_supp/wpa.c | 53 +++++++++++++++++++++++++++++++++++++--------------- + src/rsn_supp/wpa_i.h | 2 ++ + 2 files changed, 40 insertions(+), 15 deletions(-) + +diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c +index 95bd7be..7a2c68d 100644 +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -709,14 +709,17 @@ struct wpa_gtk_data { + + static int wpa_supplicant_install_gtk(struct wpa_sm *sm, + const struct wpa_gtk_data *gd, +- const u8 *key_rsc) ++ const u8 *key_rsc, int wnm_sleep) + { + const u8 *_gtk = gd->gtk; + u8 gtk_buf[32]; + + /* Detect possible key reinstallation */ +- if (sm->gtk.gtk_len == (size_t) gd->gtk_len && +- os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { ++ if ((sm->gtk.gtk_len == (size_t) gd->gtk_len && ++ os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) || ++ (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len && ++ os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk, ++ sm->gtk_wnm_sleep.gtk_len) == 0)) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", + gd->keyidx, gd->tx, gd->gtk_len); +@@ -757,8 +760,14 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, + } + os_memset(gtk_buf, 0, sizeof(gtk_buf)); + +- sm->gtk.gtk_len = gd->gtk_len; +- os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); ++ if (wnm_sleep) { ++ sm->gtk_wnm_sleep.gtk_len = gd->gtk_len; ++ os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk, ++ sm->gtk_wnm_sleep.gtk_len); ++ } else { ++ sm->gtk.gtk_len = gd->gtk_len; ++ os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); ++ } + + return 0; + } +@@ -852,7 +861,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, + (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, + gtk_len, gtk_len, + &gd.key_rsc_len, &gd.alg) || +- wpa_supplicant_install_gtk(sm, &gd, key_rsc))) { ++ wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "RSN: Failed to install GTK"); + os_memset(&gd, 0, sizeof(gd)); +@@ -868,14 +877,18 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, + + #ifdef CONFIG_IEEE80211W + static int wpa_supplicant_install_igtk(struct wpa_sm *sm, +- const struct wpa_igtk_kde *igtk) ++ const struct wpa_igtk_kde *igtk, ++ int wnm_sleep) + { + size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); + u16 keyidx = WPA_GET_LE16(igtk->keyid); + + /* Detect possible key reinstallation */ +- if (sm->igtk.igtk_len == len && +- os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { ++ if ((sm->igtk.igtk_len == len && ++ os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) || ++ (sm->igtk_wnm_sleep.igtk_len == len && ++ os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk, ++ sm->igtk_wnm_sleep.igtk_len) == 0)) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", + keyidx); +@@ -900,8 +913,14 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm, + return -1; + } + +- sm->igtk.igtk_len = len; +- os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); ++ if (wnm_sleep) { ++ sm->igtk_wnm_sleep.igtk_len = len; ++ os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk, ++ sm->igtk_wnm_sleep.igtk_len); ++ } else { ++ sm->igtk.igtk_len = len; ++ os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); ++ } + + return 0; + } +@@ -924,7 +943,7 @@ static int ieee80211w_set_keys(struct wpa_sm *sm, + return -1; + + igtk = (const struct wpa_igtk_kde *) ie->igtk; +- if (wpa_supplicant_install_igtk(sm, igtk) < 0) ++ if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0) + return -1; + } + +@@ -1574,7 +1593,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, + if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc)) + key_rsc = null_rsc; + +- if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) || ++ if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) || + wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0) + goto failed; + os_memset(&gd, 0, sizeof(gd)); +@@ -2386,8 +2405,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) + sm->tptk_set = 0; + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++ os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); + #ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++ os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); + #endif /* CONFIG_IEEE80211W */ + } + +@@ -2920,8 +2941,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) + os_memset(&sm->ptk, 0, sizeof(sm->ptk)); + os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); ++ os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); + #ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); ++ os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); + #endif /* CONFIG_IEEE80211W */ + #ifdef CONFIG_IEEE80211R + os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); +@@ -2986,7 +3009,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) + + wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", + gd.gtk, gd.gtk_len); +- if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) { ++ if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) { + os_memset(&gd, 0, sizeof(gd)); + wpa_printf(MSG_DEBUG, "Failed to install the GTK in " + "WNM mode"); +@@ -2998,7 +3021,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) + const struct wpa_igtk_kde *igtk; + + igtk = (const struct wpa_igtk_kde *) (buf + 2); +- if (wpa_supplicant_install_igtk(sm, igtk) < 0) ++ if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0) + return -1; + #endif /* CONFIG_IEEE80211W */ + } else { +diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h +index afc9e37..9a54631 100644 +--- a/src/rsn_supp/wpa_i.h ++++ b/src/rsn_supp/wpa_i.h +@@ -32,8 +32,10 @@ struct wpa_sm { + int rx_replay_counter_set; + u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + struct wpa_gtk gtk; ++ struct wpa_gtk gtk_wnm_sleep; + #ifdef CONFIG_IEEE80211W + struct wpa_igtk igtk; ++ struct wpa_igtk igtk_wnm_sleep; + #endif /* CONFIG_IEEE80211W */ + + struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0004-Prevent-installation-of-an-all-zero-TK.patch b/SOURCES/rh1495527-0004-Prevent-installation-of-an-all-zero-TK.patch new file mode 100644 index 0000000..22ee217 --- /dev/null +++ b/SOURCES/rh1495527-0004-Prevent-installation-of-an-all-zero-TK.patch @@ -0,0 +1,79 @@ +From 8f82bc94e8697a9d47fa8774dfdaaede1084912c Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Fri, 29 Sep 2017 04:22:51 +0200 +Subject: [PATCH 4/8] Prevent installation of an all-zero TK + +Properly track whether a PTK has already been installed to the driver +and the TK part cleared from memory. This prevents an attacker from +trying to trick the client into installing an all-zero TK. + +This fixes the earlier fix in commit +ad00d64e7d8827b3cebd665a0ceb08adabf15e1e ('Fix TK configuration to the +driver in EAPOL-Key 3/4 retry case') which did not take into account +possibility of an extra message 1/4 showing up between retries of +message 3/4. + +Signed-off-by: Mathy Vanhoef +--- + src/common/wpa_common.h | 1 + + src/rsn_supp/wpa.c | 5 ++--- + src/rsn_supp/wpa_i.h | 1 - + 3 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h +index d200285..1021ccb 100644 +--- a/src/common/wpa_common.h ++++ b/src/common/wpa_common.h +@@ -215,6 +215,7 @@ struct wpa_ptk { + size_t kck_len; + size_t kek_len; + size_t tk_len; ++ int installed; /* 1 if key has already been installed to driver */ + }; + + struct wpa_gtk { +diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c +index 7a2c68d..0550a41 100644 +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -510,7 +510,6 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, + os_memset(buf, 0, sizeof(buf)); + } + sm->tptk_set = 1; +- sm->tk_to_set = 1; + + kde = sm->assoc_wpa_ie; + kde_len = sm->assoc_wpa_ie_len; +@@ -615,7 +614,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, + enum wpa_alg alg; + const u8 *key_rsc; + +- if (!sm->tk_to_set) { ++ if (sm->ptk.installed) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Do not re-install same PTK to the driver"); + return 0; +@@ -659,7 +658,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, + + /* TK is not needed anymore in supplicant */ + os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); +- sm->tk_to_set = 0; ++ sm->ptk.installed = 1; + + if (sm->wpa_ptk_rekey) { + eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); +diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h +index 9a54631..41f371f 100644 +--- a/src/rsn_supp/wpa_i.h ++++ b/src/rsn_supp/wpa_i.h +@@ -24,7 +24,6 @@ struct wpa_sm { + struct wpa_ptk ptk, tptk; + int ptk_set, tptk_set; + unsigned int msg_3_of_4_ok:1; +- unsigned int tk_to_set:1; + u8 snonce[WPA_NONCE_LEN]; + u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ + int renew_snonce; +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch b/SOURCES/rh1495527-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch new file mode 100644 index 0000000..c19c4c7 --- /dev/null +++ b/SOURCES/rh1495527-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch @@ -0,0 +1,64 @@ +From 12fac09b437a1dc8a0f253e265934a8aaf4d2f8b Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Sun, 1 Oct 2017 12:32:57 +0300 +Subject: [PATCH 5/8] Fix PTK rekeying to generate a new ANonce + +The Authenticator state machine path for PTK rekeying ended up bypassing +the AUTHENTICATION2 state where a new ANonce is generated when going +directly to the PTKSTART state since there is no need to try to +determine the PMK again in such a case. This is far from ideal since the +new PTK would depend on a new nonce only from the supplicant. + +Fix this by generating a new ANonce when moving to the PTKSTART state +for the purpose of starting new 4-way handshake to rekey PTK. + +Signed-off-by: Jouni Malinen +--- + src/ap/wpa_auth.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c +index 707971d..bf10cc1 100644 +--- a/src/ap/wpa_auth.c ++++ b/src/ap/wpa_auth.c +@@ -1901,6 +1901,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) + } + + ++static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) ++{ ++ if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { ++ wpa_printf(MSG_ERROR, ++ "WPA: Failed to get random data for ANonce"); ++ sm->Disconnect = TRUE; ++ return -1; ++ } ++ wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, ++ WPA_NONCE_LEN); ++ sm->TimeoutCtr = 0; ++ return 0; ++} ++ ++ + SM_STATE(WPA_PTK, INITPMK) + { + u8 msk[2 * PMK_LEN]; +@@ -2458,9 +2473,12 @@ SM_STEP(WPA_PTK) + SM_ENTER(WPA_PTK, AUTHENTICATION); + else if (sm->ReAuthenticationRequest) + SM_ENTER(WPA_PTK, AUTHENTICATION2); +- else if (sm->PTKRequest) +- SM_ENTER(WPA_PTK, PTKSTART); +- else switch (sm->wpa_ptk_state) { ++ else if (sm->PTKRequest) { ++ if (wpa_auth_sm_ptk_update(sm) < 0) ++ SM_ENTER(WPA_PTK, DISCONNECTED); ++ else ++ SM_ENTER(WPA_PTK, PTKSTART); ++ } else switch (sm->wpa_ptk_state) { + case WPA_PTK_INITIALIZE: + break; + case WPA_PTK_DISCONNECT: +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0006-TDLS-Reject-TPK-TK-reconfiguration.patch b/SOURCES/rh1495527-0006-TDLS-Reject-TPK-TK-reconfiguration.patch new file mode 100644 index 0000000..e1bd5a5 --- /dev/null +++ b/SOURCES/rh1495527-0006-TDLS-Reject-TPK-TK-reconfiguration.patch @@ -0,0 +1,132 @@ +From 6c4bed4f47d1960ec04981a9d50e5076aea5223d Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Fri, 22 Sep 2017 11:03:15 +0300 +Subject: [PATCH 6/8] TDLS: Reject TPK-TK reconfiguration + +Do not try to reconfigure the same TPK-TK to the driver after it has +been successfully configured. This is an explicit check to avoid issues +related to resetting the TX/RX packet number. There was already a check +for this for TPK M2 (retries of that message are ignored completely), so +that behavior does not get modified. + +For TPK M3, the TPK-TK could have been reconfigured, but that was +followed by immediate teardown of the link due to an issue in updating +the STA entry. Furthermore, for TDLS with any real security (i.e., +ignoring open/WEP), the TPK message exchange is protected on the AP path +and simple replay attacks are not feasible. + +As an additional corner case, make sure the local nonce gets updated if +the peer uses a very unlikely "random nonce" of all zeros. + +Signed-off-by: Jouni Malinen +--- + src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c +index e424168..9eb9738 100644 +--- a/src/rsn_supp/tdls.c ++++ b/src/rsn_supp/tdls.c +@@ -112,6 +112,7 @@ struct wpa_tdls_peer { + u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ + } tpk; + int tpk_set; ++ int tk_set; /* TPK-TK configured to the driver */ + int tpk_success; + int tpk_in_progress; + +@@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) + u8 rsc[6]; + enum wpa_alg alg; + ++ if (peer->tk_set) { ++ /* ++ * This same TPK-TK has already been configured to the driver ++ * and this new configuration attempt (likely due to an ++ * unexpected retransmitted frame) would result in clearing ++ * the TX/RX sequence number which can break security, so must ++ * not allow that to happen. ++ */ ++ wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR ++ " has already been configured to the driver - do not reconfigure", ++ MAC2STR(peer->addr)); ++ return -1; ++ } ++ + os_memset(rsc, 0, 6); + + switch (peer->cipher) { +@@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) + return -1; + } + ++ wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, ++ MAC2STR(peer->addr)); + if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, + rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { + wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " + "driver"); + return -1; + } ++ peer->tk_set = 1; + return 0; + } + +@@ -696,7 +714,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) + peer->cipher = 0; + peer->qos_info = 0; + peer->wmm_capable = 0; +- peer->tpk_set = peer->tpk_success = 0; ++ peer->tk_set = peer->tpk_set = peer->tpk_success = 0; + peer->chan_switch_enabled = 0; + os_memset(&peer->tpk, 0, sizeof(peer->tpk)); + os_memset(peer->inonce, 0, WPA_NONCE_LEN); +@@ -1159,6 +1177,7 @@ skip_rsnie: + wpa_tdls_peer_free(sm, peer); + return -1; + } ++ peer->tk_set = 0; /* A new nonce results in a new TK */ + wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", + peer->inonce, WPA_NONCE_LEN); + os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); +@@ -1751,6 +1770,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, + } + + ++static int tdls_nonce_set(const u8 *nonce) ++{ ++ int i; ++ ++ for (i = 0; i < WPA_NONCE_LEN; i++) { ++ if (nonce[i]) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++ + static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, + const u8 *buf, size_t len) + { +@@ -2004,7 +2036,8 @@ skip_rsn: + peer->rsnie_i_len = kde.rsn_ie_len; + peer->cipher = cipher; + +- if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { ++ if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || ++ !tdls_nonce_set(peer->inonce)) { + /* + * There is no point in updating the RNonce for every obtained + * TPK M1 frame (e.g., retransmission due to timeout) with the +@@ -2020,6 +2053,7 @@ skip_rsn: + "TDLS: Failed to get random data for responder nonce"); + goto error; + } ++ peer->tk_set = 0; /* A new nonce results in a new TK */ + } + + #if 0 +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch b/SOURCES/rh1495527-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch new file mode 100644 index 0000000..85ea1d6 --- /dev/null +++ b/SOURCES/rh1495527-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch @@ -0,0 +1,43 @@ +From 53c5eb58e95004f86e65ee9fbfccbc291b139057 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Fri, 22 Sep 2017 11:25:02 +0300 +Subject: [PATCH 7/8] WNM: Ignore WNM-Sleep Mode Response without pending + request + +Commit 03ed0a52393710be6bdae657d1b36efa146520e5 ('WNM: Ignore WNM-Sleep +Mode Response if WNM-Sleep Mode has not been used') started ignoring the +response when no WNM-Sleep Mode Request had been used during the +association. This can be made tighter by clearing the used flag when +successfully processing a response. This adds an additional layer of +protection against unexpected retransmissions of the response frame. + +Signed-off-by: Jouni Malinen +--- + wpa_supplicant/wnm_sta.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c +index 1b3409c..67a07ff 100644 +--- a/wpa_supplicant/wnm_sta.c ++++ b/wpa_supplicant/wnm_sta.c +@@ -260,7 +260,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, + + if (!wpa_s->wnmsleep_used) { + wpa_printf(MSG_DEBUG, +- "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode has not been used in this association"); ++ "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested"); + return; + } + +@@ -299,6 +299,8 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, + return; + } + ++ wpa_s->wnmsleep_used = 0; ++ + if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT || + wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) { + wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response " +-- +2.7.4 + diff --git a/SOURCES/rh1495527-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch b/SOURCES/rh1495527-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch new file mode 100644 index 0000000..b9678f6 --- /dev/null +++ b/SOURCES/rh1495527-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch @@ -0,0 +1,82 @@ +From b372ab0b7daea719749194dc554b26e6367603f2 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Fri, 22 Sep 2017 12:06:37 +0300 +Subject: [PATCH 8/8] FT: Do not allow multiple Reassociation Response frames + +The driver is expected to not report a second association event without +the station having explicitly request a new association. As such, this +case should not be reachable. However, since reconfiguring the same +pairwise or group keys to the driver could result in nonce reuse issues, +be extra careful here and do an additional state check to avoid this +even if the local driver ends up somehow accepting an unexpected +Reassociation Response frame. + +Signed-off-by: Jouni Malinen +--- + src/rsn_supp/wpa.c | 3 +++ + src/rsn_supp/wpa_ft.c | 8 ++++++++ + src/rsn_supp/wpa_i.h | 1 + + 3 files changed, 12 insertions(+) + +diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c +index 0550a41..2a53c6f 100644 +--- a/src/rsn_supp/wpa.c ++++ b/src/rsn_supp/wpa.c +@@ -2440,6 +2440,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm) + #ifdef CONFIG_TDLS + wpa_tdls_disassoc(sm); + #endif /* CONFIG_TDLS */ ++#ifdef CONFIG_IEEE80211R ++ sm->ft_reassoc_completed = 0; ++#endif /* CONFIG_IEEE80211R */ + + /* Keys are not needed in the WPA state machine anymore */ + wpa_sm_drop_sa(sm); +diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c +index 205793e..d45bb45 100644 +--- a/src/rsn_supp/wpa_ft.c ++++ b/src/rsn_supp/wpa_ft.c +@@ -153,6 +153,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, + u16 capab; + + sm->ft_completed = 0; ++ sm->ft_reassoc_completed = 0; + + buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + + 2 + sm->r0kh_id_len + ric_ies_len + 100; +@@ -681,6 +682,11 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, + return -1; + } + ++ if (sm->ft_reassoc_completed) { ++ wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission"); ++ return 0; ++ } ++ + if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { + wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); + return -1; +@@ -781,6 +787,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, + return -1; + } + ++ sm->ft_reassoc_completed = 1; ++ + if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0) + return -1; + +diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h +index 41f371f..56f88dc 100644 +--- a/src/rsn_supp/wpa_i.h ++++ b/src/rsn_supp/wpa_i.h +@@ -128,6 +128,7 @@ struct wpa_sm { + size_t r0kh_id_len; + u8 r1kh_id[FT_R1KH_ID_LEN]; + int ft_completed; ++ int ft_reassoc_completed; + int over_the_ds_in_progress; + u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ + int set_ptk_after_assoc; +-- +2.7.4 + diff --git a/SOURCES/rh1500442-wpa_supplicant-Fix-memory-leaks-in-ieee802_1x_create.patch b/SOURCES/rh1500442-wpa_supplicant-Fix-memory-leaks-in-ieee802_1x_create.patch new file mode 100644 index 0000000..ae2773e --- /dev/null +++ b/SOURCES/rh1500442-wpa_supplicant-Fix-memory-leaks-in-ieee802_1x_create.patch @@ -0,0 +1,83 @@ +From 22151b111b493d4604c9490327c40fdac7bc4b37 Mon Sep 17 00:00:00 2001 +Message-Id: <22151b111b493d4604c9490327c40fdac7bc4b37.1525684664.git.davide.caratti@gmail.com> +From: Davide Caratti +Date: Thu, 8 Mar 2018 17:15:02 +0100 +Subject: [PATCH] wpa_supplicant: Fix memory leaks in + ieee802_1x_create_preshared_mka() + +In case MKA is initialized successfully, local copies of CAK and CKN +were allocated, but never freed. Ensure that such memory is released +also when ieee802_1x_kay_create_mka() returns a valid pointer. + +Fixes: ad51731abf06 ("wpa_supplicant: Allow pre-shared (CAK,CKN) pair for MKA") +Signed-off-by: Davide Caratti +--- + wpa_supplicant/wpas_kay.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c +index 11708b8a6..d3d06b8ae 100644 +--- a/wpa_supplicant/wpas_kay.c ++++ b/wpa_supplicant/wpas_kay.c +@@ -392,25 +392,25 @@ void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, + { + struct mka_key *cak; + struct mka_key_name *ckn; +- void *res; ++ void *res = NULL; + + if ((ssid->mka_psk_set & MKA_PSK_SET) != MKA_PSK_SET) +- return NULL; +- +- if (ieee802_1x_alloc_kay_sm(wpa_s, ssid) < 0) +- return NULL; +- +- if (!wpa_s->kay || wpa_s->kay->policy == DO_NOT_SECURE) +- return NULL; ++ goto end; + + ckn = os_zalloc(sizeof(*ckn)); + if (!ckn) +- goto dealloc; ++ goto end; + + cak = os_zalloc(sizeof(*cak)); + if (!cak) + goto free_ckn; + ++ if (ieee802_1x_alloc_kay_sm(wpa_s, ssid) < 0 || !wpa_s->kay) ++ goto free_cak; ++ ++ if (wpa_s->kay->policy == DO_NOT_SECURE) ++ goto dealloc; ++ + cak->len = MACSEC_CAK_LEN; + os_memcpy(cak->key, ssid->mka_cak, cak->len); + +@@ -419,17 +419,15 @@ void * ieee802_1x_create_preshared_mka(struct wpa_supplicant *wpa_s, + + res = ieee802_1x_kay_create_mka(wpa_s->kay, ckn, cak, 0, PSK, FALSE); + if (res) +- return res; ++ goto free_cak; + ++dealloc: + /* Failed to create MKA */ ++ ieee802_1x_dealloc_kay_sm(wpa_s); ++free_cak: + os_free(cak); +- +- /* fallthrough */ +- + free_ckn: + os_free(ckn); +-dealloc: +- ieee802_1x_dealloc_kay_sm(wpa_s); +- +- return NULL; ++end: ++ return res; + } +-- +2.14.3 + diff --git a/SOURCES/rh1531254-common-Avoid-conflict-with-__bitwise-macro-from-linu.patch b/SOURCES/rh1531254-common-Avoid-conflict-with-__bitwise-macro-from-linu.patch new file mode 100644 index 0000000..cb0ae12 --- /dev/null +++ b/SOURCES/rh1531254-common-Avoid-conflict-with-__bitwise-macro-from-linu.patch @@ -0,0 +1,40 @@ +From f5b74b966c942feb95a8ddbb7d130540b15b796d Mon Sep 17 00:00:00 2001 +Message-Id: +From: Beniamino Galvani +Date: Mon, 30 Oct 2017 11:14:40 +0100 +Subject: [PATCH] common: Avoid conflict with __bitwise macro from + linux/types.h + +Undefine the __bitwise macro before defining it to avoid conflicts +with the one from linux/types.h; the same is done some lines above +when __CHECKER__ is defined. Fixes the following warning: + + In file included from ../src/l2_packet/l2_packet_linux.c:15:0: + hostap/src/utils/common.h:438:0: warning: "__bitwise" redefined + #define __bitwise + + In file included from /usr/include/linux/filter.h:9:0, + from ../src/l2_packet/l2_packet_linux.c:13: + /usr/include/linux/types.h:21:0: note: this is the location of the previous definition + #define __bitwise __bitwise__ + +Signed-off-by: Beniamino Galvani +--- + src/utils/common.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/utils/common.h b/src/utils/common.h +index 46e96a65b..fec7f6013 100644 +--- a/src/utils/common.h ++++ b/src/utils/common.h +@@ -435,6 +435,7 @@ void perror(const char *s); + #define __bitwise __attribute__((bitwise)) + #else + #define __force ++#undef __bitwise + #define __bitwise + #endif + +-- +2.13.6 + diff --git a/SOURCES/rh1619553-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch b/SOURCES/rh1619553-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch new file mode 100644 index 0000000..a62b52c --- /dev/null +++ b/SOURCES/rh1619553-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch @@ -0,0 +1,44 @@ +From 3e34cfdff6b192fe337c6fb3f487f73e96582961 Mon Sep 17 00:00:00 2001 +From: Mathy Vanhoef +Date: Sun, 15 Jul 2018 01:25:53 +0200 +Subject: [PATCH] WPA: Ignore unauthenticated encrypted EAPOL-Key data + +Ignore unauthenticated encrypted EAPOL-Key data in supplicant +processing. When using WPA2, these are frames that have the Encrypted +flag set, but not the MIC flag. + +When using WPA2, EAPOL-Key frames that had the Encrypted flag set but +not the MIC flag, had their data field decrypted without first verifying +the MIC. In case the data field was encrypted using RC4 (i.e., when +negotiating TKIP as the pairwise cipher), this meant that +unauthenticated but decrypted data would then be processed. An adversary +could abuse this as a decryption oracle to recover sensitive information +in the data field of EAPOL-Key messages (e.g., the group key). +(CVE-2018-14526) + +Signed-off-by: Mathy Vanhoef +--- + src/rsn_supp/wpa.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff -upr wpa_supplicant-2.6.orig/src/rsn_supp/wpa.c wpa_supplicant-2.6/src/rsn_supp/wpa.c +--- wpa_supplicant-2.6.orig/src/rsn_supp/wpa.c 2016-10-02 21:51:11.000000000 +0300 ++++ wpa_supplicant-2.6/src/rsn_supp/wpa.c 2018-08-08 16:55:11.506831029 +0300 +@@ -2016,6 +2016,17 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, c + + if ((sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) && + (key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) { ++ /* ++ * Only decrypt the Key Data field if the frame's authenticity ++ * was verified. When using AES-SIV (FILS), the MIC flag is not ++ * set, so this check should only be performed if mic_len != 0 ++ * which is the case in this code branch. ++ */ ++ if (!(key_info & WPA_KEY_INFO_MIC)) { ++ wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, ++ "WPA: Ignore EAPOL-Key with encrypted but unauthenticated data"); ++ goto out; ++ } + if (wpa_supplicant_decrypt_key_data(sm, key, ver, key_data, + &key_data_len)) + goto out; diff --git a/SOURCES/rh837402-less-aggressive-roaming.patch b/SOURCES/rh837402-less-aggressive-roaming.patch new file mode 100644 index 0000000..172967a --- /dev/null +++ b/SOURCES/rh837402-less-aggressive-roaming.patch @@ -0,0 +1,25 @@ +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -1443,16 +1443,14 @@ static int wpa_supplicant_need_to_roam(s + + min_diff = 2; + if (current_bss->level < 0) { +- if (current_bss->level < -85) +- min_diff = 1; +- else if (current_bss->level < -80) +- min_diff = 2; +- else if (current_bss->level < -75) +- min_diff = 3; +- else if (current_bss->level < -70) ++ if (current_bss->level < -75) + min_diff = 4; ++ else if (current_bss->level < -70) ++ min_diff = 6; ++ else if (current_bss->level < -65) ++ min_diff = 8; + else +- min_diff = 5; ++ min_diff = 15; + } + if (to_5ghz) { + /* Make it easier to move to 5 GHz band */ diff --git a/SOURCES/wpa_supplicant-assoc-timeout.patch b/SOURCES/wpa_supplicant-assoc-timeout.patch new file mode 100644 index 0000000..c330f58 --- /dev/null +++ b/SOURCES/wpa_supplicant-assoc-timeout.patch @@ -0,0 +1,15 @@ +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -2632,10 +2632,10 @@ static void wpas_start_assoc_cb(struct w + + if (assoc_failed) { + /* give IBSS a bit more time */ +- timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5; ++ timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10; + } else if (wpa_s->conf->ap_scan == 1) { + /* give IBSS a bit more time */ +- timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10; ++ timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 20; + } + wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); + } diff --git a/SOURCES/wpa_supplicant-dbus-service-file-args.patch b/SOURCES/wpa_supplicant-dbus-service-file-args.patch new file mode 100644 index 0000000..47942fe --- /dev/null +++ b/SOURCES/wpa_supplicant-dbus-service-file-args.patch @@ -0,0 +1,18 @@ +--- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in ++++ b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in +@@ -1,5 +1,5 @@ + [D-BUS Service] + Name=fi.w1.wpa_supplicant1 +-Exec=@BINDIR@/wpa_supplicant -u ++Exec=@BINDIR@/wpa_supplicant -B -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf -P /var/run/wpa_supplicant.pid + User=root + SystemdService=wpa_supplicant.service +--- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in ++++ b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in +@@ -1,5 +1,5 @@ + [D-BUS Service] + Name=fi.epitest.hostap.WPASupplicant +-Exec=@BINDIR@/wpa_supplicant -u ++Exec=@BINDIR@/wpa_supplicant -B -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf -P /var/run/wpa_supplicant.pid + User=root + SystemdService=wpa_supplicant.service diff --git a/SOURCES/wpa_supplicant-flush-debug-output.patch b/SOURCES/wpa_supplicant-flush-debug-output.patch new file mode 100644 index 0000000..937d4b4 --- /dev/null +++ b/SOURCES/wpa_supplicant-flush-debug-output.patch @@ -0,0 +1,49 @@ +--- a/src/utils/wpa_debug.c ++++ b/src/utils/wpa_debug.c +@@ -75,6 +75,7 @@ void wpa_debug_print_timestamp(void) + if (out_file) { + fprintf(out_file, "%ld.%06u: ", (long) tv.sec, + (unsigned int) tv.usec); ++ fflush(out_file); + } else + #endif /* CONFIG_DEBUG_FILE */ + printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec); +@@ -221,6 +222,7 @@ void wpa_printf(int level, const char *f + if (out_file) { + vfprintf(out_file, fmt, ap); + fprintf(out_file, "\n"); ++ fflush(out_file); + } else { + #endif /* CONFIG_DEBUG_FILE */ + vprintf(fmt, ap); +@@ -357,6 +359,7 @@ static void _wpa_hexdump(int level, cons + fprintf(out_file, " [REMOVED]"); + } + fprintf(out_file, "\n"); ++ fflush(out_file); + } else { + #endif /* CONFIG_DEBUG_FILE */ + printf("%s - hexdump(len=%lu):", title, (unsigned long) len); +@@ -425,12 +428,14 @@ static void _wpa_hexdump_ascii(int level + fprintf(out_file, + "%s - hexdump_ascii(len=%lu): [REMOVED]\n", + title, (unsigned long) len); ++ fflush(out_file); + return; + } + if (buf == NULL) { + fprintf(out_file, + "%s - hexdump_ascii(len=%lu): [NULL]\n", + title, (unsigned long) len); ++ fflush(out_file); + return; + } + fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n", +@@ -455,6 +460,7 @@ static void _wpa_hexdump_ascii(int level + pos += llen; + len -= llen; + } ++ fflush(out_file); + } else { + #endif /* CONFIG_DEBUG_FILE */ + if (!show) { diff --git a/SOURCES/wpa_supplicant-gui-qt4.patch b/SOURCES/wpa_supplicant-gui-qt4.patch new file mode 100644 index 0000000..1d0345c --- /dev/null +++ b/SOURCES/wpa_supplicant-gui-qt4.patch @@ -0,0 +1,15 @@ +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -1807,10 +1807,10 @@ wpa_gui: + @echo "wpa_gui has been removed - see wpa_gui-qt4 for replacement" + + wpa_gui-qt4/Makefile: +- qmake -o wpa_gui-qt4/Makefile wpa_gui-qt4/wpa_gui.pro ++ qmake-qt4 -o wpa_gui-qt4/Makefile wpa_gui-qt4/wpa_gui.pro + + wpa_gui-qt4/lang/wpa_gui_de.qm: wpa_gui-qt4/lang/wpa_gui_de.ts +- lrelease wpa_gui-qt4/wpa_gui.pro ++ lrelease-qt4 wpa_gui-qt4/wpa_gui.pro + + wpa_gui-qt4: wpa_gui-qt4/Makefile wpa_gui-qt4/lang/wpa_gui_de.qm + $(MAKE) -C wpa_gui-qt4 diff --git a/SOURCES/wpa_supplicant-quiet-scan-results-message.patch b/SOURCES/wpa_supplicant-quiet-scan-results-message.patch new file mode 100644 index 0000000..9b9da44 --- /dev/null +++ b/SOURCES/wpa_supplicant-quiet-scan-results-message.patch @@ -0,0 +1,16 @@ +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -1555,11 +1555,11 @@ static int _wpa_supplicant_event_scan_re + if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && + wpa_s->manual_scan_use_id && wpa_s->own_scan_running && + own_request && !(data && data->scan_info.external_scan)) { +- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u", ++ wpa_msg_ctrl(wpa_s, MSG_DEBUG, WPA_EVENT_SCAN_RESULTS "id=%u", + wpa_s->manual_scan_id); + wpa_s->manual_scan_use_id = 0; + } else { +- wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); ++ wpa_msg_ctrl(wpa_s, MSG_DEBUG, WPA_EVENT_SCAN_RESULTS); + } + wpas_notify_scan_results(wpa_s); + diff --git a/SOURCES/wpa_supplicant.conf b/SOURCES/wpa_supplicant.conf new file mode 100644 index 0000000..65ad645 --- /dev/null +++ b/SOURCES/wpa_supplicant.conf @@ -0,0 +1,3 @@ +ctrl_interface=/var/run/wpa_supplicant +ctrl_interface_group=wheel + diff --git a/SOURCES/wpa_supplicant.logrotate b/SOURCES/wpa_supplicant.logrotate new file mode 100644 index 0000000..bd7ef91 --- /dev/null +++ b/SOURCES/wpa_supplicant.logrotate @@ -0,0 +1,6 @@ +/var/log/wpa_supplicant.log { + missingok + notifempty + size 30k + create 0600 root root +} diff --git a/SOURCES/wpa_supplicant.service b/SOURCES/wpa_supplicant.service new file mode 100644 index 0000000..45d8b99 --- /dev/null +++ b/SOURCES/wpa_supplicant.service @@ -0,0 +1,14 @@ +[Unit] +Description=WPA Supplicant daemon +Before=network.target +After=syslog.target + +[Service] +Type=dbus +BusName=fi.w1.wpa_supplicant1 +EnvironmentFile=-/etc/sysconfig/wpa_supplicant +ExecStart=/usr/sbin/wpa_supplicant -u -f /var/log/wpa_supplicant.log -c /etc/wpa_supplicant/wpa_supplicant.conf $INTERFACES $DRIVERS $OTHER_ARGS + +[Install] +WantedBy=multi-user.target + diff --git a/SOURCES/wpa_supplicant.sysconfig b/SOURCES/wpa_supplicant.sysconfig new file mode 100644 index 0000000..2ec8486 --- /dev/null +++ b/SOURCES/wpa_supplicant.sysconfig @@ -0,0 +1,16 @@ +# Use the flag "-i" before each of your interfaces, like so: +# INTERFACES="-ieth1 -iwlan0" +INTERFACES="" + +# Use the flag "-D" before each driver, like so: +# DRIVERS="-Dwext" +DRIVERS="" + +# Other arguments +# -u Enable the D-Bus interface (required for use with NetworkManager) +# -f Log to /var/log/wpa_supplicant.log +# -P Write pid file to /var/run/wpa_supplicant.pid +# required to return proper codes by init scripts (e.g. double "start" action) +# -B to daemonize that has to be used together with -P is already in wpa_supplicant.init.d +OTHER_ARGS="-P /var/run/wpa_supplicant.pid" + diff --git a/SPECS/wpa_supplicant.spec b/SPECS/wpa_supplicant.spec new file mode 100644 index 0000000..d41dcfc --- /dev/null +++ b/SPECS/wpa_supplicant.spec @@ -0,0 +1,782 @@ +%define rcver %{nil} +%define snapshot %{nil} + +%global _hardened_build 1 + +Summary: WPA/WPA2/IEEE 802.1X Supplicant +Name: wpa_supplicant +Epoch: 1 +Version: 2.6 +Release: 12%{?dist} +License: BSD +Group: System Environment/Base +Source0: http://w1.fi/releases/%{name}-%{version}%{rcver}%{snapshot}.tar.gz +Source1: build-config +Source2: %{name}.conf +Source3: %{name}.service +Source4: %{name}.sysconfig +Source6: %{name}.logrotate +Source7: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/linux/if_macsec.h?h=v4.10#/if_macsec.h +Source8: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/linux/if_link.h?h=v4.10#/if_link.h + +%define build_gui 1 +%if 0%{?rhel} >= 1 +%define build_gui 0 +%endif + +# RHEL-7 doesn't define _rundir macro yet +# Fedora 15 onwards uses /run as _rundir +%if 0%{!?_rundir:1} +%define _rundir /run +%endif + +# distro specific customization and not suitable for upstream, +# works around busted drivers +Patch0: wpa_supplicant-assoc-timeout.patch +# ensures that debug output gets flushed immediately to help diagnose driver +# bugs, not suitable for upstream +Patch1: wpa_supplicant-flush-debug-output.patch +# disto specific customization for log paths, not suitable for upstream +Patch2: wpa_supplicant-dbus-service-file-args.patch +# quiet an annoying and frequent syslog message +Patch3: wpa_supplicant-quiet-scan-results-message.patch +# distro specific customization for Qt4 build tools, not suitable for upstream +Patch6: wpa_supplicant-gui-qt4.patch +# Less aggressive roaming; signal strength is wildly variable +Patch8: rh837402-less-aggressive-roaming.patch +# backport of macsec series +Patch9: macsec-0001-mka-Move-structs-transmit-receive-_-sa-sc-to-a-commo.patch +Patch10: macsec-0002-mka-Pass-full-structures-down-to-macsec-drivers-pack.patch +Patch11: macsec-0003-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch +Patch12: macsec-0004-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch +Patch13: macsec-0005-mka-Pass-full-structures-down-to-macsec-drivers-tran.patch +Patch14: macsec-0006-mka-Pass-full-structures-down-to-macsec-drivers-rece.patch +Patch15: macsec-0007-mka-Add-driver-op-to-get-macsec-capabilities.patch +Patch16: macsec-0008-mka-Remove-channel-hacks-from-the-stack-and-the-macs.patch +Patch17: macsec-0009-mka-Sync-structs-definitions-with-IEEE-Std-802.1X-20.patch +Patch18: macsec-0010-mka-Add-support-for-removing-SAs.patch +Patch19: macsec-0011-mka-Implement-reference-counting-on-data_key.patch +Patch20: macsec-0012-mka-Fix-getting-capabilities-from-the-driver.patch +Patch21: macsec-0013-wpa_supplicant-Allow-pre-shared-CAK-CKN-pair-for-MKA.patch +Patch22: macsec-0014-mka-Disable-peer-detection-timeout-for-PSK-mode.patch +Patch23: macsec-0015-wpa_supplicant-Add-macsec_integ_only-setting-for-MKA.patch +Patch24: macsec-0016-mka-Add-enable_encrypt-op-and-call-it-from-CP-state-.patch +Patch25: macsec-0017-wpa_supplicant-Allow-configuring-the-MACsec-port-for.patch +Patch26: macsec-0018-drivers-Move-common-definitions-for-wired-drivers-ou.patch +Patch27: macsec-0019-drivers-Move-wired_multicast_membership-to-a-common-.patch +Patch28: macsec-0020-drivers-Move-driver_wired_multi-to-a-common-file.patch +Patch29: macsec-0021-drivers-Move-driver_wired_get_ifflags-to-a-common-fi.patch +Patch30: macsec-0022-drivers-Move-driver_wired_set_ifflags-to-a-common-fi.patch +Patch31: macsec-0023-drivers-Move-driver_wired_get_ifstatus-to-a-common-f.patch +Patch32: macsec-0024-drivers-Move-driver_wired_init_common-to-a-common-fi.patch +Patch33: macsec-0025-drivers-Move-driver_wired_deinit_common-to-a-common-.patch +Patch34: macsec-0026-drivers-Move-driver_wired_get_capa-to-a-common-file.patch +Patch35: macsec-0027-drivers-Move-driver_wired_get_bssid-to-a-common-file.patch +Patch36: macsec-0028-drivers-Move-driver_wired_get_ssid-to-a-common-file.patch +Patch37: macsec-0029-macsec_linux-Add-a-driver-for-macsec-on-Linux-kernel.patch +Patch38: macsec-0030-mka-Remove-references-to-macsec_qca-from-wpa_supplic.patch +Patch39: macsec-0031-PAE-Make-KaY-specific-details-available-via-control-.patch +Patch40: macsec-0032-mka-Make-MKA-actor-priority-configurable.patch +Patch41: macsec-0033-mka-Fix-an-incorrect-update-of-participant-to_use_sa.patch +Patch42: macsec-0034-mka-Some-bug-fixes-for-MACsec-in-PSK-mode.patch +Patch43: macsec-0035-mka-Send-MKPDUs-forever-if-mode-is-PSK.patch +# upstream patch not in 2.6 +Patch44: rh1447073-nl80211-Fix-race-condition-in-detecting-MAC-change.patch +Patch45: rh1440646-macsec_linux-Fix-NULL-pointer-dereference-on-error-c.patch +Patch46: rh1489919-mka-Add-error-handling-for-secy_init_macsec-calls.patch +Patch47: rh1495527-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch +Patch48: rh1495527-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch +Patch49: rh1495527-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch +Patch50: rh1495527-0004-Prevent-installation-of-an-all-zero-TK.patch +Patch51: rh1495527-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch +Patch52: rh1495527-0006-TDLS-Reject-TPK-TK-reconfiguration.patch +Patch53: rh1495527-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch +Patch54: rh1495527-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch +Patch55: rh1531254-common-Avoid-conflict-with-__bitwise-macro-from-linu.patch +Patch56: rh1434434-wpa_supplicant-Don-t-reply-to-EAPOL-if-pkt_type-is-P.patch +Patch57: rh1490885-fix-auth-failure-when-the-mac-is-updated-externally.patch +Patch58: rh1500442-wpa_supplicant-Fix-memory-leaks-in-ieee802_1x_create.patch +Patch59: rh1619553-0001-WPA-Ignore-unauthenticated-encrypted-EAPOL-Key-data.patch + +URL: http://w1.fi/wpa_supplicant/ + +%if %{build_gui} +BuildRequires: qt-devel >= 4.0 +%endif +BuildRequires: openssl-devel +BuildRequires: readline-devel +BuildRequires: dbus-devel +BuildRequires: libnl3-devel +BuildRequires: systemd-units +BuildRequires: docbook-utils +Requires(post): systemd-sysv +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +%description +wpa_supplicant is a WPA Supplicant for Linux, BSD and Windows with support +for WPA and WPA2 (IEEE 802.11i / RSN). Supplicant is the IEEE 802.1X/WPA +component that is used in the client stations. It implements key negotiation +with a WPA Authenticator and it controls the roaming and IEEE 802.11 +authentication/association of the wlan driver. + +%if %{build_gui} + +%package gui +Summary: Graphical User Interface for %{name} +Group: Applications/System + +%description gui +Graphical User Interface for wpa_supplicant written using QT + +%endif + +%prep +%setup -q -n %{name}-%{version}%{rcver} + +mkdir -p src/linux +cp %{SOURCE7} src/linux/if_macsec.h +cp %{SOURCE8} src/linux/if_link.h + +%patch0 -p1 -b .assoc-timeout +%patch1 -p1 -b .flush-debug-output +%patch2 -p1 -b .dbus-service-file +%patch3 -p1 -b .quiet-scan-results-msg +%patch6 -p1 -b .qt4 +%patch8 -p1 -b .rh837402-less-aggressive-roaming +%patch9 -p1 -b .macsec-0001 +%patch10 -p1 -b .macsec-0002 +%patch11 -p1 -b .macsec-0003 +%patch12 -p1 -b .macsec-0004 +%patch13 -p1 -b .macsec-0005 +%patch14 -p1 -b .macsec-0006 +%patch15 -p1 -b .macsec-0007 +%patch16 -p1 -b .macsec-0008 +%patch17 -p1 -b .macsec-0009 +%patch18 -p1 -b .macsec-0010 +%patch19 -p1 -b .macsec-0011 +%patch20 -p1 -b .macsec-0012 +%patch21 -p1 -b .macsec-0013 +%patch22 -p1 -b .macsec-0014 +%patch23 -p1 -b .macsec-0015 +%patch24 -p1 -b .macsec-0016 +%patch25 -p1 -b .macsec-0017 +%patch26 -p1 -b .macsec-0018 +%patch27 -p1 -b .macsec-0019 +%patch28 -p1 -b .macsec-0020 +%patch29 -p1 -b .macsec-0021 +%patch30 -p1 -b .macsec-0022 +%patch31 -p1 -b .macsec-0023 +%patch32 -p1 -b .macsec-0024 +%patch33 -p1 -b .macsec-0025 +%patch34 -p1 -b .macsec-0026 +%patch35 -p1 -b .macsec-0027 +%patch36 -p1 -b .macsec-0028 +%patch37 -p1 -b .macsec-0029 +%patch38 -p1 -b .macsec-0030 +%patch39 -p1 -b .macsec-0031 +%patch40 -p1 -b .macsec-0032 +%patch41 -p1 -b .macsec-0033 +%patch42 -p1 -b .macsec-0034 +%patch43 -p1 -b .macsec-0035 +%patch44 -p1 -b .rh1447073-detect-mac-change +%patch45 -p1 -b .rh1440646-macsec-segfault +%patch46 -p1 -b .rh1489919-macsec-eapol-segfault +%patch47 -p1 -b .rh1495527-0001 +%patch48 -p1 -b .rh1495527-0002 +%patch49 -p1 -b .rh1495527-0003 +%patch50 -p1 -b .rh1495527-0004 +%patch51 -p1 -b .rh1495527-0005 +%patch52 -p1 -b .rh1495527-0006 +%patch53 -p1 -b .rh1495527-0007 +%patch54 -p1 -b .rh1495527-0008 +%patch55 -p1 -b .rh1531254-fix-bitwise-redefined +%patch56 -p1 -b .rh1434434-fix-pkt_otherhost +%patch57 -p1 -b .rh1490885-mac-changed-event +%patch58 -p1 -b .rh1500442-macsec-memleak +%patch59 -p1 -b .rh1619553-ignore-unauth-eapol + +%build +pushd wpa_supplicant + cp %{SOURCE1} .config + CFLAGS="${CFLAGS:-%optflags} -fPIE -DPIE" ; export CFLAGS ; + CXXFLAGS="${CXXFLAGS:-%optflags} -fPIE -DPIE" ; export CXXFLAGS ; + LDFLAGS="${LDFLAGS:-%optflags} -pie -Wl,-z,now,-z,relro" ; export LDFLAGS ; + # yes, BINDIR=_sbindir + BINDIR="%{_sbindir}" ; export BINDIR ; + LIBDIR="%{_libdir}" ; export LIBDIR ; + make %{_smp_mflags} V=1 +%if %{build_gui} + QTDIR=%{_libdir}/qt4 make wpa_gui-qt4 %{_smp_mflags} +%endif + make eapol_test V=1 +popd + +pushd wpa_supplicant/doc/docbook + make man V=1 +popd + +%install +# init scripts +install -D -m 0644 %{SOURCE3} %{buildroot}/%{_unitdir}/%{name}.service +install -D -m 0644 %{SOURCE4} %{buildroot}/%{_sysconfdir}/sysconfig/%{name} +install -D -m 0644 %{SOURCE6} %{buildroot}/%{_sysconfdir}/logrotate.d/%{name} + +# config +install -D -m 0600 %{SOURCE2} %{buildroot}/%{_sysconfdir}/%{name}/%{name}.conf + +# binary +install -d %{buildroot}/%{_sbindir} +install -m 0755 %{name}/wpa_passphrase %{buildroot}/%{_sbindir} +install -m 0755 %{name}/wpa_cli %{buildroot}/%{_sbindir} +install -m 0755 %{name}/wpa_supplicant %{buildroot}/%{_sbindir} +install -m 0755 %{name}/eapol_test %{buildroot}/%{_sbindir} +install -D -m 0644 %{name}/dbus/dbus-wpa_supplicant.conf %{buildroot}/%{_sysconfdir}/dbus-1/system.d/wpa_supplicant.conf +install -D -m 0644 %{name}/dbus/fi.w1.wpa_supplicant1.service %{buildroot}/%{_datadir}/dbus-1/system-services/fi.w1.wpa_supplicant1.service +install -D -m 0644 %{name}/dbus/fi.epitest.hostap.WPASupplicant.service %{buildroot}/%{_datadir}/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service + +%if %{build_gui} +# gui +install -d %{buildroot}/%{_bindir} +install -m 0755 %{name}/wpa_gui-qt4/wpa_gui %{buildroot}/%{_bindir} +%endif + +install -d -m 0755 %{buildroot}%{_rundir}/%{name} + +# man pages +install -d %{buildroot}%{_mandir}/man{5,8} +install -m 0644 %{name}/doc/docbook/*.8 %{buildroot}%{_mandir}/man8 +install -m 0644 %{name}/doc/docbook/*.5 %{buildroot}%{_mandir}/man5 + +# some cleanup in docs and examples +rm -f %{name}/doc/.cvsignore +rm -rf %{name}/doc/docbook +chmod -R 0644 %{name}/examples/*.py + +%post +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +fi + +%preun +if [ $1 -eq 0 ] ; then + # Package removal, not upgrade + /bin/systemctl --no-reload disable wpa_supplicant.service > /dev/null 2>&1 || : + /bin/systemctl stop wpa_supplicant.service > /dev/null 2>&1 || : +fi + +%triggerun -- wpa_supplicant < 0.7.3-10 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply wpa_supplicant +# to migrate them to systemd targets +/usr/bin/systemd-sysv-convert --save wpa_supplicant >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +/sbin/chkconfig --del wpa_supplicant >/dev/null 2>&1 || : +/bin/systemctl try-restart wpa_supplicant.service >/dev/null 2>&1 || : + + +%files +%license COPYING +%doc %{name}/ChangeLog README %{name}/eap_testing.txt %{name}/todo.txt %{name}/wpa_supplicant.conf %{name}/examples +%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %{_sysconfdir}/logrotate.d/%{name} +%{_unitdir}/%{name}.service +%{_sysconfdir}/dbus-1/system.d/%{name}.conf +%{_datadir}/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service +%{_datadir}/dbus-1/system-services/fi.w1.wpa_supplicant1.service +%{_sbindir}/wpa_passphrase +%{_sbindir}/wpa_supplicant +%{_sbindir}/wpa_cli +%{_sbindir}/eapol_test +%ghost %attr(755,root,root) %verify(not owner group) %{_rundir}/%{name} +%dir %{_sysconfdir}/%{name} +%{_mandir}/man8/* +%{_mandir}/man5/* + +%if %{build_gui} +%files gui +%{_bindir}/wpa_gui +%endif + +%changelog +* Tue Aug 28 2018 Davide Caratti - 1:2.6-12 +- Ignore unauthenticated encrypted EAPOL-Key data (CVE-2018-14526) + +* Fri Jun 1 2018 Davide Caratti - 1:2.6-11 +- Better handling of /run/wpa_supplicant (rh #1507919) + +* Fri May 18 2018 Davide Caratti - 1:2.6-10 +- Fix memory leak when macsec MKA/PSK is used (rh #1500442) +- Fix authentication failure when the MAC is updated externally (rh #1490885) +- Let the kernel discard EAPOL if packet type is PACKET_OTHERHOST (rh #1434434) +- Don't restart wpa_supplicant.service on package upgrade (rh #1505404) +- Don't own a directory in /run/ (rh #1507919) + +* Mon Jan 8 2018 Davide Caratti - 1:2.6-9 +- Fix RPMDiff failures on ppc (rh #1532320) + +* Fri Jan 5 2018 Davide Caratti - 1:2.6-8 +- Fix build issue on kernel-alt (rh #1531254) + +* Wed Oct 18 2017 Davide Caratti - 1:2.6-7 +- avoid key reinstallation (CVE-2017-13077, CVE-2017-13078, CVE-2017-13079, + CVE-2017-13080, CVE-2017-13081, CVE-2017-13082, CVE-2017-13086, + CVE-2017-13087, CVE-2017-13088) + +* Thu Oct 05 2017 Davide Caratti - 1:2.6-6 +- Fix segmentation fault on EAPOL RX if macsec.ko is not loaded (rh #1489919) + +* Wed May 17 2017 Davide Caratti - 1:2.6-5 +- macsec: Fix segmentation fault in case macsec.ko is not loaded (rh #1440646) +- nl80211: Fix race condition in detecting MAC change (rh #1447073) + +* Mon Apr 3 2017 Lubomir Rintel - 1:2.6-4 +- Include MACsec headers (rh #1438007) + +* Fri Mar 10 2017 Davide Caratti - 1:2.6-3 +- Fix coverity failures (rh #1430407) + +* Tue Mar 7 2017 Davide Caratti - 1:2.6-2 +- Backport support for IEEE 802.1AE MACsec (rh #1338005) + +* Fri Feb 10 2017 Davide Caratti - 1:2.6-1 +- Update to 2.6 (rh #1404793) + +* Fri Dec 16 2016 Davide Caratti - 1:2.0-22 +- bump revision for RHEL7.4 rebuild + +* Tue Aug 9 2016 Davide Caratti - 1:2.0-21 +- fix wpa_supplicant.sysconfig to avoid duplicate -u and -f arguments (rh #1351388) + +* Mon Mar 21 2016 Lubomir Rintel - 1:2.0-20 +- D-Bus: Don't do in dbus service file (rh #1319796) + +* Mon Jan 11 2016 Lubomir Rintel - 1:2.0-19 +- nl80211: resubscribe to netlink events when cfg80211 gets re-added (rh #1085473) + +* Tue Dec 1 2015 Jiří Klimeš - 1:2.0-18 +- spec: do not install wpa_supplicant.service as executable (rh #1286965) + +* Wed May 20 2015 Jiří Klimeš - 1:2.0-17 +- AP WMM: Fix integer underflow in WMM Action frame parser (rh #1221178) (rh #1222016) + +* Tue Apr 28 2015 Dan Winship - 1:2.0-16 +- P2P: Validate SSID element length before copying it (CVE-2015-1863) + +* Wed Jan 14 2015 - 1:2.0-15 +- Add domain_match config option from upstream (rh #1178263) +- Include peer certificate in EAP events for use by clients + +* Wed Oct 22 2014 Dan Williams - 1:2.0-14 +- Use os_exec() for action script execution (CVE-2014-3686) + +* Mon Jul 14 2014 Thomas Haller - 1:2.0-12 +- Mass rebuild 2014-01-24 + +* Mon Jan 20 2014 Dan Williams - 1:2.0-11 +- Add eapol_test manpage (rh #948453) + +* Fri Dec 27 2013 Daniel Mach - 1:2.0-10 +- Mass rebuild 2013-12-27 + +* Mon Dec 16 2013 Dan Williams - 1:2.0-9 +- Don't disconnect when PMKSA cache gets too large (rh #1032758) (rh #1016707) + +* Mon Dec 16 2013 Dan Winship - 1:2.0-8 +- Fill in some gaps in the man pages (rh #948453) + +* Wed Jul 10 2013 Dan Williams - 1:2.0-6 +- Enable full RELRO/PIE/PIC for wpa_supplicant and libeap +- Fix changelog dates + +* Wed Jul 10 2013 Dan Williams - 1:2.0-5 +- Build and package eapol_test (rh #638218) + +* Wed Jul 10 2013 Dan Williams - 1:2.0-4 +- Disable WiMAX libeap hack for RHEL + +* Wed May 15 2013 Dan Williams - 1:2.0-3 +- Enable HT (802.11n) for AP mode + +* Tue May 7 2013 Dan Williams - 1:2.0-2 +- Use hardened build macros and ensure they apply to libeap too + +* Mon May 6 2013 Dan Williams - 1:2.0-1 +- Update to 2.0 +- Be less aggressive when roaming due to signal strength changes (rh #837402) + +* Mon Apr 1 2013 Dan Williams - 1:1.1-1 +- Update to 1.1 +- Be less aggressive when roaming due to signal strength changes + +* Fri Feb 15 2013 Fedora Release Engineering - 1:1.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Sun Jan 20 2013 Dan Horák - 1:1.0-3 +- rebuilt again for fixed soname in libnl3 + +* Sun Jan 20 2013 Kalev Lember - 1:1.0-2 +- Rebuilt for libnl3 + +* Wed Aug 29 2012 Dan Williams - 1:1.0-1 +- Enable lightweight AP mode support +- Enable P2P (WiFi Direct) support +- Enable RSN IBSS/AdHoc support + +* Sun Jul 22 2012 Fedora Release Engineering - 1:1.0-0.5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue May 1 2012 Dan Williams - 1:1.0-0.4 +- Update to wpa_supplicant 1.0-rc3 +- Fix systemd target dependencies (rh #815091) + +* Fri Mar 2 2012 Dan Williams - 1:1.0-0.3 +- Update to latest 1.0 git snapshot +- Rebuild against libnl3 + +* Thu Feb 2 2012 Dan Williams - 1:1.0-0.2 +- Fix driver fallback for non nl80211-based drivers (rh #783712) + +* Tue Jan 10 2012 Dan Williams - 1:1.0-0.1 +- Update to 1.0-rc1 + git + +* Fri Sep 9 2011 Tom Callaway - 1:0.7.3-11 +- add missing systemd scriptlets + +* Thu Sep 8 2011 Tom Callaway - 1:0.7.3-10 +- convert to systemd + +* Wed Jul 27 2011 Dan Williams - 1:0.7.3-9 +- Fix various crashes with D-Bus interface (rh #678625) (rh #725517) + +* Tue May 3 2011 Dan Williams - 1:0.7.3-8 +- Don't crash when trying to access invalid properties via D-Bus (rh #678625) + +* Mon May 2 2011 Dan Williams - 1:0.7.3-7 +- Make examples read-only to avoid erroneous python dependency (rh #687952) + +* Tue Apr 19 2011 Bill Nottingham - 1:0.7.3-6 +- Fix EAP patch to only apply when building libeap + +* Fri Mar 25 2011 Bill Nottingham - 1:0.7.3-5 +- Add libeap/libeap-devel subpackge for WiMAX usage + +* Mon Feb 07 2011 Fedora Release Engineering - 1:0.7.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Jan 11 2011 Dan Williams - 1:0.7.3-3 +- Enable EAP-TNC (rh #659038) + +* Wed Dec 15 2010 Dan Williams - 1:0.7.3-2 +- Enable the bgscan_simple plugin + +* Wed Dec 8 2010 Dan Williams - 1:0.7.3-1 +- Update to 0.7.3 +- Drop upstreamed and backported patches +- Drop support for Qt3 + +* Thu Oct 7 2010 Peter Lemenkov - 1:0.6.8-11 +- Added comments to some patches (see rhbz #226544#c17) +- Shortened %%install section a bit + +* Thu May 13 2010 Dan Williams - 1:0.6.8-10 +- Remove prereq on chkconfig +- Build GUI with qt4 for rawhide (rh #537105) + +* Thu May 6 2010 Dan Williams - 1:0.6.8-9 +- Fix crash when interfaces are removed (like suspend/resume) (rh #589507) + +* Wed Jan 6 2010 Dan Williams - 1:0.6.8-8 +- Fix handling of newer PKCS#12 files (rh #541924) + +* Sun Nov 29 2009 Dan Williams - 1:0.6.8-7 +- Fix supplicant initscript return value (rh #521807) +- Fix race when connecting to WPA-Enterprise/802.1x-enabled access points (rh #508509) +- Don't double-scan when attempting to associate + +* Fri Aug 21 2009 Tomas Mraz - 1:0.6.8-6 +- rebuilt with new openssl + +* Mon Jul 27 2009 Fedora Release Engineering - 1:0.6.8-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed May 13 2009 Dan Williams - 1:0.6.8-4 +- Let D-Bus clients know when the supplicant is scanning + +* Tue May 12 2009 Dan Williams - 1:0.6.8-3 +- Ensure the supplicant starts and ends with clean driver state +- Handle driver disconnect spammage by forcibly clearing SSID +- Don't switch access points unless the current association is dire (rh #493745) + +* Tue May 12 2009 Dan Williams - 1:0.6.8-2 +- Avoid creating bogus Ad-Hoc networks when forcing the driver to disconnect (rh #497771) + +* Mon Mar 9 2009 Dan Williams - 1:0.6.8-1 +- Update to latest upstream release + +* Wed Feb 25 2009 Colin Walters - 1:0.6.7-4 +- Add patch from upstream to suppress unrequested replies, this + quiets a dbus warning. + +* Fri Feb 6 2009 Dan Williams - 1:0.6.7-3 +- Fix scan result retrieval in very dense wifi environments + +* Fri Feb 6 2009 Dan Williams - 1:0.6.7-2 +- Ensure that drivers don't retry association when they aren't supposed to + +* Fri Jan 30 2009 Dan Williams - 1:0.6.7-1 +- Fix PEAP connections to Windows Server 2008 authenticators (rh #465022) +- Stop supplicant on uninstall (rh #447843) +- Suppress scan results message in logs (rh #466601) + +* Sun Jan 18 2009 Tomas Mraz - 1:0.6.4-3 +- rebuild with new openssl + +* Wed Oct 15 2008 Dan Williams - 1:0.6.4-2 +- Handle encryption keys correctly when switching 802.11 modes (rh #459399) +- Better scanning behavior on resume from suspend/hibernate +- Better interaction with newer kernels and drivers + +* Wed Aug 27 2008 Dan Williams - 1:0.6.4-1 +- Update to 0.6.4 +- Remove 'hostap', 'madwifi', and 'prism54' drivers; use standard 'wext' instead +- Drop upstreamed patches + +* Tue Jun 10 2008 Dan Williams - 1:0.6.3-6 +- Fix 802.11a frequency bug +- Always schedule specific SSID scans to help find hidden APs +- Properly switch between modes on mac80211 drivers +- Give adhoc connections more time to assocate + +* Mon Mar 10 2008 Christopher Aillon - 1:0.6.3-5 +- BuildRequires qt3-devel + +* Sat Mar 8 2008 Dan Williams - 1:0.6.3-4 +- Fix log file path in service config file + +* Thu Mar 6 2008 Dan Williams - 1:0.6.3-3 +- Don't start the supplicant by default when installed (rh #436380) + +* Tue Mar 4 2008 Dan Williams - 1:0.6.3-2 +- Fix a potential use-after-free in the D-Bus byte array demarshalling code + +* Mon Mar 3 2008 Dan Williams - 1:0.6.3-1 +- Update to latest development release; remove upstreamed patches + +* Fri Feb 22 2008 Dan Williams 1:0.5.7-23 +- Fix gcc 4.3 rebuild issues + +* Mon Feb 18 2008 Fedora Release Engineering - 1:0.5.7-22 +- Autorebuild for GCC 4.3 + +* Tue Dec 25 2007 Dan Williams - 0.5.7-21 +- Backport 'frequency' option for Ad-Hoc network configs + +* Mon Dec 24 2007 Dan Williams - 0.5.7-20 +- Fix LSB initscript header to ensure 'messagebus' is started first (rh #244029) + +* Thu Dec 6 2007 Dan Williams - 1:0.5.7-19 +- Fix two leaks when signalling state and scan results (rh #408141) +- Add logrotate config file (rh #404181) +- Add new LSB initscript header to initscript with correct deps (rh #244029) +- Move other runtime arguments to /etc/sysconfig/wpa_supplicant +- Start after messagebus service (rh #385191) +- Fix initscript 'condrestart' command (rh #217281) + +* Tue Dec 4 2007 Matthias Clasen - 1:0.5.7-18 +- Rebuild against new openssl + +* Tue Dec 4 2007 Ville Skyttä - 1:0.5.7-17 +- Group: Application/System -> Applications/System in -gui. + +* Tue Nov 13 2007 Dan Williams - 0.5.7-16 +- Add IW_ENCODE_TEMP patch for airo driver and Dynamic WEP +- Fix error in wpa_supplicant-0.5.7-ignore-dup-ca-cert-addition.patch that + caused the last error to not be printed +- Fix wpa_supplicant-0.5.7-ignore-dup-ca-cert-addition.patch to ignore + duplicate cert additions for all certs and keys +- Change license to BSD due to linkage against OpenSSL since there is no + OpenSSL exception in the GPLv2 license text that upstream ships + +* Sun Oct 28 2007 Dan Williams - 0.5.7-15 +- Fix Dynamic WEP associations with mac80211-based drivers + +* Sun Oct 28 2007 Dan Williams - 0.5.7-14 +- Don't error an association on duplicate CA cert additions + +* Wed Oct 24 2007 Dan Williams - 0.5.7-13 +- Correctly set the length of blobs added via the D-Bus interface + +* Wed Oct 24 2007 Dan Williams - 0.5.7-12 +- Fix conversion of byte arrays to strings by ensuring the buffer is NULL + terminated after conversion + +* Sat Oct 20 2007 Dan Williams - 0.5.7-11 +- Add BLOB support to the D-Bus interface +- Fix D-Bus interface permissions so that only root can use the wpa_supplicant + D-Bus interface + +* Tue Oct 9 2007 Dan Williams - 0.5.7-10 +- Don't segfault with dbus control interface enabled and invalid network + interface (rh #310531) + +* Tue Sep 25 2007 Dan Williams - 0.5.7-9 +- Always allow explicit wireless scans triggered from a control interface + +* Thu Sep 20 2007 Dan Williams - 0.5.7-8 +- Change system bus activation file name to work around D-Bus bug that fails + to launch services unless their .service file is named the same as the + service itself + +* Fri Aug 24 2007 Dan Williams - 0.5.7-7 +- Make SIGUSR1 change debug level on-the-fly; useful in combination with + the -f switch to log output to /var/log/wpa_supplicant.log +- Stop stripping binaries on install so we get debuginfo packages +- Remove service start requirement for interfaces & devices from sysconfig file, + since wpa_supplicant's D-Bus interface is now turned on + +* Fri Aug 17 2007 Dan Williams - 0.5.7-6 +- Fix compilation with RPM_OPT_FLAGS (rh #249951) +- Make debug output to logfile a runtime option + +* Fri Aug 17 2007 Christopher Aillon - 0.5.7-5 +- Update the license tag + +* Tue Jun 19 2007 Dan Williams - 0.5.7-4 +- Fix initscripts to use -Dwext by default, be more verbose on startup + (rh #244511) + +* Mon Jun 4 2007 Dan Williams - 0.5.7-3 +- Fix buffer overflow by removing syslog patch (#rh242455) + +* Mon Apr 9 2007 Dan Williams - 0.5.7-2 +- Add patch to send output to syslog + +* Thu Mar 15 2007 Dan Williams - 0.5.7-1 +- Update to 0.5.7 stable release + +* Fri Oct 27 2006 Dan Williams - 0.4.9-1 +- Update to 0.4.9 for WE-21 fixes, remove upstreamed patches +- Don't package doc/ because they aren't actually wpa_supplicant user documentation, + and becuase it pulls in perl + +* Wed Jul 12 2006 Jesse Keating - 0.4.8-10.1 +- rebuild + +* Thu Apr 27 2006 Dan Williams - 0.4.8-10 +- Add fix for madwifi and WEP (wpa_supplicant/hostap bud #140) (#rh190075#) +- Fix up madwifi-ng private ioctl()s for r1331 and later +- Update madwifi headers to r1475 + +* Tue Apr 25 2006 Dan Williams - 0.4.8-9 +- Enable Wired driver, PKCS12, and Smartcard options (#rh189805#) + +* Tue Apr 11 2006 Dan Williams - 0.4.8-8 +- Fix control interface key obfuscation a bit + +* Sun Apr 2 2006 Dan Williams - 0.4.8-7 +- Work around older & incorrect drivers that return null-terminated SSIDs + +* Mon Mar 27 2006 Dan Williams - 0.4.8-6 +- Add patch to make orinoco happy with WEP keys +- Enable Prism54-specific driver +- Disable ipw-specific driver; ipw2x00 should be using WEXT instead + +* Fri Mar 3 2006 Dan Williams - 0.4.8-5 +- Increase association timeout, mainly for drivers that don't + fully support WPA ioctls yet + +* Fri Mar 3 2006 Dan Williams - 0.4.8-4 +- Add additional BuildRequires #rh181914# +- Add prereq on chkconfig #rh182905# #rh182906# +- Own /var/run/wpa_supplicant and /etc/wpa_supplicant #rh183696# + +* Wed Mar 1 2006 Dan Williams - 0.4.8-3 +- Install wpa_passphrase too #rh183480# + +* Mon Feb 27 2006 Dan Williams - 0.4.8-2 +- Don't expose private data on the control interface unless requested + +* Fri Feb 24 2006 Dan Williams - 0.4.8-1 +- Downgrade to 0.4.8 stable release rather than a dev release + +* Sun Feb 12 2006 Dan Williams - 0.5.1-3 +- Documentation cleanup (Terje Rosten ) + +* Sun Feb 12 2006 Dan Williams - 0.5.1-2 +- Move initscript to /etc/rc.d/init.d + +* Fri Feb 10 2006 Jesse Keating - 0.5.1-1.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 0.5.1-1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Sun Feb 5 2006 Dan Williams 0.5.1-1 +- Update to 0.5.1 +- Add WE auth fallback to actually work with older drivers + +* Thu Jan 26 2006 Dan Williams 0.4.7-2 +- Bring package into Fedora Core +- Add ap_scan control interface patch +- Enable madwifi-ng driver + +* Sun Jan 15 2006 Douglas E. Warner 0.4.7-1 +- upgrade to 0.4.7 +- added package w/ wpa_gui in it + +* Mon Nov 14 2005 Douglas E. Warner 0.4.6-1 +- upgrade to 0.4.6 +- adding ctrl interface changes recommended + by Hugo Paredes + +* Sun Oct 9 2005 Douglas E. Warner 0.4.5-1 +- upgrade to 0.4.5 +- updated config file wpa_supplicant is built with + especially, the ipw2100 driver changed to just ipw + and enabled a bunch more EAP +- disabled dist tag + +* Thu Jun 30 2005 Douglas E. Warner 0.4.2-3 +- fix typo in init script + +* Thu Jun 30 2005 Douglas E. Warner 0.4.2-2 +- fixing init script using fedora-extras' template +- removing chkconfig default startup + +* Tue Jun 21 2005 Douglas E. Warner 0.4.2-1 +- upgrade to 0.4.2 +- new sample conf file that will use any unrestricted AP +- make sysconfig config entry +- new BuildRoot for Fedora Extras +- adding dist tag to Release + +* Fri May 06 2005 Douglas E. Warner 0.3.8-1 +- upgrade to 0.3.8 + +* Thu Feb 10 2005 Douglas E. Warner 0.3.6-2 +- compile ipw driver in + +* Wed Feb 09 2005 Douglas E. Warner 0.3.6-1 +- upgrade to 0.3.6 + +* Thu Dec 23 2004 Douglas E. Warner 0.2.5-4 +- fixing init script + +* Mon Dec 20 2004 Douglas E. Warner 0.2.5-3 +- fixing init script +- adding post/preun items to add/remove via chkconfig + +* Mon Dec 20 2004 Douglas E. Warner 0.2.5-2 +- adding sysV scripts + +* Mon Dec 20 2004 Douglas E. Warner 0.2.5-1 +- Initial RPM release. +