From alex at um.es  Thu Mar  1 01:57:32 2018
From: alex at um.es (=?UTF-8?Q?Alejandro_P=c3=a9rez_M=c3=a9ndez?=)
Date: Thu, 1 Mar 2018 10:57:32 +0100
Subject: Request: add missing standard RADIUS attribute types
Message-ID: <b1b21dfc-a399-e2c0-7818-c96e6011f439@um.es>

Hello,

I'd like to request the addition of four RADIUS attribute types, that 
are missing in the radius/radius.h file. They are defined in section 7.4 
of RFC 7055. They would be:

RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 164
RADIUS_ATTR_GSS_ACCEPTOR_HOST_NAME = 165
RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_SPECIFICS = 166
RADIUS_ATTR_GSS_ACCEPTOR_REALM_NAME = 167

Thanks,
Alejandro


From dlebed at quantenna.com  Thu Mar  1 03:49:25 2018
From: dlebed at quantenna.com (Dmitrii Lebed)
Date: Thu,  1 Mar 2018 14:49:25 +0300
Subject: [PATCH 0/4] Implement supported channel BW checking
Message-ID: <20180301114929.420-1-dlebed@quantenna.com>

From: Dmitry Lebed <dlebed at quantenna.com>

Hi all,

Here is a patch set with nl80211 FREQ_ATTR_NO_* usage added.
Currently linux kernel is verifying that channel settings
are allowed in terms of supported channel BW attributes.
Sometimes HW or driver may limit some channel configurations,
but hostapd is not taking it into account and it leads to
unsupported channel can be selected manually, by ACS and by DFS,
leading to hostapd shutdown e.g. in case of wrong channel
is being selected in a response to radar event.
This patch set do not introduce support of any new channel modes,
it just adds new checks to make hostapd avaliable channel set view
consistent with linux kernel view.

Dmitry Lebed (4):
  nl80211: add supported BW parsing
  hostapd: add supported channel BW checking infrastructure
  ACS: add supported channel BW checking
  DFS: add supported channel BW checking

 src/ap/acs.c                      | 28 +++++++++--
 src/ap/dfs.c                      | 19 ++++++--
 src/ap/hw_features.c              | 45 ++++++++++--------
 src/common/hw_features_common.c   | 99 +++++++++++++++++++++++++++++++--------
 src/common/hw_features_common.h   | 11 ++++-
 src/drivers/driver.h              | 20 ++++++++
 src/drivers/driver_nl80211_capa.c | 20 ++++++++
 7 files changed, 192 insertions(+), 50 deletions(-)

--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From dlebed at quantenna.com  Thu Mar  1 03:49:26 2018
From: dlebed at quantenna.com (Dmitrii Lebed)
Date: Thu,  1 Mar 2018 14:49:26 +0300
Subject: [PATCH 1/4] nl80211: add supported BW parsing
In-Reply-To: <20180301114929.420-1-dlebed@quantenna.com>
References: <20180301114929.420-1-dlebed@quantenna.com>
Message-ID: <20180301114929.420-2-dlebed@quantenna.com>

From: Dmitry Lebed <dlebed at quantenna.com>

Add NL80211_FREQUENCY_ATTR_NO_* channel attributes parsing.
Needed for correct checking if channel is available in
particular BW.

Signed-off-by: Dmitry Lebed <dlebed at quantenna.com>
---
 src/ap/dfs.c                      |  1 -
 src/drivers/driver.h              | 20 ++++++++++++++++++++
 src/drivers/driver_nl80211_capa.c | 20 ++++++++++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index f1476eee0..8c56cbb96 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -172,7 +172,6 @@ static int is_in_chanlist(struct hostapd_iface *iface,
        return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan);
 }

-
 /*
  * The function assumes HT40+ operation.
  * Make sure to adjust the following variables after calling this:
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 92a58b2f2..37a31d3bc 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -58,6 +58,20 @@
 #define HOSTAPD_CHAN_VHT_130_30 0x04000000
 #define HOSTAPD_CHAN_VHT_150_10 0x08000000

+/* Allowed BW mask */
+enum hostapd_chan_width_attr {
+       HOSTAPD_CHAN_WIDTH_10   = BIT(0),
+       HOSTAPD_CHAN_WIDTH_20   = BIT(1),
+       HOSTAPD_CHAN_WIDTH_40P  = BIT(2),
+       HOSTAPD_CHAN_WIDTH_40M  = BIT(3),
+       HOSTAPD_CHAN_WIDTH_80   = BIT(4),
+       HOSTAPD_CHAN_WIDTH_160  = BIT(5),
+
+       /* all new elements goes before this line */
+       __HOSTAPD_CHAN_WIDTH_AFTER_LAST,
+       HOSTAPD_CHAN_WIDTH_ALL = __HOSTAPD_CHAN_WIDTH_AFTER_LAST - 2
+};
+
 /* Filter gratuitous ARP */
 #define WPA_DATA_FRAME_FILTER_FLAG_ARP BIT(0)
 /* Filter unsolicited Neighbor Advertisement */
@@ -110,6 +124,12 @@ struct hostapd_channel_data {
         */
        int flag;

+       /**
+        * allowed_bw - allowed channel width bitmask
+        * see enum hostapd_chan_width_attr
+        */
+       u32 allowed_bw;
+
        /**
         * max_tx_power - Regulatory transmit power limit in dBm
         */
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index e5bc7693b..ea6139c87 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -1286,6 +1286,7 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
        u8 channel;
        chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
        chan->flag = 0;
+       chan->allowed_bw = HOSTAPD_CHAN_WIDTH_ALL;
        chan->dfs_cac_ms = 0;
        if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
                chan->chan = channel;
@@ -1301,6 +1302,19 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
        if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
                chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;

+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
+       if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
+               chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
+
        if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
                enum nl80211_dfs_state state =
                        nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
@@ -1335,6 +1349,12 @@ static int phy_info_freqs(struct phy_info_arg *phy_info,
                [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
                [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
                [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
+               [NL80211_FREQUENCY_ATTR_NO_10MHZ] = { .type = NLA_FLAG },
+               [NL80211_FREQUENCY_ATTR_NO_20MHZ] = { .type = NLA_FLAG },
+               [NL80211_FREQUENCY_ATTR_NO_HT40_PLUS] = { .type = NLA_FLAG },
+               [NL80211_FREQUENCY_ATTR_NO_HT40_MINUS] = { .type = NLA_FLAG },
+               [NL80211_FREQUENCY_ATTR_NO_80MHZ] = { .type = NLA_FLAG },
+               [NL80211_FREQUENCY_ATTR_NO_160MHZ] = { .type = NLA_FLAG },
        };
        int new_channels = 0;
        struct hostapd_channel_data *channel;
--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From dlebed at quantenna.com  Thu Mar  1 03:49:27 2018
From: dlebed at quantenna.com (Dmitrii Lebed)
Date: Thu,  1 Mar 2018 14:49:27 +0300
Subject: [PATCH 2/4] hostapd: add supported channel BW checking infrastructure
In-Reply-To: <20180301114929.420-1-dlebed@quantenna.com>
References: <20180301114929.420-1-dlebed@quantenna.com>
Message-ID: <20180301114929.420-3-dlebed@quantenna.com>

From: Dmitry Lebed <dlebed at quantenna.com>

Additional checks added to common code to verify supported
BW options for each channel using nl80211-provided info.
No support of additional modes added, just additional checks.
Such checks are needed because driver/HW can declare more
strict limitations than declared in 802.11 spec, without
this patch hostapd may select unsupported channel and will
fail because linux kernel does check channel BW limitations.

Signed-off-by: Dmitry Lebed <dlebed at quantenna.com>
---
 src/ap/hw_features.c            | 45 ++++++++++---------
 src/common/hw_features_common.c | 99 +++++++++++++++++++++++++++++++++--------
 src/common/hw_features_common.h | 11 ++++-
 3 files changed, 114 insertions(+), 41 deletions(-)

diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 84e74eef0..cea75b85e 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -229,9 +229,6 @@ static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
 {
        int pri_chan, sec_chan;

-       if (!iface->conf->secondary_channel)
-               return 1; /* HT40 not used */
-
        pri_chan = iface->conf->channel;
        sec_chan = pri_chan + iface->conf->secondary_channel * 4;

@@ -692,31 +689,30 @@ int hostapd_check_ht_capab(struct hostapd_iface *iface)
        return 0;
 }

-
 static int hostapd_is_usable_chan(struct hostapd_iface *iface,
                                  int channel, int primary)
 {
-       int i;
        struct hostapd_channel_data *chan;

        if (!iface->current_mode)
                return 0;

-       for (i = 0; i < iface->current_mode->num_channels; i++) {
-               chan = &iface->current_mode->channels[i];
-               if (chan->chan != channel)
-                       continue;
+       chan = hw_get_channel_chan(iface->current_mode, channel, NULL);
+       if (!chan)
+               return 0;

-               if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
-                       return 1;
+       if (primary && chan_pri_allowed(chan))
+               return 1;

-               wpa_printf(MSG_DEBUG,
-                          "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s",
-                          primary ? "" : "Configured HT40 secondary ",
-                          i, chan->chan, chan->flag,
-                          chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
-                          chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
-       }
+       if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
+               return 1;
+
+       wpa_printf(MSG_DEBUG,
+                  "%schannel (%i) is disabled for use in AP mode, flags: 0x%x%s%s",
+                  primary ? "" : "Configured HT40 secondary ",
+                  chan->chan, chan->flag,
+                  chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "",
+                  chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");

        wpa_printf(MSG_INFO, "Channel %d (%s) not allowed for AP mode",
                   channel, primary ? "primary" : "secondary");
@@ -727,6 +723,13 @@ static int hostapd_is_usable_chan(struct hostapd_iface *iface,
 static int hostapd_is_usable_chans(struct hostapd_iface *iface)
 {
        int secondary_chan;
+       struct hostapd_channel_data *pri_chan;
+
+       pri_chan = hw_get_channel_chan(iface->current_mode,
+                                      iface->conf->channel, NULL);
+
+       if (!pri_chan)
+               return 0;

        if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
                return 0;
@@ -741,13 +744,15 @@ static int hostapd_is_usable_chans(struct hostapd_iface *iface)

        /* Both HT40+ and HT40- are set, pick a valid secondary channel */
        secondary_chan = iface->conf->channel + 4;
-       if (hostapd_is_usable_chan(iface, secondary_chan, 0)) {
+       if (hostapd_is_usable_chan(iface, secondary_chan, 0) &&
+           (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) {
                iface->conf->secondary_channel = 1;
                return 1;
        }

        secondary_chan = iface->conf->channel - 4;
-       if (hostapd_is_usable_chan(iface, secondary_chan, 0)) {
+       if (hostapd_is_usable_chan(iface, secondary_chan, 0) &&
+           (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M)) {
                iface->conf->secondary_channel = -1;
                return 1;
        }
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index db4037927..903c17742 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -84,35 +84,45 @@ int hw_get_chan(struct hostapd_hw_modes *mode, int freq)
 }


-int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
-                             int sec_chan)
+int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan_num,
+                             int sec_chan_num)
 {
-       int ok, j, first;
+       int ok, first;
        int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
                          149, 157, 165, 184, 192 };
        size_t k;
+       struct hostapd_channel_data *pri_chan, *sec_chan;
+       const int ht_plus = pri_chan_num < sec_chan_num ? 1 : 0;

-       if (pri_chan == sec_chan || !sec_chan)
-               return 1; /* HT40 not used */
+       pri_chan = hw_get_channel_chan(mode, pri_chan_num, NULL);
+       if (!pri_chan)
+               return 0;
+
+       if (pri_chan_num == sec_chan_num || !sec_chan_num) {
+               if (chan_pri_allowed(pri_chan)) {
+                       return 1; /* HT40 not used */
+               } else {
+                       wpa_printf(MSG_ERROR, "Channel %d is not allowed as primary",
+                                  pri_chan_num);
+                       return 0;
+               }
+       }
+
+       sec_chan = hw_get_channel_chan(mode, sec_chan_num, NULL);
+       if (!sec_chan)
+               return 0;

        wpa_printf(MSG_DEBUG,
                   "HT40: control channel: %d  secondary channel: %d",
-                  pri_chan, sec_chan);
+                  pri_chan_num, sec_chan_num);

        /* Verify that HT40 secondary channel is an allowed 20 MHz
         * channel */
-       ok = 0;
-       for (j = 0; j < mode->num_channels; j++) {
-               struct hostapd_channel_data *chan = &mode->channels[j];
-               if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
-                   chan->chan == sec_chan) {
-                       ok = 1;
-                       break;
-               }
-       }
-       if (!ok) {
+       if ((sec_chan->flag & HOSTAPD_CHAN_DISABLED) ||
+           (ht_plus && !(pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) ||
+           (!ht_plus && !(pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M))) {
                wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
-                          sec_chan);
+                          sec_chan_num);
                return 0;
        }

@@ -125,7 +135,7 @@ int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
        if (mode->mode != HOSTAPD_MODE_IEEE80211A)
                return 1;

-       first = pri_chan < sec_chan ? pri_chan : sec_chan;
+       first = pri_chan_num < sec_chan_num ? pri_chan_num : sec_chan_num;

        ok = 0;
        for (k = 0; k < ARRAY_SIZE(allowed); k++) {
@@ -136,7 +146,7 @@ int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
        }
        if (!ok) {
                wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed",
-                          pri_chan, sec_chan);
+                          pri_chan_num, sec_chan_num);
                return 0;
        }

@@ -553,3 +563,54 @@ int ieee80211ac_cap_check(u32 hw, u32 conf)
 }

 #endif /* CONFIG_IEEE80211AC */
+
+u32 num_chan_to_bw(int num_chans)
+{
+       switch (num_chans) {
+       case 2:
+       case 4:
+       case 8:
+               return num_chans * 20;
+       default:
+               return 20;
+       }
+}
+
+int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
+                   int ht40_plus, int pri)
+{
+       u32 bw_mask;
+
+       switch (bw) {
+       case 20:
+               bw_mask = HOSTAPD_CHAN_WIDTH_20;
+               break;
+       case 40:
+               /* HT 40 MHz support declared only for primary channel,
+                * just skip 40 MHz secondary checking */
+               if (pri && ht40_plus)
+                       bw_mask = HOSTAPD_CHAN_WIDTH_40P;
+               else if (pri && !ht40_plus)
+                       bw_mask = HOSTAPD_CHAN_WIDTH_40M;
+               else
+                       bw_mask = 0;
+               break;
+       case 80:
+               bw_mask = HOSTAPD_CHAN_WIDTH_80;
+               break;
+       case 160:
+               bw_mask = HOSTAPD_CHAN_WIDTH_160;
+               break;
+       default:
+               bw_mask = 0;
+               break;
+       }
+
+       return (chan->allowed_bw & bw_mask) == bw_mask;
+}
+
+int chan_pri_allowed(const struct hostapd_channel_data *chan)
+{
+       return !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
+               (chan->allowed_bw & HOSTAPD_CHAN_WIDTH_20);
+}
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index 9cddbd50e..b2ae50488 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -20,8 +20,8 @@ struct hostapd_channel_data * hw_get_channel_freq(struct hostapd_hw_modes *mode,
 int hw_get_freq(struct hostapd_hw_modes *mode, int chan);
 int hw_get_chan(struct hostapd_hw_modes *mode, int freq);

-int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
-                             int sec_chan);
+int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan_num,
+                             int sec_chan_num);
 void get_pri_sec_chan(struct wpa_scan_res *bss, int *pri_chan, int *sec_chan);
 int check_40mhz_5g(struct hostapd_hw_modes *mode,
                   struct wpa_scan_results *scan_res, int pri_chan,
@@ -39,4 +39,11 @@ void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
                      int disabled);
 int ieee80211ac_cap_check(u32 hw, u32 conf);

+u32 num_chan_to_bw(int num_chans);
+/* check if BW is applicable for channel */
+int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
+                   int ht40_plus, int pri);
+/* check if channel is allowed to be used as primary */
+int chan_pri_allowed(const struct hostapd_channel_data *chan);
+
 #endif /* HW_FEATURES_COMMON_H */
--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From dlebed at quantenna.com  Thu Mar  1 03:49:28 2018
From: dlebed at quantenna.com (Dmitrii Lebed)
Date: Thu,  1 Mar 2018 14:49:28 +0300
Subject: [PATCH 3/4] ACS: add supported channel BW checking
In-Reply-To: <20180301114929.420-1-dlebed@quantenna.com>
References: <20180301114929.420-1-dlebed@quantenna.com>
Message-ID: <20180301114929.420-4-dlebed@quantenna.com>

From: Dmitry Lebed <dlebed at quantenna.com>

While doing automatic channel selection we need
to take into account supported BW for each channel
provided via nl80211.
Without this modification hostapd can select unsupported
channel, will fail to use it and eventually will not start.

Signed-off-by: Dmitry Lebed <dlebed at quantenna.com>
---
 src/ap/acs.c | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/ap/acs.c b/src/ap/acs.c
index aa5905894..9ce5ca8f6 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -13,6 +13,7 @@
 #include "utils/common.h"
 #include "utils/list.h"
 #include "common/ieee802_11_defs.h"
+#include "common/hw_features_common.h"
 #include "common/wpa_ctrl.h"
 #include "drivers/driver.h"
 #include "hostapd.h"
@@ -565,6 +566,7 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
        long double factor, ideal_factor = 0;
        int i, j;
        int n_chans = 1;
+       u32 bw;
        unsigned int k;

        /* TODO: HT40- support */
@@ -583,12 +585,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
            iface->conf->vht_oper_chwidth == 1)
                n_chans = 4;

+       bw = num_chan_to_bw(n_chans);
+
        /* TODO: VHT80+80, VHT160. Update acs_adjust_vht_center_freq() too. */

-       wpa_printf(MSG_DEBUG, "ACS: Survey analysis for selected bandwidth %d MHz",
-                  n_chans == 1 ? 20 :
-                  n_chans == 2 ? 40 :
-                  80);
+       wpa_printf(MSG_DEBUG, "ACS: Survey analysis for selected bandwidth %u MHz",
+                  bw);

        for (i = 0; i < iface->current_mode->num_channels; i++) {
                double total_weight;
@@ -596,12 +598,22 @@ acs_find_ideal_chan(struct hostapd_iface *iface)

                chan = &iface->current_mode->channels[i];

-               if (chan->flag & HOSTAPD_CHAN_DISABLED)
+               /* Since in current ACS implementation first channel is
+                * always a primary channel, skip channels not available as
+                * primary until more sophisticated channel selection will be
+                * implemented */
+               if (!chan_pri_allowed(chan))
                        continue;

                if (!is_in_chanlist(iface, chan))
                        continue;

+               if (!chan_bw_allowed(chan, bw, 1, 1)) {
+                       wpa_printf(MSG_DEBUG, "ACS: Channel %d: BW %u is not supported",
+                                  chan->chan, bw);
+                       continue;
+               }
+
                /* HT40 on 5 GHz has a limited set of primary channels as per
                 * 11n Annex J */
                if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
@@ -632,6 +644,12 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
                        if (!adj_chan)
                                break;

+                       if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
+                               wpa_printf(MSG_DEBUG, "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
+                                          chan->chan, adj_chan->chan, bw);
+                               break;
+                       }
+
                        if (acs_usable_chan(adj_chan)) {
                                factor += adj_chan->interference_factor;
                                total_weight += 1;
--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From dlebed at quantenna.com  Thu Mar  1 03:49:29 2018
From: dlebed at quantenna.com (Dmitrii Lebed)
Date: Thu,  1 Mar 2018 14:49:29 +0300
Subject: [PATCH 4/4] DFS: add supported channel BW checking
In-Reply-To: <20180301114929.420-1-dlebed@quantenna.com>
References: <20180301114929.420-1-dlebed@quantenna.com>
Message-ID: <20180301114929.420-5-dlebed@quantenna.com>

From: Dmitry Lebed <dlebed at quantenna.com>

While selecting new channel as a reation to radar event
we need to take into account supported BW for each channel
provided via nl80211.
Without this modification hostapd can select unsupported
channel, will fail to use it and eventually will halt.

Signed-off-by: Dmitry Lebed <dlebed at quantenna.com>
---
 src/ap/dfs.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 8c56cbb96..f2c115ca5 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -143,18 +143,30 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
 {
        struct hostapd_channel_data *first_chan, *chan;
        int i;
+       const u32 bw = num_chan_to_bw(num_chans);

        if (first_chan_idx + num_chans > mode->num_channels)
                return 0;

        first_chan = &mode->channels[first_chan_idx];

+       /* hostapd DFS implementation assumes first channel as primary,
+        * if it's not allowed to use fist channel as primary
+        * then decline the whole channel range */
+       if (!chan_pri_allowed(first_chan))
+               return 0;
+
        for (i = 0; i < num_chans; i++) {
                chan = dfs_get_chan_data(mode, first_chan->freq + i * 20,
                                         first_chan_idx);
                if (!chan)
                        return 0;

+               /* HT 40MHz secondary channel availability checked only for
+                * primary channel */
+               if (!chan_bw_allowed(chan, bw, 1, !i))
+                       return 0;
+
                if (!dfs_channel_available(chan, skip_radar))
                        return 0;
        }
@@ -195,9 +207,9 @@ static int dfs_find_channel(struct hostapd_iface *iface,
                chan = &mode->channels[i];

                /* Skip HT40/VHT incompatible channels */
-               if (iface->conf->ieee80211n &&
-                   iface->conf->secondary_channel &&
-                   !dfs_is_chan_allowed(chan, n_chans))
+               if (iface->conf->ieee80211n && iface->conf->secondary_channel &&
+                   (!dfs_is_chan_allowed(chan, n_chans) ||
+                    !(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)))
                        continue;

                /* Skip incompatible chandefs */
--
2.16.1



This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From yvsg.phanis at gmail.com  Thu Mar  1 17:06:11 2018
From: yvsg.phanis at gmail.com (Phani Siriki)
Date: Thu, 1 Mar 2018 19:06:11 -0600
Subject: Query on WMM AC parameters configuration using netlink
Message-ID: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>

Hi All

I am working on changing the TXQ queue parameters dynamically using
netlink sockets.

As of now, I was able to change the TXQ parameters used by AP(tx_queue
parameters in hostap.conf) by setting the structure
NL80211_ATTR_WIPHY_TXQ_PARAMS.

I tested this on mininet-wifi and I able to see below debug output.

Feb 21 11:57:01 wifi-VirtualBox kernel: [38320.963179] ieee80211
mn00s02: mac80211_hwsim_conf_tx (queue=0 txop=0 cw_min=7 cw_max=15
aifs=2)
Feb 21 11:57:01 wifi-VirtualBox kernel: [38320.963184] ieee80211
mn00s02: mac80211_hwsim_bss_info_changed(changed=0x2000
vif->addr=02:00:00:00:02:00)

Now, I want to change the wmm_ac parameters as well, but couldn't get
the exact netlink parameter to set.

Could someone point me the nl80211 parameter used to set these
parameters in AP, so that AP can advertise these values to stations in
their IE?

Best Regards
Phani


From zefir.kurtisi at neratec.com  Fri Mar  2 06:22:36 2018
From: zefir.kurtisi at neratec.com (Zefir Kurtisi)
Date: Fri, 2 Mar 2018 15:22:36 +0100
Subject: [PATCH 0/8] Enhance FT roaming
In-Reply-To: <620d7cd29d751310242b0ba4ffd43091@fami-braun.de>
References: <1495113717-26860-1-git-send-email-michael-dev@fami-braun.de>
 <970DB745-78BD-4AE5-9273-A3B8038A369D@fami-braun.de>
 <620d7cd29d751310242b0ba4ffd43091@fami-braun.de>
Message-ID: <2ec31cf1-1311-3cbb-28db-69486d63e70a@neratec.com>

Hello Michael,

I tested your patches for the key lifetime functionality and want to confirm that
it works as expected.


Thanks a lot.

Zefir

On 11/16/2017 08:14 PM, michael-dev wrote:
> Hi,
> 
> how to continue with this series?
> 
> Regards,
> M. Braun
> 
> Am 23. Juli 2017 20:39:31 MESZ schrieb michael-dev at fami-braun.de:
> 
>> Hi,
>>
>> any comments on this?
>>
>> Regards,
>> M. Braum
>>
>> Am 18. Mai 2017 15:21:49 MESZ schrieb Michael Braun <michael-dev at fami-braun.de>:
>>
>>> Hi,
>>>
>>> here come some follow-up patches for FT roaming
>>> based on the new protocol.
>>>
>>> Regards,
>>> M. Braun
>>>
>>> Michael Braun (8):
>>> FT: add expiration to PMK-R0 and PMK-R1 cache
>>> FT: add IEEE vlan support (including tagged vlans)
>>> test: FT-EAP with VLAN
>>> test: FT-PSK with VLAN
>>> FT: include identity and radius_cui in pull/resp frames
>>> tests: FT with CUI
>>> FT: add session_timeout to push/resp
>>> FT: convert r0_key_lifetime to seconds
>>>
>>> hostapd/config_file.c | 4 +
>>> hostapd/hostapd.conf | 10 +-
>>> src/ap/ap_config.c | 1 +
>>> src/ap/ap_config.h | 1 +
>>> src/ap/ieee802_11.c | 12 +-
>>> src/ap/ieee802_1x.c | 18 +-
>>> src/ap/sta_info.h | 3 +-
>>> src/ap/wpa_auth.c | 5 +-
>>> src/ap/wpa_auth.h | 25 ++
>>> src/ap/wpa_auth_ft.c | 747
>>> ++++++++++++++++++++++++++++++++----
>>> src/ap/wpa_auth_glue.c | 255 ++++++++++++
>>> src/ap/wpa_auth_i.h | 5 +-
>>> tests/hwsim/auth_serv/eap_user.conf | 5 +
>>> tests/hwsim/test_ap_ft.py | 254 +++++++++++-
>>> 14 files changed, 1242 insertions(+), 103 deletions(-)
>>
>> -------------------------
>>
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:50 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:50 -0500
Subject: [PATCH 02/15] mka: Ignore MACsec SAK Use Old Key parameter if we
 don't remember our old key
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-3-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

Upon receipt of the "MACsec MKPDU SAK Use parameter set" the KaY verifies
that both the latest key and the old key are valid.  If the local system
reboots or is reinitalizied, the KaY won't have a copy of it's old key.
Therefore if the KaY does not have a copy of it's old key it should not
reject MKPDUs that contain old key data in the MACsec SAK Use parameter.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index beaae58f0..d77f81b7b 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1336,8 +1336,9 @@ ieee802_1x_mka_decode_sak_use_body(
                }
        }

-       /* check old key is valid */
-       if (body->otx || body->orx) {
+       /* check old key is valid (but only if we remember our old key) */
+       if ((participant->oki.kn != 0) &&
+           (body->otx || body->orx)) {
                if (os_memcmp(participant->oki.mi, body->osrv_mi,
                              sizeof(participant->oki.mi)) != 0 ||
                    be_to_host32(body->okn) != participant->oki.kn ||
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:49 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:49 -0500
Subject: [PATCH 01/15] mka: When matching CKNs ensure that lengths are
 identical
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-2-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

KaY looks up participants using CAK Name (CKN).  Per IEEE802.1X-2010
Clause 9.3.1 CAK identification, the CKN is an integral number of octets,
between 1 and 32 (inclusive).  This fix will ensure that the KaY does not
inadvertently match CKNs such as 'myCakNamedFoo' and 'myCakNamedFooBar'.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index cad0292ec..beaae58f0 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -245,14 +245,15 @@ ieee802_1x_mka_dump_sak_use_body(struct ieee802_1x_mka_sak_use_body *body)
  * ieee802_1x_kay_get_participant -
  */
 static struct ieee802_1x_mka_participant *
-ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn)
+ieee802_1x_kay_get_participant(struct ieee802_1x_kay *kay, const u8 *ckn, size_t len)
 {
        struct ieee802_1x_mka_participant *participant;

        dl_list_for_each(participant, &kay->participant_list,
                         struct ieee802_1x_mka_participant, list) {
-               if (os_memcmp(participant->ckn.name, ckn,
-                             participant->ckn.len) == 0)
+               if ((participant->ckn.len == len) &&
+                   (os_memcmp(participant->ckn.name, ckn,
+                             participant->ckn.len) == 0))
                        return participant;
        }

@@ -748,6 +749,8 @@ ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
        struct ieee802_1x_mka_participant *participant;
        const struct ieee802_1x_mka_basic_body *body;
        struct ieee802_1x_kay_peer *peer;
+       size_t ckn_len;
+       size_t body_len;

        body = (const struct ieee802_1x_mka_basic_body *) mka_msg;

@@ -761,7 +764,9 @@ ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
                return NULL;
        }

-       participant = ieee802_1x_kay_get_participant(kay, body->ckn);
+       body_len = get_mka_param_body_len(body);
+       ckn_len = body_len - (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN);
+       participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len);
        if (!participant) {
                wpa_printf(MSG_DEBUG, "Peer is not included in my CA");
                return NULL;
@@ -2856,6 +2861,7 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
        size_t mka_msg_len;
        struct ieee802_1x_mka_participant *participant;
        size_t body_len;
+       size_t ckn_len;
        u8 icv[MAX_ICV_LEN];
        u8 *msg_icv;

@@ -2895,8 +2901,16 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
                return -1;
        }

+       ckn_len = body_len - (sizeof(struct ieee802_1x_mka_basic_body) - MKA_HDR_LEN);
+       if ((ckn_len < 1) || (ckn_len > MAX_CKN_LEN)) {
+               wpa_printf(MSG_ERROR,
+                          "KaY: Received EAPOL-MKA CKN Length (%zu bytes) is out of range (<=%u bytes)",
+                          ckn_len, MAX_CKN_LEN);
+               return -1;
+       }
+
        /* CKN should be owned by I */
-       participant = ieee802_1x_kay_get_participant(kay, body->ckn);
+       participant = ieee802_1x_kay_get_participant(kay, body->ckn, ckn_len);
        if (!participant) {
                wpa_printf(MSG_DEBUG, "CKN is not included in my CA");
                return -1;
@@ -3403,7 +3417,7 @@ ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn)
        wpa_printf(MSG_DEBUG, "KaY: participant removed");

        /* get the participant */
-       participant = ieee802_1x_kay_get_participant(kay, ckn->name);
+       participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len);
        if (!participant) {
                wpa_hexdump(MSG_DEBUG, "KaY: participant is not found",
                            ckn->name, ckn->len);
@@ -3462,7 +3476,7 @@ void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
        if (!kay || !ckn)
                return;

-       participant = ieee802_1x_kay_get_participant(kay, ckn->name);
+       participant = ieee802_1x_kay_get_participant(kay, ckn->name, ckn->len);
        if (!participant)
                return;

--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:59 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:59 -0500
Subject: [PATCH 11/15] mka: Fix a few minor bugs in CP state machine
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-12-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

All fixes per IEEE802.1X-2010 Figure 12-2 - CP state machine.

1) Upon entering RETIRE, deleteSAs(oki)
2) RECEIVING to TRANSMIT, add !controlledPortEnabled to branching logic
3) READY should move to ABANDON (not RECEIVE) when new_sak or
   changed_connect is true.
4) READY to TRANSMIT, add !controlledPortEnabled to branching logic

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_cp.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c
index e6b2767e2..05eab7e4b 100644
--- a/src/pae/ieee802_1x_cp.c
+++ b/src/pae/ieee802_1x_cp.c
@@ -319,8 +319,11 @@ SM_STATE(CP, RETIRE)
        SM_ENTRY(CP, RETIRE);
        /* RETIRE state machine not keep with Figure 12-2 in
         * IEEE Std 802.1X-2010 */
-       os_free(sm->oki);
-       sm->oki = NULL;
+       if (sm->oki) {
+               ieee802_1x_kay_delete_sas(sm->kay, sm->oki);
+               os_free(sm->oki);
+               sm->oki = NULL;
+       }
        sm->orx = FALSE;
        sm->otx = FALSE;
        ieee802_1x_kay_set_old_sa_attr(sm->kay, sm->oki, sm->oan,
@@ -382,7 +385,7 @@ SM_STEP(CP)
                if (!sm->elected_self)
                        SM_ENTER(CP, READY);
                if (sm->elected_self &&
-                   (sm->all_receiving || !sm->transmit_when))
+                   (sm->all_receiving || !sm->controlled_port_enabled || !sm->transmit_when))
                        SM_ENTER(CP, TRANSMIT);
                break;

@@ -405,8 +408,8 @@ SM_STEP(CP)

        case CP_READY:
                if (sm->new_sak || changed_connect(sm))
-                       SM_ENTER(CP, RECEIVE);
-               if (sm->server_transmitting)
+                       SM_ENTER(CP, ABANDON);
+               if (sm->server_transmitting || !sm->controlled_port_enabled)
                        SM_ENTER(CP, TRANSMIT);
                break;
        case CP_ABANDON:
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:11:03 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:11:03 -0500
Subject: [PATCH 15/15] mka: do not update potential peer liveness timer
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-16-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

To prevent a remote peer from getting stuck in a perpetual 'potential
peer' state, only update the peer liveness timer 'peer->expire' for live
peers and not for potential peers.

Per IEEE802.1X-2010 9.4.3 Determining liveness, potential peers need to
show liveness by including our MI/MN in their transmitted MKPDU (within
potential or live parameter sets).

When a potential peer does include our MI/MN in an MKPDU, we respond by
moving the peer from 'potential_peers' to 'live_peers'.

If a potential peer does not include our MI/MN in an MKPDU within
MKPDU_LIFE_TIME, then let the peer expire to facilitate getting back in
sync with the remote peer.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 4323b6dc0..6ac7d02d1 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -3180,14 +3180,21 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                } else {
                        peer->missing_sak_use_count = 0;
                }
+
+               /* Only update live peer watchdog after successful decode of all parameter sets */
+               peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
        } else {
                /* MKPDU is from new or potential peer */
                peer = ieee802_1x_kay_get_peer(participant, participant->current_peer_id.mi);
-       }
+               if (!peer)
+                       return -1;

-       /* Only update live peer watchdog after successful decode of all parameter sets */
-       if (peer)
-               peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+               /* Do not update potential peer watchdog.  Per IEEE802.1X-2010 9.4.3,
+                * potential peers need to show liveness by including our MI/MN in their
+                * transmitted MKPDU (within potential or live parameter sets).  When
+                * a potential peer does include our MI/MN in an MKPDU, we respond by
+                * moving the peer from 'potential_peers' to 'live_peers'. */
+       }

        kay->active = TRUE;
        participant->retry_count = 0;
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:48 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:48 -0500
Subject: [PATCH 00/15] MKA bugfixes and enhancements
Message-ID: <20180302201103.16264-1-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

This patch series fixes several bugs in the MACsec Key Agreement (MKA)
protocol.  The series also includes enhancements such as better handling
of errant and/or missing MKPDU parameter sets, detection of duplicate
MAC addresses, and pausing MKA when link is down.

Mike Siedzik (15):
  mka: When matching CKNs ensure that lengths are identical
  mka: Ignore MACsec SAK Use Old Key parameter if we don't remember our
    old key
  mka: Incorrect conf_offset sent in MKPDU when in policy mode
    "SHOULD_SECURE"
  mka: Loss of live peers should result in connect PENDING not
    AUTHENTICATED
  mka: finish implementation of CP state machine "port_enabled"
    parameter
  mka: KaY setting Parameter Set Body Length incorrectly
  mka: Detect duplicate MAC addresses during key server election
  mka: MKPDU SAK Use Body's Delay Protect bit set incorrectly
  mka: Lowest acceptable Packet Number (LPN) calculated and used
    incorrectly
  mka: Do not print contents of SAK to debug log
  mka: Fix a few minor bugs in CP state machine
  mka: resources leaked when duplicated SCI detected
  mka: do not ignore MKPDU parameter set decoding failures
  mka: consider missing MKPDU parameter sets a failure
  mka: do not update potential peer liveness timer

 src/drivers/driver.h              |   8 +
 src/drivers/driver_macsec_linux.c |  43 +++++
 src/pae/ieee802_1x_cp.c           |  26 ++-
 src/pae/ieee802_1x_cp.h           |   1 +
 src/pae/ieee802_1x_kay.c          | 384 ++++++++++++++++++++++++++++++--------
 src/pae/ieee802_1x_kay.h          |   5 +
 src/pae/ieee802_1x_kay_i.h        |   5 +-
 src/pae/ieee802_1x_secy_ops.c     |  21 +++
 src/pae/ieee802_1x_secy_ops.h     |   2 +
 wpa_supplicant/driver_i.h         |   8 +
 wpa_supplicant/wpas_kay.c         |   7 +
 11 files changed, 420 insertions(+), 90 deletions(-)

--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:52 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:52 -0500
Subject: [PATCH 04/15] mka: Loss of live peers should result in connect
 PENDING not AUTHENTICATED
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-5-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

When the number of live peers becomes 0 the KaY is setting
'kay->authenticated' true and telling the CP to connect AUTHENTICATED.
Per IEEE802.1X-2010 Clause 12.2, MKA.authenticated means "the Key Sever
has proved mutual authentication but has determiend that Controlled Port
communication should proceed without the use of MACsec", which means
port traffic will be passed in the clear.
When the number of live peers becomes 0 the KaY must instead set
'kay->authenticated' false and tell the CP to connect PENDING.  Per
Clause 12.3 connect PENDING will "prevent connectivity by clearing the
controlledPortEnabled parameter."

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 41e5a07e6..fd329e610 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -2393,7 +2393,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                        participant->orx = FALSE;
                        participant->is_key_server = FALSE;
                        participant->is_elected = FALSE;
-                       kay->authenticated = TRUE;
+                       kay->authenticated = FALSE;
                        kay->secured = FALSE;
                        kay->failed = FALSE;
                        kay->ltx_kn = 0;
@@ -2410,7 +2410,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                                ieee802_1x_delete_transmit_sa(kay, txsa);
                        }

-                       ieee802_1x_cp_connect_authenticated(kay->cp);
+                       ieee802_1x_cp_connect_pending(kay->cp);
                        ieee802_1x_cp_sm_step(kay->cp);
                } else {
                        ieee802_1x_kay_elect_key_server(participant);
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:58 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:58 -0500
Subject: [PATCH 10/15] mka: Do not print contents of SAK to debug log
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-11-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

Log newly generated SAKs as well as unwrapped SAKs with wpa_hexdump_key()
rather than wpa_hexdump(). By default, the wpa_hexdump_key() function
will not display sensitive key data.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 4ac4fdc15..27022d994 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1644,7 +1644,7 @@ ieee802_1x_mka_decode_dist_sak_body(
                os_free(unwrap_sak);
                return -1;
        }
-       wpa_hexdump(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);
+       wpa_hexdump_key(MSG_DEBUG, "\tAES Key Unwrap of SAK:", unwrap_sak, sak_len);

        sa_key = os_zalloc(sizeof(*sa_key));
        if (!sa_key) {
@@ -2035,7 +2035,7 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
                wpa_printf(MSG_ERROR, "KaY: SAK Length not support");
                goto fail;
        }
-       wpa_hexdump(MSG_DEBUG, "KaY: generated new SAK", key, key_len);
+       wpa_hexdump_key(MSG_DEBUG, "KaY: generated new SAK", key, key_len);
        os_free(context);
        context = NULL;

--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:55 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:55 -0500
Subject: [PATCH 07/15] mka: Detect duplicate MAC addresses during key server
 election
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-8-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

In the unlikely event the local KaY and the elected peer have the same
actor priority as well as the same MAC address, log a warning message
and do not elect a key server.  Resolution is for network administrator
to reconfigure MAC address.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 70fda1f2d..0c3101cd8 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -2091,6 +2091,7 @@ ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
        struct ieee802_1x_kay_peer *key_server = NULL;
        struct ieee802_1x_kay *kay = participant->kay;
        Boolean i_is_key_server;
+       int priority_comparison;

        if (participant->is_obliged_key_server) {
                participant->new_sak = TRUE;
@@ -2121,8 +2122,14 @@ ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)

                tmp.key_server_priority = kay->actor_priority;
                os_memcpy(&tmp.sci, &kay->actor_sci, sizeof(tmp.sci));
-               if (compare_priorities(&tmp, key_server) < 0)
+               priority_comparison = compare_priorities(&tmp, key_server);
+               if (priority_comparison < 0) {
                        i_is_key_server = TRUE;
+               } else if (priority_comparison == 0) {
+                       wpa_printf(MSG_WARNING,
+                                  "KaY: Cannot elect key server between me and peer, duplicate MAC detected");
+                       key_server = NULL;
+               }
        } else if (participant->can_be_key_server) {
                i_is_key_server = TRUE;
        }
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:56 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:56 -0500
Subject: [PATCH 08/15] mka: MKPDU SAK Use Body's Delay Protect bit set
 incorrectly
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-9-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

Delay Protect and Replay Protect are two separate and distinct features
of MKA.  Per IEEE802.1X-2010 Clause 9.10.1 "Delay Protect, TRUE if LPNs
are being reported sufficiently frequently to allow the receipt to
provide data delay protection.  If FALSE, the LPN can be reported as
zero", and per Clause 9.10 "NOTE - Enforcement of bounded received delay
necessitates transmission of MKPDUs at frequency (0.5 s) intervals, to
meet a maximum data delay of 2 s while minimizing connectivity
interruption due to the possibility of lost or delayed MKPDUs."

This means ieee802_1x_mka_sak_use_body.delay_protect should only be set
TRUE when MKPDUs are being transmitted every 0.5 s (or faster).  By
default the KaY sends MKPDUs every MKA_HELLO_TIME (2.0s), so by default
delay_protect should be FALSE.

A new 'u32 mka_hello_time' parameter to has been added to the
'ieee802_1x_kay' data structure.  If delay protection is desired, the
KaY initialization code should set kay->mka_hello_time to
MKA_BOUNDED_HELLO_TIME (500ms).

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 14 +++++++++-----
 src/pae/ieee802_1x_kay.h |  2 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 0c3101cd8..ba2636ad6 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1205,7 +1205,7 @@ ieee802_1x_mka_encode_sak_use_body(
        }

        /* data protect, lowest accept packet number */
-       body->delay_protect = kay->macsec_replay_protect;
+       body->delay_protect = (kay->mka_hello_time <= MKA_BOUNDED_HELLO_TIME);
        pn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
        if (pn > kay->pn_exhaustion) {
                wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion");
@@ -2487,7 +2487,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                participant->retry_count++;
        }

-       eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
+       eloop_register_timeout(kay->mka_hello_time / 1000, 0,
                               ieee802_1x_participant_timer,
                               participant, NULL);

@@ -3208,6 +3208,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
                kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
+               kay->mka_hello_time = MKA_HELLO_TIME;
        } else {
                kay->macsec_desired = TRUE;
                kay->macsec_protect = TRUE;
@@ -3221,6 +3222,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_validate = Strict;
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
+               kay->mka_hello_time = MKA_HELLO_TIME;
        }

        wpa_printf(MSG_DEBUG, "KaY: state machine created");
@@ -3425,7 +3427,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
        wpa_hexdump(MSG_DEBUG, "KaY: Participant created:",
                    ckn->name, ckn->len);

-       usecs = os_random() % (MKA_HELLO_TIME * 1000);
+       usecs = os_random() % (kay->mka_hello_time * 1000);
        eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
                               participant, NULL);

@@ -3575,7 +3577,7 @@ void ieee802_1x_kay_notify_port_enabled(struct ieee802_1x_kay *kay,
                dl_list_for_each(participant, &kay->participant_list,
                                 struct ieee802_1x_mka_participant, list) {
                        if (participant->participant) {
-                               usecs = os_random() % (MKA_HELLO_TIME * 1000);
+                               usecs = os_random() % (kay->mka_hello_time * 1000);
                                eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
                                                       participant, NULL);
                        }
@@ -3681,6 +3683,7 @@ int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                          "Is Key Server=%s\n"
                          "Number of Keys Distributed=%u\n"
                          "Number of Keys Received=%u\n",
+                         "MKA Hello Time=%u\n",
                          kay->port_enable ? "Enabled" : "Disabled",
                          kay->active ? "Active" : "Not-Active",
                          kay->authenticated ? "Yes" : "No",
@@ -3690,7 +3693,8 @@ int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                          kay->key_server_priority,
                          kay->is_key_server ? "Yes" : "No",
                          kay->dist_kn - 1,
-                         kay->rcvd_keys);
+                         kay->rcvd_keys,
+                         kay->mka_hello_time);
        if (os_snprintf_error(buflen, len))
                return 0;

diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index 8c1a3b2fa..7031c1a83 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -21,6 +21,7 @@ struct macsec_init_params;

 /* MKA timer, unit: millisecond */
 #define MKA_HELLO_TIME         2000
+#define MKA_BOUNDED_HELLO_TIME  500
 #define MKA_LIFE_TIME          6000
 #define MKA_SAK_RETIRE_TIME    3000

@@ -187,6 +188,7 @@ struct ieee802_1x_kay {
        u32 macsec_replay_window;
        enum validate_frames macsec_validate;
        enum confidentiality_offset macsec_confidentiality;
+       u32 mka_hello_time;

        u32 ltx_kn;
        u8 ltx_an;
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:57 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:57 -0500
Subject: [PATCH 09/15] mka: Lowest acceptable Packet Number (LPN) calculated
 and used incorrectly
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-10-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

The purpose of the Lowest Acceptable PN (lpn) parameters in the MACsec
SAK Use parameter set is to enforce delay protection.  Per
IEEE802.1X-2010 Clause 9, "Each SecY uses MKA to communicate the lowest
PN used for transmission with the SAK within the last two seconds,
allowing receivers to bound transmission delays."

When encoding the SAK Use parameter set the KaY should set llpn and
olpn to the lowest PN transmitted by the latest SAK and oldest SAK (if
active) within the last two seconds.  Because MKPDU's are transmitted
every 2 seconds (MKA_HELLO_TIME), the solution implemented here
calculates lpn based on the txsc->next_pn read during the previous MKPDU
transmit.

Upon receiving and decoding a SAK Use parameter set with delay
protection enabled, the KaY will update the SecY's lpn if the delay
protect lpn is greater than the SecY's current lpn (which is a product
of last PN received and replay protection and window size).

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/drivers/driver.h              |  8 +++++
 src/drivers/driver_macsec_linux.c | 43 ++++++++++++++++++++++
 src/pae/ieee802_1x_kay.c          | 76 ++++++++++++++++++++++++---------------
 src/pae/ieee802_1x_kay.h          |  1 +
 src/pae/ieee802_1x_secy_ops.c     | 21 +++++++++++
 src/pae/ieee802_1x_secy_ops.h     |  2 ++
 wpa_supplicant/driver_i.h         |  8 +++++
 wpa_supplicant/wpas_kay.c         |  7 ++++
 8 files changed, 138 insertions(+), 28 deletions(-)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 92a58b2f2..7c15e9bc8 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3744,6 +3744,14 @@ struct wpa_driver_ops {
        int (*set_transmit_next_pn)(void *priv, struct transmit_sa *sa);

        /**
+        * set_receive_lowest_pn - Set receive lowest pn
+        * @priv: Private driver interface data
+        * @sa: secure association
+        * Returns: 0 on success, -1 on failure (or if not supported)
+        */
+       int (*set_receive_lowest_pn)(void *priv, struct receive_sa *sa);
+
+       /**
         * create_receive_sc - create secure channel for receiving
         * @priv: Private driver interface data
         * @sc: secure channel
diff --git a/src/drivers/driver_macsec_linux.c b/src/drivers/driver_macsec_linux.c
index e89b3ba14..ee0f64de3 100644
--- a/src/drivers/driver_macsec_linux.c
+++ b/src/drivers/driver_macsec_linux.c
@@ -670,6 +670,48 @@ static int macsec_drv_get_receive_lowest_pn(void *priv, struct receive_sa *sa)


 /**
+ * macsec_drv_set_receive_lowest_pn - Set 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_set_receive_lowest_pn(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: %d", __func__, sa->an, sa->next_pn);
+
+       msg = msg_prepare(MACSEC_CMD_UPD_RXSA, 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;
+}
+
+
+/**
  * macsec_drv_get_transmit_next_pn - Get transmit next PN
  * @priv: Private driver interface data
  * @sa: secure association
@@ -1293,6 +1335,7 @@ const struct wpa_driver_ops wpa_driver_macsec_linux_ops = {
        .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,
+       .set_receive_lowest_pn = macsec_drv_set_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,
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index ba2636ad6..4ac4fdc15 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1144,27 +1144,37 @@ ieee802_1x_mka_get_sak_use_length(


 /**
- *
+ * ieee802_1x_mka_get_lpn
  */
 static u32
 ieee802_1x_mka_get_lpn(struct ieee802_1x_mka_participant *principal,
                       struct ieee802_1x_mka_ki *ki)
 {
-       struct receive_sa *rxsa;
-       struct receive_sc *rxsc;
+       struct transmit_sa *txsa;
        u32 lpn = 0;

-       dl_list_for_each(rxsc, &principal->rxsc_list, struct receive_sc, list) {
-               dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list)
-               {
-                       if (is_ki_equal(&rxsa->pkey->key_identifier, ki)) {
-                               secy_get_receive_lowest_pn(principal->kay,
-                                                          rxsa);
-
-                               lpn = lpn > rxsa->lowest_pn ?
-                                       lpn : rxsa->lowest_pn;
-                               break;
-                       }
+       dl_list_for_each(txsa, &principal->txsc->sa_list,
+                        struct transmit_sa, list) {
+               if (is_ki_equal(&txsa->pkey->key_identifier, ki)) {
+                       /* Per IEEE802.1X-2010 Clase 9, "Eacy SecY uses MKA to
+                        * communicate the lowest PN used for transmission with
+                        * the SAK within the last two seconds".  Achive this
+                        * 2 second delay by setting the lpn using the transmit
+                        * next PN (i.e., txsa->next_pn) that was read last
+                        * time here (i.e., mka_hello_time 2 seconds ago).
+                        * The lowest acceptable PN is the same as the last
+                        * transmitted PN, which is one less than the next
+                        * transmit PN.
+                        *
+                        * NOTE: this method only works if mka_hello_time is 2s.
+                        */
+                       lpn = (txsa->next_pn > 0) ? (txsa->next_pn - 1) : 0;
+
+                       /* Now read the current transmit next PN for use next
+                        * time through. */
+                       secy_get_transmit_next_pn(principal->kay,
+                                                 txsa);
+                       break;
                }
        }

@@ -1265,7 +1275,8 @@ ieee802_1x_mka_decode_sak_use_body(
        struct ieee802_1x_mka_hdr *hdr;
        struct ieee802_1x_mka_sak_use_body *body;
        struct ieee802_1x_kay_peer *peer;
-       struct transmit_sa *txsa;
+       struct receive_sc *rxsc;
+       struct receive_sa *rxsa;
        struct data_key *sa_key = NULL;
        size_t body_len;
        struct ieee802_1x_mka_ki ki;
@@ -1385,25 +1396,34 @@ ieee802_1x_mka_decode_sak_use_body(
        }

        found = FALSE;
-       dl_list_for_each(txsa, &participant->txsc->sa_list,
-                        struct transmit_sa, list) {
-               if (sa_key != NULL && txsa->pkey == sa_key) {
-                       found = TRUE;
-                       break;
+       dl_list_for_each(rxsc, &participant->rxsc_list, struct receive_sc, list) {
+               dl_list_for_each(rxsa, &rxsc->sa_list, struct receive_sa, list) {
+                       if (sa_key != NULL && rxsa->pkey == sa_key) {
+                               found = TRUE;
+                               break;
+                       }
                }
        }
        if (!found) {
-               wpa_printf(MSG_WARNING, "KaY: Can't find txsa");
+               wpa_printf(MSG_WARNING, "KaY: Can't find rxsa");
                return -1;
        }

-       /* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key
-        * npn is larger than txsa's npn, set it to txsa.
-        */
-       secy_get_transmit_next_pn(kay, txsa);
-       if (lpn > txsa->next_pn) {
-               secy_set_transmit_next_pn(kay, txsa);
-               wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn);
+       if (body->delay_protect) {
+               secy_get_receive_lowest_pn(participant->kay, rxsa);
+               if (lpn > rxsa->lowest_pn) {
+                       /* Delay protect window (communicated via MKA) is
+                        * tighter than SecY's current replay protect window,
+                        * so tell SecY the new (and higher) lpn. */
+                       rxsa->lowest_pn = lpn;
+                       secy_set_receive_lowest_pn(participant->kay, rxsa);
+                       wpa_printf(MSG_DEBUG, "KaY: update lpn =0x%x", lpn);
+               }
+               /* FIXME: Delay protection for olpn not implemented.
+                * Note that Old Key is only active for MKA_SAK_RETIRE_TIME
+                * (3 seconds) and delay protection does allow PN's within
+                * a 2 seconds window, so olpn would be a lot of work for
+                * just 1 second's worth of protection. */
        }

        return 0;
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index 7031c1a83..01af578fc 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -150,6 +150,7 @@ 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 (*set_receive_lowest_pn)(void *ctx, struct receive_sa *sa);
        int (*create_receive_sc)(void *ctx, struct receive_sc *sc,
                                 enum validate_frames vf,
                                 enum confidentiality_offset co);
diff --git a/src/pae/ieee802_1x_secy_ops.c b/src/pae/ieee802_1x_secy_ops.c
index ab5339bb2..4e5379ff7 100644
--- a/src/pae/ieee802_1x_secy_ops.c
+++ b/src/pae/ieee802_1x_secy_ops.c
@@ -216,6 +216,27 @@ int secy_set_transmit_next_pn(struct ieee802_1x_kay *kay,
 }


+int secy_set_receive_lowest_pn(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->set_receive_lowest_pn) {
+               wpa_printf(MSG_ERROR,
+                          "KaY: secy set_receive_lowest_pn operation not supported");
+               return -1;
+       }
+
+       return ops->set_receive_lowest_pn(ops->ctx, rxsa);
+}
+
+
 int secy_create_receive_sc(struct ieee802_1x_kay *kay, struct receive_sc *rxsc)
 {
        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 9fb29c3dd..2d112ba7c 100644
--- a/src/pae/ieee802_1x_secy_ops.h
+++ b/src/pae/ieee802_1x_secy_ops.h
@@ -36,6 +36,8 @@ 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_set_receive_lowest_pn(struct ieee802_1x_kay *kay,
+                              struct receive_sa *txsa);
 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);
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 078de23f7..92a0a8fda 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -796,6 +796,14 @@ 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_set_receive_lowest_pn(struct wpa_supplicant *wpa_s,
+                                               struct receive_sa *sa)
+{
+       if (!wpa_s->driver->set_receive_lowest_pn)
+               return -1;
+       return wpa_s->driver->set_receive_lowest_pn(wpa_s->drv_priv, sa);
+}
+
 static inline int
 wpa_drv_create_receive_sc(struct wpa_supplicant *wpa_s, struct receive_sc *sc,
                          unsigned int conf_offset, int validation)
diff --git a/wpa_supplicant/wpas_kay.c b/wpa_supplicant/wpas_kay.c
index 11708b8a6..5235af77a 100644
--- a/wpa_supplicant/wpas_kay.c
+++ b/wpa_supplicant/wpas_kay.c
@@ -92,6 +92,12 @@ static int wpas_set_transmit_next_pn(void *wpa_s, struct transmit_sa *sa)
 }


+static int wpas_set_receive_lowest_pn(void *wpa_s, struct receive_sa *sa)
+{
+       return wpa_drv_set_receive_lowest_pn(wpa_s, sa);
+}
+
+
 static unsigned int conf_offset_val(enum confidentiality_offset co)
 {
        switch (co) {
@@ -219,6 +225,7 @@ 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->set_receive_lowest_pn = wpas_set_receive_lowest_pn;
        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;
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:51 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:51 -0500
Subject: [PATCH 03/15] mka: Incorrect conf_offset sent in MKPDU when in policy
 mode "SHOULD_SECURE"
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-4-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

Commit 7b4d546e introduced policy setting SHOULD_ENCRYPT (MACsec provides
integrity+confidentiality) in addition to SHOULD_SECURE (MACsec provides
integrity only).  In both cases the KaY is populating the
"Confidentiality Offset" parameter within the "Distributed SAK parameter
set" with CONFIDENTIALITY_OFFSET_0=1.  In the case of SHOULD_SECURE the
parameter should be populated with CONFIDENTIALITY_NONE=0.

IEEE802.1X-2010 Table 11-6 and Figure 11-11 define how the two
Confidentiality Offset bits in the "Distributed SAK parameter set" must
be set: "0 if confidentiality not used" and "1 if confidentiality with no
offset".  When policy is SHOULD_SECURE KaY should to send the former, and
when policy is SHOULD_ENCRYPT KaY should send the latter.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index d77f81b7b..41e5a07e6 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -3159,6 +3159,7 @@ ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_capable = MACSEC_CAP_NOT_IMPLEMENTED;
                kay->macsec_desired = FALSE;
                kay->macsec_protect = FALSE;
+               kay->macsec_encrypt = FALSE;
                kay->macsec_validate = Disabled;
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
@@ -3166,14 +3167,16 @@ 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;
+               if (policy == SHOULD_SECURE) {
+                       kay->macsec_encrypt = FALSE;
+                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
+               } else {  /* SHOULD_ENCRYPT */
+                       kay->macsec_encrypt = TRUE;
+                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
+               }
                kay->macsec_validate = Strict;
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
-               if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF)
-                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
-               else
-                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
        }

        wpa_printf(MSG_DEBUG, "KaY: state machine created");
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:11:02 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:11:02 -0500
Subject: [PATCH 14/15] mka: consider missing MKPDU parameter sets a failure
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-15-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

The previous commit introduced parameter set error checking.  This
commit extends upon that by considering missing parameter sets a
failure.

Two checks are added by this commit.  First, verify that live peers
start encoding MKA_SAK_USE within a reasonable amount of time after
going live (10 MKPDUs).  Second, verify that once a live peer starts
encoding MKA_SAK_USE it continues to do so indefinitely.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c   | 31 ++++++++++++++++++++++++++++++-
 src/pae/ieee802_1x_kay_i.h |  1 +
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 7945cc898..4323b6dc0 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -27,6 +27,8 @@
 #define DEFAULT_ICV_LEN                16
 #define MAX_ICV_LEN            32  /* 32 bytes, 256 bits */

+#define MAX_MISSING_SAK_USE 10  /* Accept up to 10 inbound MKPDU's w/o SAK-USE before dropping */
+
 #define PENDING_PN_EXHAUSTION 0xC0000000

 #define MKA_ALIGN_LENGTH(len) (((len) + 0x3) & ~0x3)
@@ -562,6 +564,7 @@ ieee802_1x_kay_create_peer(const u8 *mi, u32 mn)
        peer->mn = mn;
        peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
        peer->sak_used = FALSE;
+       peer->missing_sak_use_count = 0;

        return peer;
 }
@@ -3155,8 +3158,34 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                return -1;
        }

+       /* Detect missing parameter sets */
+       peer = ieee802_1x_kay_get_live_peer(participant, participant->current_peer_id.mi);
+       if (peer) {
+               /* MKPDU is from live peer */
+               if (!handled[MKA_SAK_USE]) {
+                       /* Once a live peer starts sending SAK-USE, it should be sent
+                        * every time. */
+                       if (peer->sak_used) {
+                               wpa_printf(MSG_INFO, "KaY: Discarding Rx MKPDU: Live Peer stopped sending SAK-USE");
+                               return -1;
+                       }
+
+                       /* Live peer is probably hung if it hasn't sent SAK-USE
+                        * after a reasonable number of MKPDU's. Drop the MKPDU,
+                        * which will eventually force an timeout. */
+                       if (++peer->missing_sak_use_count > MAX_MISSING_SAK_USE) {
+                               wpa_printf(MSG_INFO, "KaY: Discarding Rx MKPDU: Live Peer not sending SAK-USE");
+                               return -1;
+                       }
+               } else {
+                       peer->missing_sak_use_count = 0;
+               }
+       } else {
+               /* MKPDU is from new or potential peer */
+               peer = ieee802_1x_kay_get_peer(participant, participant->current_peer_id.mi);
+       }
+
        /* Only update live peer watchdog after successful decode of all parameter sets */
-       peer = ieee802_1x_kay_get_peer(participant, participant->current_peer_id.mi);
        if (peer)
                peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;

diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index c10851d2d..33c5b721b 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -51,6 +51,7 @@ struct ieee802_1x_kay_peer {
        Boolean macsec_desired;
        enum macsec_cap macsec_capability;
        Boolean sak_used;
+       int missing_sak_use_count;
        struct dl_list list;
 };

--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:11:00 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:11:00 -0500
Subject: [PATCH 12/15] mka: resources leaked when duplicated SCI detected
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-13-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

If a live peer ever changes its Member Identifier (MI), the KaY
correctly detects a "duplicated SCI" but then proceeds to delete the
peer without deleting the peer's resources (i.e., RxSC, RxSAs, TxSAs).

Note that a remote peer's MI will change if and when a
ieee8021XPaePortInitialize is executed on the remote port.

The solution here is to ignore all MKPDUs containing the new MI until
after the peer (that corresponds to the old MI) expires and cleans up
its resources.  After the old peer is removed reception of the next
MKPDU containing the new MI will result in the creation of a new peer
with the new MI.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 27022d994..4d61cb32b 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -792,17 +792,31 @@ ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
        /* handler peer */
        peer = ieee802_1x_kay_get_peer(participant, body->actor_mi);
        if (!peer) {
-               /* Check duplicated SCI */
-               /* TODO: What policy should be applied to detect duplicated SCI
-                * is active attacker or a valid peer whose MI is be changed?
+               /* Check duplicated SCI
+                *
+                * A duplicated SCI indicates either an active attacker or
+                * a valid peer whose MI is be changed.  The latter scenario is
+                * more likely because to have gotten this far the received
+                * MKPDU must have had a valid ICV, indicating the peer holds
+                * the same CAK our participant.
+                *
+                * Before creating a new peer object for the new MI we must
+                * clean up the resources (SCs and SAs) associated with the
+                * old peer.  An easy way to do this is to ignore MKPDUs with
+                * the new MI's for now and just wait for the old peer to
+                * timeout and clean itself up (within MKA_LIFE_TIME).
+                *
+                * This method is peferable to deleting the old peer here
+                * and now and continuing on with processing because if this
+                * MKPDU is from an attacker it's better to ignore the MKPDU
+                * than to process it (and delete a valid peer as well).
                 */
                peer = ieee802_1x_kay_get_peer_sci(participant,
                                                   &body->actor_sci);
                if (peer) {
                        wpa_printf(MSG_WARNING,
-                                  "KaY: duplicated SCI detected, Maybe active attacker");
-                       dl_list_del(&peer->list);
-                       os_free(peer);
+                                  "KaY: duplicated SCI detected, Maybe active attacker or peer selected new MI");
+                       return NULL;
                }

                peer = ieee802_1x_kay_create_potential_peer(
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:11:01 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:11:01 -0500
Subject: [PATCH 13/15] mka: do not ignore MKPDU parameter set decoding failures
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-14-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

The status values returned by mka_param_body_handler.body_rx functions
are currently ignored by ieee802_1x_kay_decode_mkpdu().  If a failure is
detected the KaY should (a) stop processing the MKDPU and (b) do not
update the associated peer's liveliness.

IEEE802.1X-2010's Table 11-7 MKPDU Parameter sets and Clause 11.11.3
Encoding MKPDUs dictate that MKA_SAK_USE (set type 3) will always be
encoded before MKA_DISTRIBUTED_SAK (set type 4) in MKPDUs.  Due to
hostap's implementation of mka_param_body_handler, the code will always
decode MKA_SAK_USE before MKA_DISTRIBUTED_SAK.  When MKA_DISTRUBUTED_SAK
contains a new SAK the code should decode MKA_DISTRUBUTED_SAK first so
that the lastest SAK is in known before decoding MKA_SAK_USE.

The ideal solution would be to make two passes at MKDPU decoding: the
first pass decodes MKA_DISTRIBUTED_SAK, the second pass decodes all
other parameter sets.

A simpler and less risky solution is presented here: ignore MKA_SAK_USE
failures if MKA_DISTRIBUTED_SAK is also present.  The new SAK will be
saved so that the next MKPDU's MKA_SAK_USE can be properly decoded.
This is basically what the code prior to this commit was doing (by
ignoring all errors).

Also, the only real recourse the KaY has when detecting any bad
parameter set is to ignore the MKPDU by not updating the corresponding
peer's liveliness timer, 'peer->expire'.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 4d61cb32b..7945cc898 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -831,7 +831,6 @@ ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
                peer->key_server_priority = body->priority;
        } else if (peer->mn < be_to_host32(body->actor_mn)) {
                peer->mn = be_to_host32(body->actor_mn);
-               peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
                peer->macsec_desired = body->macsec_desired;
                peer->macsec_capability = body->macsec_capability;
                peer->is_key_server = (Boolean) body->key_server;
@@ -1076,7 +1075,6 @@ static int ieee802_1x_mka_decode_live_peer_body(
                peer = ieee802_1x_kay_get_peer(participant, peer_mi->mi);
                if (peer) {
                        peer->mn = peer_mn;
-                       peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
                } else if (!ieee802_1x_kay_create_potential_peer(
                                participant, peer_mi->mi, peer_mn)) {
                        return -1;
@@ -1350,7 +1348,7 @@ ieee802_1x_mka_decode_sak_use_body(
                        }
                }
                if (!found) {
-                       wpa_printf(MSG_WARNING, "KaY: Latest key is invalid");
+                       wpa_printf(MSG_INFO, "KaY: Latest key is invalid");
                        return -1;
                }
                if (os_memcmp(participant->lki.mi, body->lsrv_mi,
@@ -3041,12 +3039,14 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
 {
        struct ieee802_1x_mka_participant *participant;
        struct ieee802_1x_mka_hdr *hdr;
+       struct ieee802_1x_kay_peer *peer;
        size_t body_len;
        size_t left_len;
        u8 body_type;
        int i;
        const u8 *pos;
        Boolean handled[256];
+       Boolean bad_sak_use = FALSE; /* Error detected while processing SAK Use parameter set */

        if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
                return -1;
@@ -3121,8 +3121,26 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                handled[body_type] = TRUE;
                if (body_type < ARRAY_SIZE(mka_body_handler) &&
                    mka_body_handler[body_type].body_rx) {
-                       mka_body_handler[body_type].body_rx
-                               (participant, pos, left_len);
+                       if (mka_body_handler[body_type].body_rx
+                               (participant, pos, left_len) != 0) {
+                               /* Handle parameter set failure */
+                               if (body_type == MKA_SAK_USE) {
+                                       /* Ideally DIST-SAK should be processed before
+                                        * SAK-USE. Unfortunately IEEE8021X-2010 Clause
+                                        * 11.11.3 Encoding MKPDUs states SAK-USE(3)
+                                        * must always be encoded before DIST-SAK(4).
+                                        * Rather than redesigning mka_body_handler so
+                                        * that it somehow processes DIST-SAK before
+                                        * SAK-USE, just ignore SAK-USE failures if
+                                        * DIST-SAK is also present in this MKPDU. */
+                                       bad_sak_use = TRUE;
+                               } else {
+                                       wpa_printf(MSG_INFO,
+                                                  "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
+                                                  body_type);
+                                       return -1;
+                               }
+                       }
                } else {
                        wpa_printf(MSG_ERROR,
                                   "The type %d is not supported in this MKA version %d",
@@ -3130,6 +3148,18 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                }
        }

+       if (bad_sak_use && !handled[MKA_DISTRIBUTED_SAK]) {
+               wpa_printf(MSG_INFO,
+                          "KaY: Discarding Rx MKPDU: decode of parameter set type (%d) failed",
+                          MKA_SAK_USE);
+               return -1;
+       }
+
+       /* Only update live peer watchdog after successful decode of all parameter sets */
+       peer = ieee802_1x_kay_get_peer(participant, participant->current_peer_id.mi);
+       if (peer)
+               peer->expire = time(NULL) + MKA_LIFE_TIME / 1000;
+
        kay->active = TRUE;
        participant->retry_count = 0;
        participant->active = TRUE;
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:54 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:54 -0500
Subject: [PATCH 06/15] mka: KaY setting Parameter Set Body Length incorrectly
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-7-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

Per IEEE802.1X-2010 Clause 11.11 EAPOL-MKA, each parameter set must be
padded to a multiple of 4 octets.  In order for the length of variable
length parameters, such as CAK Name, to be correctly decoded the
parameter set body length must not include the length of null padding
octets.

When allocating buffer space for the parameter set (e.g., wpabuf_put())
the padded length must be used.  When setting the 'Parameter set body
length' within the parameter set the unpadded length must be used.

Consider the case were the length of a PSK's CKN is not a multiple of 4
octets.  Currently ieee802_1x_mka_encode_basic_body() will correctly
reserve the padded number buffer bytes.  However it will incorrectly
set ieee8021_x_mka_hdr->length and ->length1 to the padded number of
bytes.  The receiver will not be able to recover the original CKN
length.

Note that the hostap will successfully interoperate with itself because
both sides incorrectly calculate CKN length.  The problem is only seen
when interoperating with non-hostap KaY's.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 17519ae69..70fda1f2d 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -681,7 +681,7 @@ ieee802_1x_mka_basic_body_length(struct ieee802_1x_mka_participant *participant)

        length = sizeof(struct ieee802_1x_mka_basic_body);
        length += participant->ckn.len;
-       return MKA_ALIGN_LENGTH(length);
+       return length;
 }


@@ -697,7 +697,7 @@ ieee802_1x_mka_encode_basic_body(
        struct ieee802_1x_kay *kay = participant->kay;
        unsigned int length = ieee802_1x_mka_basic_body_length(participant);

-       body = wpabuf_put(buf, length);
+       body = wpabuf_put(buf, MKA_ALIGN_LENGTH(length));

        body->version = kay->mka_version;
        body->priority = kay->actor_priority;
@@ -856,7 +856,7 @@ ieee802_1x_mka_get_live_peer_length(
                         struct ieee802_1x_kay_peer, list)
                len += sizeof(struct ieee802_1x_mka_peer_id);

-       return MKA_ALIGN_LENGTH(len);
+       return len;
 }


@@ -916,7 +916,7 @@ ieee802_1x_mka_get_potential_peer_length(
                         struct ieee802_1x_kay_peer, list)
                len += sizeof(struct ieee802_1x_mka_peer_id);

-       return MKA_ALIGN_LENGTH(len);
+       return len;
 }


@@ -1139,7 +1139,7 @@ ieee802_1x_mka_get_sak_use_length(
        if (participant->kay->macsec_desired && participant->advised_desired)
                length = sizeof(struct ieee802_1x_mka_sak_use_body);

-       return MKA_ALIGN_LENGTH(length);
+       return length;
 }


@@ -1189,7 +1189,7 @@ ieee802_1x_mka_encode_sak_use_body(
        u32 pn = 1;

        length = ieee802_1x_mka_get_sak_use_length(participant);
-       body = wpabuf_put(buf, length);
+       body = wpabuf_put(buf, MKA_ALIGN_LENGTH(length));

        body->type = MKA_SAK_USE;
        set_mka_param_body_len(body, length - MKA_HDR_LEN);
@@ -1439,7 +1439,7 @@ ieee802_1x_mka_get_dist_sak_length(
                length += cipher_suite_tbl[cs_index].sak_len + 8;
        }

-       return MKA_ALIGN_LENGTH(length);
+       return length;
 }


@@ -1458,7 +1458,7 @@ ieee802_1x_mka_encode_dist_sak_body(
        int sak_pos;

        length = ieee802_1x_mka_get_dist_sak_length(participant);
-       body = wpabuf_put(buf, length);
+       body = wpabuf_put(buf, MKA_ALIGN_LENGTH(length));
        body->type = MKA_DISTRIBUTED_SAK;
        set_mka_param_body_len(body, length - MKA_HDR_LEN);
        if (length == MKA_HDR_LEN) {
@@ -1683,7 +1683,7 @@ ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant)
        length = sizeof(struct ieee802_1x_mka_icv_body);
        length += mka_alg_tbl[participant->kay->mka_algindex].icv_len;

-       return MKA_ALIGN_LENGTH(length);
+       return length;
 }


@@ -1713,7 +1713,7 @@ ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,

        if (length != DEFAULT_ICV_LEN)
                length -= MKA_HDR_LEN;
-       os_memcpy(wpabuf_put(buf, length), cmac, length);
+       os_memcpy(wpabuf_put(buf, MKA_ALIGN_LENGTH(length - MKA_HDR_LEN)), cmac, length - MKA_HDR_LEN);

        return 0;
 }
@@ -2297,7 +2297,7 @@ ieee802_1x_participant_send_mkpdu(
        for (i = 0; i < ARRAY_SIZE(mka_body_handler); i++) {
                if (mka_body_handler[i].body_present &&
                    mka_body_handler[i].body_present(participant))
-                       length += mka_body_handler[i].body_length(participant);
+                       length += MKA_ALIGN_LENGTH(mka_body_handler[i].body_length(participant));
        }

        buf = wpabuf_alloc(length);
@@ -2931,7 +2931,7 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
        ieee802_1x_mka_dump_basic_body(body);
        body_len = get_mka_param_body_len(body);
        /* EAPOL-MKA body should comprise basic parameter set and ICV */
-       if (mka_msg_len < MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN) {
+       if (mka_msg_len < MKA_HDR_LEN + MKA_ALIGN_LENGTH(body_len) + DEFAULT_ICV_LEN) {
                wpa_printf(MSG_ERROR,
                           "KaY: Received EAPOL-MKA Packet Body Length (%zu bytes) is less than the Basic Parameter Set Header Length (%zu bytes) + the Basic Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
                           mka_msg_len, MKA_HDR_LEN,
@@ -3020,7 +3020,7 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,

        /* to skip basic parameter set */
        hdr = (struct ieee802_1x_mka_hdr *) pos;
-       body_len = get_mka_param_body_len(hdr);
+       body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr));
        pos += body_len + MKA_HDR_LEN;
        left_len -= body_len + MKA_HDR_LEN;

@@ -3060,7 +3060,7 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
             pos += body_len + MKA_HDR_LEN,
                     left_len -= body_len + MKA_HDR_LEN) {
                hdr = (struct ieee802_1x_mka_hdr *) pos;
-               body_len = get_mka_param_body_len(hdr);
+               body_len = MKA_ALIGN_LENGTH(get_mka_param_body_len(hdr));
                body_type = get_mka_param_body_type(hdr);

                if (body_type == MKA_ICV_INDICATOR)
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  2 12:10:53 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 2 Mar 2018 15:10:53 -0500
Subject: [PATCH 05/15] mka: finish implementation of CP state machine
 "port_enabled" parameter
In-Reply-To: <20180302201103.16264-1-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
Message-ID: <20180302201103.16264-6-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

KaY's controlled port (CP) state machine contains a 'port_enabled'
parameter, but the current implementation is incomplete.  There is no
way to set the value, and it is ignored by the CP state machine.

A new function, ieee802_1x_kay_notify_port_enabled(), has been added
that allows the system to notify KaY and CP of changes to the common
port's MAC_Operational state.  When port_enabled is set FALSE, the KaY
will stop transmitting MKPDUs and delete all secure associations as well
as all receive secure channels.  When port_enabled is set TRUE, the KaY
will resume MKA for all participants.

The KaY will also notify the CP whenever port_enabled changes state.
When port_enabled is FALSE the CP state machine will be forced back to
the INIT state, as perscribed by IEEE802.1X-2010 Figure 12-2 - CP state
machine.

Additionally fixed the setting of ieee802_1x_mka_participant.active,
which is used to calculate ieee802_1x_kay.active, which corresponds to
ieee8021XKayMkaActive in IEEE8021X-PAE-MIB.

Additionally fixed the behavior of ieee802_1x_kay_mka_participate(),
which now sets/clears ieee802_1x_mka_participant.participant.  I assume
this parameter is supposed to correspond to MKA.participate, which is
defined in IEEE802.1X-2010 Clause 12.2 Kay Interfaces.

 "- MKA.participate: Set by the Logon Process to request the actor's
    active participation in MKA.  Cleared by the Logon process to
    request the actor to cease participation."

Currently no process in hostap calls ieee802_1x_kay_mka_particiate(),
but if one ever does in the future the function should now work.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_cp.c    |  13 +++++-
 src/pae/ieee802_1x_cp.h    |   1 +
 src/pae/ieee802_1x_kay.c   | 103 ++++++++++++++++++++++++++++++++++++++++++---
 src/pae/ieee802_1x_kay.h   |   2 +
 src/pae/ieee802_1x_kay_i.h |   4 +-
 5 files changed, 114 insertions(+), 9 deletions(-)

diff --git a/src/pae/ieee802_1x_cp.c b/src/pae/ieee802_1x_cp.c
index 360fcd3f5..e6b2767e2 100644
--- a/src/pae/ieee802_1x_cp.c
+++ b/src/pae/ieee802_1x_cp.c
@@ -126,7 +126,6 @@ SM_STATE(CP, INIT)
        sm->otx = FALSE;
        sm->orx = FALSE;

-       sm->port_enabled = TRUE;
        sm->chgd_server = FALSE;
 }

@@ -448,6 +447,7 @@ struct ieee802_1x_cp_sm * ieee802_1x_cp_sm_init(struct ieee802_1x_kay *kay)
        sm->replay_window = kay->macsec_replay_window;

        sm->controlled_port_enabled = FALSE;
+       sm->port_enabled = TRUE;

        sm->lki = NULL;
        sm->lrx = FALSE;
@@ -693,6 +693,17 @@ void ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, Boolean status)


 /**
+ * ieee802_1x_cp_set_portenabled -
+ * @status: indicates MAC_Operational status of the common port
+ */
+void ieee802_1x_cp_set_portenabled(void *cp_ctx, Boolean status)
+{
+       struct ieee802_1x_cp_sm *sm = cp_ctx;
+       sm->port_enabled = status;
+}
+
+
+/**
  * ieee802_1x_cp_sm_step - Advance EAPOL state machines
  * @sm: EAPOL state machine
  *
diff --git a/src/pae/ieee802_1x_cp.h b/src/pae/ieee802_1x_cp.h
index 695629e5c..0d5358666 100644
--- a/src/pae/ieee802_1x_cp.h
+++ b/src/pae/ieee802_1x_cp.h
@@ -36,5 +36,6 @@ void ieee802_1x_cp_set_usingreceivesas(void *cp_ctx, Boolean status);
 void ieee802_1x_cp_set_allreceiving(void *cp_ctx, Boolean status);
 void ieee802_1x_cp_set_servertransmitting(void *cp_ctx, Boolean status);
 void ieee802_1x_cp_set_usingtransmitas(void *cp_ctx, Boolean status);
+void ieee802_1x_cp_set_portenabled(void *cp_ctx, Boolean status);

 #endif /* IEEE802_1X_CP_H */
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index fd329e610..17519ae69 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -772,6 +772,11 @@ ieee802_1x_mka_decode_basic_body(struct ieee802_1x_kay *kay, const u8 *mka_msg,
                return NULL;
        }

+       if (!participant->participant) {
+               wpa_printf(MSG_MSGDUMP, "KaY: MKA participation disabled");
+               return NULL;
+       }
+
        /* If the peer's MI is my MI, I will choose new MI */
        if (os_memcmp(body->actor_mi, participant->mi, MI_LEN) == 0) {
                if (!reset_participant_mi(participant))
@@ -1240,7 +1245,6 @@ ieee802_1x_mka_encode_sak_use_body(
        /* set CP's variable */
        if (body->ltx) {
                kay->tx_enable = TRUE;
-               kay->port_enable = TRUE;
        }
        if (body->lrx)
                kay->rx_enable = TRUE;
@@ -2329,6 +2333,28 @@ static void ieee802_1x_delete_transmit_sa(struct ieee802_1x_kay *kay,


 /**
+ * ieee802_1x_kay_recalc_mka_active -
+ */
+static void
+ieee802_1x_kay_recalc_mka_active(struct ieee802_1x_kay *kay)
+{
+       struct ieee802_1x_mka_participant *participant;
+       Boolean active = FALSE;
+
+       /* Recalculate KaY active (ieee8021XKayMkaActive) */
+       dl_list_for_each(participant, &kay->participant_list,
+                        struct ieee802_1x_mka_participant, list) {
+               if (participant->active) {
+                       active = TRUE;
+                       break;
+               }
+       }
+
+       kay->active = active;
+}
+
+
+/**
  * ieee802_1x_participant_timer -
  */
 static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
@@ -2338,6 +2364,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
        struct ieee802_1x_kay_peer *peer, *pre_peer;
        time_t now = time(NULL);
        Boolean lp_changed;
+       Boolean participate;
        struct receive_sc *rxsc, *pre_rxsc;
        struct transmit_sa *txsa, *pre_txsa;

@@ -2348,6 +2375,10 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                        goto delete_mka;
        }

+       /* only participate in MKA (i.e., transmit MKPDUs) if port
+        * is enabled and participant has not been disabled */
+       participate = kay->port_enable && participant->participant;
+
        /* should delete MKA instance if there are not live peers
         * when the MKA life elapsed since its creating */
        if (participant->mka_life) {
@@ -2362,7 +2393,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
        lp_changed = FALSE;
        dl_list_for_each_safe(peer, pre_peer, &participant->live_peers,
                              struct ieee802_1x_kay_peer, list) {
-               if (now > peer->expire) {
+               if (!participate || (now > peer->expire)) {
                        wpa_printf(MSG_DEBUG, "KaY: Live peer removed");
                        wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
                                    sizeof(peer->mi));
@@ -2420,7 +2451,7 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)

        dl_list_for_each_safe(peer, pre_peer, &participant->potential_peers,
                              struct ieee802_1x_kay_peer, list) {
-               if (now > peer->expire) {
+               if (!participate || (now > peer->expire)) {
                        wpa_printf(MSG_DEBUG, "KaY: Potential peer removed");
                        wpa_hexdump(MSG_DEBUG, "\tMI: ", peer->mi,
                                    sizeof(peer->mi));
@@ -2430,6 +2461,12 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                }
        }

+       if (!participate) {
+               participant->active = FALSE;
+               ieee802_1x_kay_recalc_mka_active(kay);
+               return;
+       }
+
        if (participant->new_sak) {
                if (!ieee802_1x_kay_generate_new_sak(participant))
                        participant->to_dist_sak = TRUE;
@@ -2836,7 +2873,7 @@ int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay)
        struct ieee802_1x_mka_participant *principal;

        principal = ieee802_1x_kay_get_principal_participant(kay);
-       if (!principal)
+       if (!principal || !principal->participant)
                return -1;

        if (principal->retry_count < MAX_RETRY_CNT || principal->mode == PSK) {
@@ -3321,7 +3358,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
        participant->cached = FALSE;

        participant->active = FALSE;
-       participant->participant = FALSE;
+       participant->participant = TRUE;
        participant->retain = FALSE;
        participant->activate = DEFAULT;

@@ -3465,6 +3502,8 @@ ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn)
        os_memset(&participant->kek, 0, sizeof(participant->kek));
        os_memset(&participant->ick, 0, sizeof(participant->ick));
        os_free(participant);
+
+       ieee802_1x_kay_recalc_mka_active(kay);
 }


@@ -3484,7 +3523,57 @@ void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
        if (!participant)
                return;

-       participant->active = status;
+       if (participant->participant == status)
+               return;
+
+       participant->participant = status;
+
+       if (status) {
+               /* Restart timer immediately if both port and participant are enabled */
+               if (kay->port_enable) {
+                       eloop_register_timeout(0, 0, ieee802_1x_participant_timer,
+                                              participant, NULL);
+               }
+       } else {
+               participant->active = FALSE;
+               ieee802_1x_kay_recalc_mka_active(kay);
+       }
+}
+
+
+/**
+ * ieee802_1x_kay_notify_port_enabled -
+ */
+void ieee802_1x_kay_notify_port_enabled(struct ieee802_1x_kay *kay,
+                                       Boolean enabled)
+{
+       struct ieee802_1x_mka_participant *participant;
+       unsigned int usecs;
+
+       if (kay->port_enable == enabled)
+               return;
+
+       wpa_printf(MSG_DEBUG, "KaY: External notification - "
+                  "portEnabled=%d", enabled);
+
+       kay->port_enable = enabled;
+
+       ieee802_1x_cp_set_portenabled(kay->cp, enabled);
+
+       if (!enabled) {
+               /* Existing participants will be cleaned up next time their timers expire */
+               kay->active = FALSE;
+       } else {
+               /* Staggered restart of participant timers */
+               dl_list_for_each(participant, &kay->participant_list,
+                                struct ieee802_1x_mka_participant, list) {
+                       if (participant->participant) {
+                               usecs = os_random() % (MKA_HELLO_TIME * 1000);
+                               eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
+                                                      participant, NULL);
+                       }
+               }
+       }
 }


@@ -3575,6 +3664,7 @@ int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                return 0;

        len = os_snprintf(buf, buflen,
+                         "Port status=%s\n"
                          "PAE KaY status=%s\n"
                          "Authenticated=%s\n"
                          "Secured=%s\n"
@@ -3584,6 +3674,7 @@ int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                          "Is Key Server=%s\n"
                          "Number of Keys Distributed=%u\n"
                          "Number of Keys Received=%u\n",
+                         kay->port_enable ? "Enabled" : "Disabled",
                          kay->active ? "Active" : "Not-Active",
                          kay->authenticated ? "Yes" : "No",
                          kay->secured ? "Yes" : "No",
diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index 8f394fd96..8c1a3b2fa 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -249,6 +249,8 @@ void ieee802_1x_kay_delete_mka(struct ieee802_1x_kay *kay,
 void ieee802_1x_kay_mka_participate(struct ieee802_1x_kay *kay,
                                    struct mka_key_name *ckn,
                                    Boolean status);
+void ieee802_1x_kay_notify_port_enabled(struct ieee802_1x_kay *kay,
+                                       Boolean enabled);
 int ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay);
 int ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
                                       unsigned int cs_index);
diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index bc522d898..c10851d2d 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -90,8 +90,8 @@ struct ieee802_1x_mka_participant {
        Boolean cached;

        /* used by management to monitor and control activation */
-       Boolean active;
-       Boolean participant;
+       Boolean active;      /* used to calculate ieee8021XKayMkaActive (IEEE8021X-PAE-MIB) */
+       Boolean participant; /* MKA.participate, from IEEE802.1X-2010, Clause 12.2 */
        Boolean retain;
        enum mka_created_mode mode;

--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From james at nurealm.net  Sat Mar  3 07:13:54 2018
From: james at nurealm.net (James Feeney)
Date: Sat, 3 Mar 2018 08:13:54 -0700
Subject: wpa_supplicant stops carrying traffic after some hours
Message-ID: <02a56001-37a0-168e-b741-4219d8ed8c41@nurealm.net>

I have a current Arch system on a dual core Pentium D Sony desktop machine running a PCICard Qualcomm Atheros AR5416 Wireless Network Adapter through a Ricoh RL5c475 PCI CardBus bridge adapter.  The Access Point is running LEDE/OpenWRT.

wpa_supplicant 1:2.6-11
linux 4.15.7-1

After a few hours, the wireless traffic continues to work on the local network, but just stops working across the outside network.  Now, this sounds like some problem with the Access Point or with the router - which is a linux desktop machine - but restarting wpa_supplicant on the remote machine fixes the problem.  The IP addresses and the routing table seem normal, but outside traffic seems to be dropped at the interface.  There is no firewall running, so that should not be an issue.

I suspect that wpa_supplicant is the problem, because a wpa_supplicant restart fixes things, but I don't know how else to troubleshoot this.  Any suggestions?

Thanks
James



From j at w1.fi  Sat Mar  3 11:19:07 2018
From: j at w1.fi (Jouni Malinen)
Date: Sat, 3 Mar 2018 21:19:07 +0200
Subject: Proposed Patch: Support for wolfSSL
In-Reply-To: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
References: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
Message-ID: <20180303191907.GA13466@w1.fi>

On Thu, Jan 18, 2018 at 12:26:39PM +1000, Sean Parkinson wrote:
> I?ve prepared a new patch with the changes as asked for by Jouni.
> 
> This patch was written to allow hostap to be compiled with the wolfSSL cryptography and TLS library.

Thanks! I'm seeing number of errors in the hwsim test cases, but it
looks like it is easiest to move ahead with this if I push in the
cleaned up version that I've been testing with some fixes to avoid
breaking non-wolfSSL builds. I'd welcome any incremental changes on top
of the current hostap.git master branch snapshot to address things that
I list below or maybe a recommendation on how to configure the wolfSSL
build properly to avoid the issues. I ran my tests with wolfSSL 3.13.0
and ended up adding various configure options until the build went
through cleanly. This ended up with following options:

./configure --prefix=/home/jm/wolfssl/3.13.0 --enable-des3 --enable-md4 --enable-harden --enable-pwdbased --enable-tlsv10 --enable-oldtls --enable-cmac --enable-aeskeywrap --enable-keygen --enable-crl --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 --enable-pkcallbacks --enable-tls13 --enable-fortress --enable-wpas --enable-static=yes --enable-shared=no


These are the notes from my hwsim test runs:

SAE:
- SAE: Could not solve y
- SAE: Could not pick PWE
--> check crypto_ec_point_solve_y_coord() implementation
   (wc_ecc_import_point_der() returns -1)
sae
sae_anti_clogging
sae_anti_clogging_proto
sae_bignum_failure
sae_forced_anti_clogging
sae_group_nego
sae_groups
sae_invalid_anti_clogging_token_req
sae_key_lifetime_in_memory
sae_mixed
sae_mixed_mfp
sae_no_random
sae_oom_wpas
sae_password
sae_password_ecc
sae_password_long
sae_password_short
sae_pmksa_caching
sae_pmksa_caching_disabled
sae_proto_confirm_replay
sae_proto_ecc
sae_pwe_failure
ap_ft_sae
ap_ft_sae_over_ds
sigma_dut_ap_psk_sae
sigma_dut_ap_sae
sigma_dut_ap_sae_group
sigma_dut_ap_sae_password
sigma_dut_sae
sigma_dut_sae_password
wpas_mesh_password_mismatch
mesh_forwarding_secure
ap_mixed_security


TLS interop(?) issue with OpenSSL server:
- OpenSSL server:
  * SSL: SSL3 alert: write (local SSL3 detected an error):fatal:bad record mac
  * SSL: SSL_accept:error in SSLv3 read finished A
  * OpenSSL: openssl_handshake - SSL_connect error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
ap_hs20_remediation_sql
eap_tls_no_session_resumption_radius
authsrv_testing_options
ap_wpa2_eap_tls_versions


OpenSSL authentication server:
- OpenSSL: openssl_handshake - SSL_connect error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
ap_wpa2_eap_ttls_dh_params
ap_wpa2_eap_ttls_dh_params_blob
ap_wpa2_eap_ttls_dh_params_dsa


OpenSSL authentication server:
- TLS: Certificate verification failed, error 20 (unable to get local issuer certificate) depth 0 for '/C=FI/O=w1.fi/CN=user.w1.fi'
- SSL: SSL3 alert: write (local SSL3 detected an error):fatal:unknown CA
- OpenSSL: openssl_handshake - SSL_connect error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
ap_wpa2_eap_tls_intermediate_ca
ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1
ap_wpa2_eap_tls_intermediate_ca_ocsp
ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked
ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked_sha1


TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
TLS: altSubjectName match 'EMAIL:noone at example.com;DNS:server.w1.fi;URI:http://example.com/' not found
wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
ap_wpa2_eap_ttls_pap_subject_match


TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
TLS: altSubjectName match 'EMAIL:noone at example.com;URI:http://example.com/;DNS:server.w1.fi' not found
wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
ap_wpa2_eap_ttls_chap_altsubject_match


TLS: Certificate verification failed, error -407 (Invalid OCSP Status Error) depth 2 for '/C=FI/O=w1.fi/CN=server.w1.fi'
ap_wpa2_eap_ttls_ocsp_revoked
ap_wpa2_eap_ttls_ocsp_unknown
ap_wpa2_eap_ttls_optional_ocsp_unknown


Missing altsubject in D-Bus output?!
dbus_connect_eap


DH: crypto_dh_derive_secret failed
eap_proto_ikev2


TLS: Certificate verification failed, error -238 (ASN CA path length larger than signer error) depth 2 for '/C=FI/O=w1.fi/CN=sha384.server.w1.fi'
eap_tls_sha384
eap_tls_sha512



GET_FAIL/GET_ALLOC_FAIL failure did not trigger:
radius_mppe_failure
authsrv_oom

 
-- 
Jouni Malinen                                            PGP id EFC895FA


From vvavrychuk at gmail.com  Sun Mar  4 06:56:22 2018
From: vvavrychuk at gmail.com (Vasyl Vavrychuk)
Date: Sun, 4 Mar 2018 16:56:22 +0200
Subject: [PATCH] fixed missing FindStopped in the case of separate
 P2P-Device interface
In-Reply-To: <20180212192720.14325-1-vvavrychuk@gmail.com>
References: <20180212192720.14325-1-vvavrychuk@gmail.com>
Message-ID: <CAGj4m+5xGrXYG5ZGROUm=iGfs76TxvGDNc3diLeL2MGphh_OuQ@mail.gmail.com>

Just reminding about this issue.

On Mon, Feb 12, 2018 at 9:27 PM, Vasyl Vavrychuk <vvavrychuk at gmail.com> wrote:
> Propagate similiar change to p2p_group_formation_failure and
> p2p_invitation_received.
>
> Some wireless controllers might have separate P2P-Device interface, see
> as example result of 'iw dev':
>
> phy#0
>         Unnamed/non-netdev interface
>                 ...
>                 type P2P-device
>                 ...
>         Interface wlp2s0
>                 type managed
>                 ...
>
> In this case there is separate 'struct wpa_supplicant' created for this
> p2p-dev-* device as result of 'wpa_supplicant_add_iface >
> wpas_p2p_add_p2pdev_interface > wpa_supplicant_add_iface'.
>
> This instance of wpa_supplicant is not registered in D-Bus
> (wpas_dbus_register_*) since for corresponding P2P device interface flag
> 'struct wpa_interface > p2p_mgmt' is set.
>
> But this instance is saved in p2p_init_wpa_s and is used for handling
> P2P related D-Bus commands. Therefore we should look for D-Bus path in
> the parent of p2p_init_wpa_s instance.
>
> Without this change test dbus_p2p_discovery starts failing if we set
> support_p2p_device in vm-run.sh.
>
> Signed-off-by: Vasyl Vavrychuk <vvavrychuk at gmail.com>
> ---
>  wpa_supplicant/dbus/dbus_new.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
> index 8115f7721..e0f16bbda 100644
> --- a/wpa_supplicant/dbus/dbus_new.c
> +++ b/wpa_supplicant/dbus/dbus_new.c
> @@ -2027,6 +2027,9 @@ void wpas_dbus_signal_p2p_group_formation_failure(struct wpa_supplicant *wpa_s,
>         if (iface == NULL)
>                 return;
>
> +       if (wpa_s->p2p_mgmt)
> +               wpa_s = wpa_s->parent;
> +
>         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
>                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
>                                       "GroupFormationFailure");
> @@ -2068,6 +2071,9 @@ void wpas_dbus_signal_p2p_invitation_received(struct wpa_supplicant *wpa_s,
>         if (iface == NULL)
>                 return;
>
> +       if (wpa_s->p2p_mgmt)
> +               wpa_s = wpa_s->parent;
> +
>         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
>                                       WPAS_DBUS_NEW_IFACE_P2PDEVICE,
>                                       "InvitationReceived");
> @@ -4266,7 +4272,13 @@ void wpas_dbus_signal_p2p_find_stopped(struct wpa_supplicant *wpa_s)
>         iface = wpa_s->global->dbus;
>
>         /* Do nothing if the control interface is not turned on */
> -       if (iface == NULL || !wpa_s->dbus_new_path)
> +       if (iface == NULL)
> +               return;
> +
> +       if (wpa_s->p2p_mgmt)
> +               wpa_s = wpa_s->parent;
> +
> +       if (!wpa_s->dbus_new_path)
>                 return;
>
>         msg = dbus_message_new_signal(wpa_s->dbus_new_path,
> --
> 2.11.0
>


From vvavrychuk at gmail.com  Sun Mar  4 07:00:05 2018
From: vvavrychuk at gmail.com (Vasyl Vavrychuk)
Date: Sun, 4 Mar 2018 17:00:05 +0200
Subject: [PATCH] clean-up setting iface->p2p_mgmt flag
In-Reply-To: <20180212192906.14583-1-vvavrychuk@gmail.com>
References: <20180212192906.14583-1-vvavrychuk@gmail.com>
Message-ID: <CAGj4m+4NaJ4mw8v31uHmP2va6i0=wZJ8pSJCC1dgHu+ZFSNPHA@mail.gmail.com>

Just reminding about this issue.

On Mon, Feb 12, 2018 at 9:29 PM, Vasyl Vavrychuk <vvavrychuk at gmail.com> wrote:
> Previously we set this flag to one in wpa_supplicant_init_iface if
> Wi-Fi controller does not have dedicated P2P-interface.
>
> This setting had effect only in scope of wpa_supplicant_init_iface and
> it contradicts with comment to 'struct wpa_interface > p2p_mgmt' field.
> This comment says that this flag is used only if Wi-Fi controller has
> dedicated P2P-device interface.
>
> Also it contradicts with usage of similiar p2p_mgmt field in
> wpa_supplicant struct. Again field p2p_mgmt in wpa_supplicant struct
> is set only for dedicated P2P-device interface.
>
> After this change wpa_interface become input argument to
> wpa_supplicant_init_iface that we are not modifying.
>
> Signed-off-by: Vasyl Vavrychuk <vvavrychuk at gmail.com>
> ---
>  wpa_supplicant/wpa_supplicant.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
> index fcb267764..73033eb3a 100644
> --- a/wpa_supplicant/wpa_supplicant.c
> +++ b/wpa_supplicant/wpa_supplicant.c
> @@ -5123,7 +5123,7 @@ radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
>
>
>  static int wpas_init_driver(struct wpa_supplicant *wpa_s,
> -                           struct wpa_interface *iface)
> +                           const struct wpa_interface *iface)
>  {
>         const char *ifname, *driver, *rn;
>
> @@ -5207,7 +5207,7 @@ static void wpas_gas_server_tx(void *ctx, int freq, const u8 *da,
>  #endif /* CONFIG_GAS_SERVER */
>
>  static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
> -                                    struct wpa_interface *iface)
> +                                    const struct wpa_interface *iface)
>  {
>         struct wpa_driver_capa capa;
>         int capa_res;
> @@ -5408,8 +5408,6 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
>          */
>         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
>                 wpa_s->p2p_mgmt = iface->p2p_mgmt;
> -       else
> -               iface->p2p_mgmt = 1;
>
>         if (wpa_s->num_multichan_concurrent == 0)
>                 wpa_s->num_multichan_concurrent = 1;
> @@ -5418,11 +5416,10 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
>                 return -1;
>
>  #ifdef CONFIG_TDLS
> -       if ((!iface->p2p_mgmt ||
> -            !(wpa_s->drv_flags &
> -              WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
> -           wpa_tdls_init(wpa_s->wpa))
> -               return -1;
> +       if (!iface->p2p_mgmt) {
> +               if (wpa_tdls_init(wpa_s->wpa))
> +                       return -1;
> +       }
>  #endif /* CONFIG_TDLS */
>
>         if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
> @@ -5493,9 +5490,12 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
>                 return -1;
>         }
>
> -       if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
> -               wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
> -               return -1;
> +       if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) ||
> +           wpa_s->p2p_mgmt) {
> +               if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
> +                       wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
> +                       return -1;
> +               }
>         }
>
>         if (wpa_bss_init(wpa_s) < 0)
> --
> 2.11.0
>


From janusz.dziedzic at gmail.com  Mon Mar  5 06:37:10 2018
From: janusz.dziedzic at gmail.com (Janusz Dziedzic)
Date: Mon,  5 Mar 2018 15:37:10 +0100
Subject: [PATCH] hostapd: FT, fix interop connection issue
Message-ID: <20180305143710.3764-1-janusz.dziedzic@gmail.com>

From: Janusz Dziedzic <janusz at plumewifi.com>

While configure AP for FT-PSK and WPA-PSK, HP
printer in assoc frame request both AKMs, but
don't add MDIE and don't use FT.

Next in logs we see:

RSN: Trying to use FT, but MDIE not included
IE - hexdump(len=26): 30 18 01 00 00 0f ac 04 01 00 00 0f ac 04
                      02 00 00 0f ac 02 00 0f ac 04 00 00

This is seen with some HP and Epson printers.
This patch strip FT when MDIE is not present and there
is still non-FT key mgmt available.

Signed-off-by: Janusz Dziedzic <janusz at plumewifi.com>
---
 src/ap/wpa_auth_ie.c |  7 +++++++
 src/common/defs.h    | 19 ++++++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
index 28db952..2ea081b 100644
--- a/src/ap/wpa_auth_ie.c
+++ b/src/ap/wpa_auth_ie.c
@@ -539,6 +539,13 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
 	if (version == WPA_PROTO_RSN) {
 		res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data);
 
+		if (wpa_key_mgmt_ft(data.key_mgmt) && !mdie &&
+		    !wpa_key_mgmt_only_ft(data.key_mgmt)) {
+			wpa_printf(MSG_DEBUG, "RSN: FT set in AKM but MDIE is missing, "
+				   "stripping FT because there's still non-FT key mgmt available");
+			data.key_mgmt &= ~WPA_KEY_MGMT_FT;
+		}
+
 		selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X;
 		if (0) {
 		}
diff --git a/src/common/defs.h b/src/common/defs.h
index 1de099f..38f5059 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -58,6 +58,12 @@ typedef enum { FALSE = 0, TRUE = 1 } Boolean;
 #define WPA_KEY_MGMT_OWE BIT(22)
 #define WPA_KEY_MGMT_DPP BIT(23)
 
+#define WPA_KEY_MGMT_FT (WPA_KEY_MGMT_FT_IEEE8021X | \
+			 WPA_KEY_MGMT_FT_PSK | \
+			 WPA_KEY_MGMT_FT_SAE | \
+			 WPA_KEY_MGMT_FT_FILS_SHA256 | \
+			 WPA_KEY_MGMT_FT_FILS_SHA384)
+
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
 	return !!(akm & (WPA_KEY_MGMT_IEEE8021X |
@@ -84,11 +90,14 @@ static inline int wpa_key_mgmt_wpa_psk(int akm)
 
 static inline int wpa_key_mgmt_ft(int akm)
 {
-	return !!(akm & (WPA_KEY_MGMT_FT_PSK |
-			 WPA_KEY_MGMT_FT_IEEE8021X |
-			 WPA_KEY_MGMT_FT_SAE |
-			 WPA_KEY_MGMT_FT_FILS_SHA256 |
-			 WPA_KEY_MGMT_FT_FILS_SHA384));
+	return !!(akm & WPA_KEY_MGMT_FT);
+}
+
+static inline int wpa_key_mgmt_only_ft(int akm)
+{
+	int ft = wpa_key_mgmt_ft(akm);
+	akm &= ~WPA_KEY_MGMT_FT;
+	return ft && !akm;
 }
 
 static inline int wpa_key_mgmt_ft_psk(int akm)
-- 
2.9.3



From thework.vlpl at gmail.com  Mon Mar  5 10:08:25 2018
From: thework.vlpl at gmail.com (work vlpl)
Date: Tue, 6 Mar 2018 00:08:25 +0600
Subject: How to test OSU server with mac80211_hwsim hostap and wpa_supplicant?
Message-ID: <CAPt3fZj=VXz-j5dxXvb9u2SRXnmz5iHYNRj9PrsO0tf_C1Kicg@mail.gmail.com>

Hello,
I setup my test environment with mac80211_hwsim. Create AP with
Hotspot 2.0 support, and can connect to it with wpa_supplicant
(eap-ttls authentication). Now, I want to test OSU server, for case
when user don't have credentials for this network. But can't figure
out how wpa_supplicant should fetch data over through ANQP, and  send
a request to OSU server to register in networks and get credentials.
?an someone show an example how to do it?

--
Vladimir


From jongwook at google.com  Mon Mar  5 17:01:23 2018
From: jongwook at google.com (Jong Wook Kim)
Date: Mon, 5 Mar 2018 17:01:23 -0800
Subject: [PATCH] Toggle to flush BSS entries when interface is disabled
Message-ID: <CADZiLaaX9Zhrf9aWGSCvsuOMjv+gSo+dgkxa51+fLvNNitNBGQ@mail.gmail.com>

Currently, bss entries are cleared out whenever the interface goes down.
This is the right thing to do most of the time, but this flush is unnecessary
when we are intentionally bringing the interface down and up as it takes
~3 seconds to re-scan all channels and fill up the bss entries again.

For Connected MAC Randomization, we have to bring the interface down,
change MAC address, bring the interface back up, and then start associating
(and we are observing ~3 scan delay here due to re-scanning).
Thus, we would like to have an option to not flush the cache when the
interface is disabled.

Do let me know if there would be a better way to avoid this delay. Thanks.

Signed-off-by: Jong Wook Kim <jongwook at google.com>
---
 wpa_supplicant/config.c      | 1 +
 wpa_supplicant/config.h      | 8 ++++++++
 wpa_supplicant/config_file.c | 3 +++
 wpa_supplicant/events.c      | 4 +++-
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index a22434cb..87161481 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -4642,6 +4642,7 @@ static const struct global_parse_data global_fields[] = {
  { INT(gas_rand_addr_lifetime), 0 },
  { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
  { INT_RANGE(dpp_config_processing, 0, 2), 0 },
+ { INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
 };

 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 07b67e6b..c63ef1d6 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1418,6 +1418,14 @@ struct wpa_config {
  * profile automatically
  */
  int dpp_config_processing;
+
+ /**
+ * bss_no_flush_when_down - Whether to flush BSS entries when the
interface is disabled
+ *
+ * 0 = Flush BSS entries when the interface becomes disabled (Default)
+ * 1 = Do not flush BSS entries when the interface becomes disabled
+ */
+ int bss_no_flush_when_down;
 };


diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 1fd432d1..d219c3da 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1490,6 +1490,9 @@ static void wpa_config_write_global(FILE *f,
struct wpa_config *config)
  if (config->dpp_config_processing)
  fprintf(f, "dpp_config_processing=%d\n",
  config->dpp_config_processing);
+ if (config->bss_no_flush_when_down)
+ fprintf(f, "bss_no_flush_when_down=%d\n",
+ config->bss_no_flush_when_down);

 }

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 63cf7737..708c6fc3 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -4390,7 +4390,9 @@ void wpa_supplicant_event(void *ctx, enum
wpa_event_type event,
  wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
  }
  wpa_supplicant_mark_disassoc(wpa_s);
- wpa_bss_flush(wpa_s);
+ if (wpa_s->conf->bss_no_flush_when_down == 0)
+ wpa_bss_flush(wpa_s);
+
  radio_remove_works(wpa_s, NULL, 0);

  wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
-- 
2.16.2.395.g2e18187dfd-goog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Toggle-to-flush-BSS-entries-when-interface-is-disabl.patch
Type: text/x-patch
Size: 3001 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20180305/d5285b95/attachment.bin>

From dcbw at redhat.com  Mon Mar  5 19:31:34 2018
From: dcbw at redhat.com (Dan Williams)
Date: Mon, 05 Mar 2018 21:31:34 -0600
Subject: [PATCH] Toggle to flush BSS entries when interface is disabled
In-Reply-To: <CADZiLaaX9Zhrf9aWGSCvsuOMjv+gSo+dgkxa51+fLvNNitNBGQ@mail.gmail.com>
References: <CADZiLaaX9Zhrf9aWGSCvsuOMjv+gSo+dgkxa51+fLvNNitNBGQ@mail.gmail.com>
Message-ID: <1520307094.15647.47.camel@redhat.com>

On Mon, 2018-03-05 at 17:01 -0800, Jong Wook Kim wrote:
> Currently, bss entries are cleared out whenever the interface goes
> down.
> This is the right thing to do most of the time, but this flush is
> unnecessary
> when we are intentionally bringing the interface down and up as it
> takes
> ~3 seconds to re-scan all channels and fill up the bss entries again.
> 
> For Connected MAC Randomization, we have to bring the interface down,
> change MAC address, bring the interface back up, and then start
> associating
> (and we are observing ~3 scan delay here due to re-scanning).
> Thus, we would like to have an option to not flush the cache when the
> interface is disabled.
> 
> Do let me know if there would be a better way to avoid this delay.
> Thanks.

Possibly a cleaner option would be to add a "change this interface's
MAC address to X" control interface call to the supplicant that takes
an optional parameter that says whether or not to flush BSSes.  (not
quite sure how it would suppress the netlink events that would just end
up back in wpa_supplicant_event though).

The toggle in the patch below is a pretty big hammer, since it will
happen for every EVENT_INTERFACE_DISABLED, whether that's intended or
not.  There are clearly cases where it would be useful to flush the BSS
list on interface down.

Dan

> Signed-off-by: Jong Wook Kim <jongwook at google.com>
> ---
>  wpa_supplicant/config.c      | 1 +
>  wpa_supplicant/config.h      | 8 ++++++++
>  wpa_supplicant/config_file.c | 3 +++
>  wpa_supplicant/events.c      | 4 +++-
>  4 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
> index a22434cb..87161481 100644
> --- a/wpa_supplicant/config.c
> +++ b/wpa_supplicant/config.c
> @@ -4642,6 +4642,7 @@ static const struct global_parse_data
> global_fields[] = {
>   { INT(gas_rand_addr_lifetime), 0 },
>   { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
>   { INT_RANGE(dpp_config_processing, 0, 2), 0 },
> + { INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
>  };
> 
>  #undef FUNC
> diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
> index 07b67e6b..c63ef1d6 100644
> --- a/wpa_supplicant/config.h
> +++ b/wpa_supplicant/config.h
> @@ -1418,6 +1418,14 @@ struct wpa_config {
>   * profile automatically
>   */
>   int dpp_config_processing;
> +
> + /**
> + * bss_no_flush_when_down - Whether to flush BSS entries when the
> interface is disabled
> + *
> + * 0 = Flush BSS entries when the interface becomes disabled
> (Default)
> + * 1 = Do not flush BSS entries when the interface becomes disabled
> + */
> + int bss_no_flush_when_down;
>  };
> 
> 
> diff --git a/wpa_supplicant/config_file.c
> b/wpa_supplicant/config_file.c
> index 1fd432d1..d219c3da 100644
> --- a/wpa_supplicant/config_file.c
> +++ b/wpa_supplicant/config_file.c
> @@ -1490,6 +1490,9 @@ static void wpa_config_write_global(FILE *f,
> struct wpa_config *config)
>   if (config->dpp_config_processing)
>   fprintf(f, "dpp_config_processing=%d\n",
>   config->dpp_config_processing);
> + if (config->bss_no_flush_when_down)
> + fprintf(f, "bss_no_flush_when_down=%d\n",
> + config->bss_no_flush_when_down);
> 
>  }
> 
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 63cf7737..708c6fc3 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -4390,7 +4390,9 @@ void wpa_supplicant_event(void *ctx, enum
> wpa_event_type event,
>   wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
>   }
>   wpa_supplicant_mark_disassoc(wpa_s);
> - wpa_bss_flush(wpa_s);
> + if (wpa_s->conf->bss_no_flush_when_down == 0)
> + wpa_bss_flush(wpa_s);
> +
>   radio_remove_works(wpa_s, NULL, 0);
> 
>   wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap


From greearb at candelatech.com  Tue Mar  6 12:55:45 2018
From: greearb at candelatech.com (greearb at candelatech.com)
Date: Tue,  6 Mar 2018 12:55:45 -0800
Subject: [PATCH] nl80211:  Add MLME assoc work-around for -EEXIST errno
Message-ID: <1520369745-26312-1-git-send-email-greearb@candelatech.com>

From: Ben Greear <greearb at candelatech.com>

The 4.9 kernel, at least, can return EEXIST when trying to add
a station that already exists.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---
 src/drivers/driver_nl80211.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 373f745..1fe0a5c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3294,7 +3294,8 @@ retry:
 		wpa_dbg(drv->ctx, MSG_INFO,
 			"nl80211: MLME command failed (auth): count=%d ret=%d (%s)",
 			count, ret, strerror(-ret));
-		if (ret == -EALREADY && count == 1 && params->bssid &&
+		if (((ret == -EALREADY) || (ret == -EEXIST))
+		    && count == 1 && params->bssid &&
 		    !params->local_state_change) {
 			/* Nov 9, 2017:  Re-enable this...user saw endless loop of
 			 * hitting this case.  Maybe the original reason I put this hack
-- 
2.7.5



From jongwook at google.com  Tue Mar  6 17:08:38 2018
From: jongwook at google.com (Jong Wook Kim)
Date: Tue, 6 Mar 2018 17:08:38 -0800
Subject: [PATCH] Toggle to flush BSS entries when interface is disabled
In-Reply-To: <1520307094.15647.47.camel@redhat.com>
References: <CADZiLaaX9Zhrf9aWGSCvsuOMjv+gSo+dgkxa51+fLvNNitNBGQ@mail.gmail.com>
 <1520307094.15647.47.camel@redhat.com>
Message-ID: <CADZiLaaZDVQ1F5uW5vzsxKpcpE87=OrLQhD3CKbSdKOWwAPvMA@mail.gmail.com>

That is a good point as in most cases, we do want BSS entries flushed.

We found this driver_nl80211->ignore_if_down_event value
that if set, prevents EVENT_INTERFACE_DISABLED from being
sent out when the interface goes down (as a result, there would be no
BSS flush when down). This is currently used when we are changing
the driver mode.

We are thinking about simply setting this value before bringing the interface
down for MAC change. Do you have any feedback for doing things this way?

Thanks.

Jong

On Mon, Mar 5, 2018 at 7:31 PM, Dan Williams <dcbw at redhat.com> wrote:
> On Mon, 2018-03-05 at 17:01 -0800, Jong Wook Kim wrote:
>> Currently, bss entries are cleared out whenever the interface goes
>> down.
>> This is the right thing to do most of the time, but this flush is
>> unnecessary
>> when we are intentionally bringing the interface down and up as it
>> takes
>> ~3 seconds to re-scan all channels and fill up the bss entries again.
>>
>> For Connected MAC Randomization, we have to bring the interface down,
>> change MAC address, bring the interface back up, and then start
>> associating
>> (and we are observing ~3 scan delay here due to re-scanning).
>> Thus, we would like to have an option to not flush the cache when the
>> interface is disabled.
>>
>> Do let me know if there would be a better way to avoid this delay.
>> Thanks.
>
> Possibly a cleaner option would be to add a "change this interface's
> MAC address to X" control interface call to the supplicant that takes
> an optional parameter that says whether or not to flush BSSes.  (not
> quite sure how it would suppress the netlink events that would just end
> up back in wpa_supplicant_event though).
>
> The toggle in the patch below is a pretty big hammer, since it will
> happen for every EVENT_INTERFACE_DISABLED, whether that's intended or
> not.  There are clearly cases where it would be useful to flush the BSS
> list on interface down.
>
> Dan
>
>> Signed-off-by: Jong Wook Kim <jongwook at google.com>
>> ---
>>  wpa_supplicant/config.c      | 1 +
>>  wpa_supplicant/config.h      | 8 ++++++++
>>  wpa_supplicant/config_file.c | 3 +++
>>  wpa_supplicant/events.c      | 4 +++-
>>  4 files changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
>> index a22434cb..87161481 100644
>> --- a/wpa_supplicant/config.c
>> +++ b/wpa_supplicant/config.c
>> @@ -4642,6 +4642,7 @@ static const struct global_parse_data
>> global_fields[] = {
>>   { INT(gas_rand_addr_lifetime), 0 },
>>   { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
>>   { INT_RANGE(dpp_config_processing, 0, 2), 0 },
>> + { INT_RANGE(bss_no_flush_when_down, 0, 1), 0 },
>>  };
>>
>>  #undef FUNC
>> diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
>> index 07b67e6b..c63ef1d6 100644
>> --- a/wpa_supplicant/config.h
>> +++ b/wpa_supplicant/config.h
>> @@ -1418,6 +1418,14 @@ struct wpa_config {
>>   * profile automatically
>>   */
>>   int dpp_config_processing;
>> +
>> + /**
>> + * bss_no_flush_when_down - Whether to flush BSS entries when the
>> interface is disabled
>> + *
>> + * 0 = Flush BSS entries when the interface becomes disabled
>> (Default)
>> + * 1 = Do not flush BSS entries when the interface becomes disabled
>> + */
>> + int bss_no_flush_when_down;
>>  };
>>
>>
>> diff --git a/wpa_supplicant/config_file.c
>> b/wpa_supplicant/config_file.c
>> index 1fd432d1..d219c3da 100644
>> --- a/wpa_supplicant/config_file.c
>> +++ b/wpa_supplicant/config_file.c
>> @@ -1490,6 +1490,9 @@ static void wpa_config_write_global(FILE *f,
>> struct wpa_config *config)
>>   if (config->dpp_config_processing)
>>   fprintf(f, "dpp_config_processing=%d\n",
>>   config->dpp_config_processing);
>> + if (config->bss_no_flush_when_down)
>> + fprintf(f, "bss_no_flush_when_down=%d\n",
>> + config->bss_no_flush_when_down);
>>
>>  }
>>
>> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
>> index 63cf7737..708c6fc3 100644
>> --- a/wpa_supplicant/events.c
>> +++ b/wpa_supplicant/events.c
>> @@ -4390,7 +4390,9 @@ void wpa_supplicant_event(void *ctx, enum
>> wpa_event_type event,
>>   wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
>>   }
>>   wpa_supplicant_mark_disassoc(wpa_s);
>> - wpa_bss_flush(wpa_s);
>> + if (wpa_s->conf->bss_no_flush_when_down == 0)
>> + wpa_bss_flush(wpa_s);
>> +
>>   radio_remove_works(wpa_s, NULL, 0);
>>
>>   wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
>> _______________________________________________
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap


From yvsg.phanis at gmail.com  Thu Mar  8 07:33:10 2018
From: yvsg.phanis at gmail.com (Phani Siriki)
Date: Thu, 8 Mar 2018 09:33:10 -0600
Subject: Query on WMM AC parameters configuration using netlink
In-Reply-To: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>
References: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>
Message-ID: <CADsGw2b6YyZo7R22JWBKN_qjojKtDzxJFdjMY3aHvoacQAwGcw@mail.gmail.com>

Could someone help me on this?

Best Regards
Phani

On Thu, Mar 1, 2018 at 7:06 PM, Phani Siriki <yvsg.phanis at gmail.com> wrote:
> Hi All
>
> I am working on changing the TXQ queue parameters dynamically using
> netlink sockets.
>
> As of now, I was able to change the TXQ parameters used by AP(tx_queue
> parameters in hostap.conf) by setting the structure
> NL80211_ATTR_WIPHY_TXQ_PARAMS.
>
> I tested this on mininet-wifi and I able to see below debug output.
>
> Feb 21 11:57:01 wifi-VirtualBox kernel: [38320.963179] ieee80211
> mn00s02: mac80211_hwsim_conf_tx (queue=0 txop=0 cw_min=7 cw_max=15
> aifs=2)
> Feb 21 11:57:01 wifi-VirtualBox kernel: [38320.963184] ieee80211
> mn00s02: mac80211_hwsim_bss_info_changed(changed=0x2000
> vif->addr=02:00:00:00:02:00)
>
> Now, I want to change the wmm_ac parameters as well, but couldn't get
> the exact netlink parameter to set.
>
> Could someone point me the nl80211 parameter used to set these
> parameters in AP, so that AP can advertise these values to stations in
> their IE?
>
> Best Regards
> Phani


From davide.caratti at gmail.com  Thu Mar  8 08:15:02 2018
From: davide.caratti at gmail.com (Davide Caratti)
Date: Thu,  8 Mar 2018 17:15:02 +0100
Subject: [PATCH] wpa_supplicant: fix 2 memory leaks in
 ieee802_1x_create_preshared_mka()
Message-ID: <3db3d40417d4190ee071fb858e4d77834f3f709e.1520524691.git.davide.caratti@gmail.com>

in case MKA is initialized successfully, local copies of CAK and CKN are
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 <davide.caratti at gmail.com>
---
 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



From msiedzik at extremenetworks.com  Fri Mar  9 12:53:04 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 9 Mar 2018 15:53:04 -0500
Subject: [PATCH 1/2] mka: ICV not encoded correctly,
 causing receive side to drop MKPDU
In-Reply-To: <20180302201103.16264-7-msiedzik@extremenetworks.com>
References: <20180302201103.16264-7-msiedzik@extremenetworks.com>
Message-ID: <20180309205305.48783-1-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

The previously submitted "PATCH 06/15 mka: KaY setting Parameter Set
Body Length Incorrectly" introduced a new bug where
ieee802_1x_mka_encode_icv_body() encodes 4 fewer octets than required.

Thanks to Jaap Keuter <jaap.keuter at xs4all.nl> for finding this bug and
working with me to resolve it.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 2 --
 1 file changed, 2 deletions(-)
 mode change 100644 => 100755 src/pae/ieee802_1x_kay.c

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
old mode 100644
new mode 100755
index 6ac7d02d1..9fa2c211f
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1746,8 +1746,6 @@ ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
                return -1;
        }

-       if (length != DEFAULT_ICV_LEN)
-               length -= MKA_HDR_LEN;
        os_memcpy(wpabuf_put(buf, MKA_ALIGN_LENGTH(length - MKA_HDR_LEN)), cmac, length - MKA_HDR_LEN);

        return 0;
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From msiedzik at extremenetworks.com  Fri Mar  9 12:53:05 2018
From: msiedzik at extremenetworks.com (msiedzik at extremenetworks.com)
Date: Fri, 9 Mar 2018 15:53:05 -0500
Subject: [PATCH 2/2] mka: Optional ICV indicator encoded when not necessary
In-Reply-To: <20180302201103.16264-7-msiedzik@extremenetworks.com>
References: <20180302201103.16264-7-msiedzik@extremenetworks.com>
Message-ID: <20180309205305.48783-2-msiedzik@extremenetworks.com>

From: Mike Siedzik <msiedzik at extremenetworks.com>

IEEE802.1X-2010 Clause 11.11.3 "Encoding MKPDUs", item (e) states that
the ICV Indicator must be encoded if the ICV length is not 16 octets,
and Table 11-7 "MKPDU parameter sets" lists the "ICV Indicator" as
optional.

The function ieee802_1x_mka_encode_icv_body() intends to only encode the
ICV Indicator when the ICV length is not equal to DEFAULT_ICV_LEN(16).
However the comparison made is between the length of the entire ICV
parameter set, not just the ICV length.

This results in the KaY encoding and sending the optional ICV Indicator
when it was not necessary.  The resulting MKPDU is still valid, but is
4 octets longer than necessary.

Thanks to Jaap Keuter <jaap.keuter at xs4all.nl> for finding this bug.  He
recommends not applying this patch, as most real world implementations
of MKA send the ICV Indicator unconditionally.

Signed-off-by: Michael Siedzik <msiedzik at extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 9fa2c211f..e77edb724 100755
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1706,17 +1706,35 @@ ieee802_1x_mka_icv_body_present(struct ieee802_1x_mka_participant *participant)
        return TRUE;
 }

+/**
+ * ieee802_1x_mka_icv_indicator_required
+ *
+ * Per IEEE802.1X-2010, Clause 11.11.3 Encoding MKPDUs, item (e):
+ * "If Algorithm Agility parameter specifies the use of an ICV that
+ *  is not 16 octets in length, the ICV Indicator is encoded as
+ *  specified in Figure 11-6."
+ */
+static Boolean
+ieee802_1x_mka_icv_indicator_required(struct ieee802_1x_mka_participant *participant)
+{
+       return (mka_alg_tbl[participant->kay->mka_algindex].icv_len != DEFAULT_ICV_LEN);
+}

 /**
  * ieee802_1x_kay_get_icv_length
+ *
+ * Return the unaligned length of the ICV parameter set, which consists
+ * of an optional ICV Indicator plus a manditory ICV.
  */
 static int
 ieee802_1x_mka_get_icv_length(struct ieee802_1x_mka_participant *participant)
 {
        int length;

-       length = sizeof(struct ieee802_1x_mka_icv_body);
-       length += mka_alg_tbl[participant->kay->mka_algindex].icv_len;
+       length = mka_alg_tbl[participant->kay->mka_algindex].icv_len;
+       if (ieee802_1x_mka_icv_indicator_required(participant)) {
+               length += sizeof(struct ieee802_1x_mka_icv_body);
+       }

        return length;
 }
@@ -1730,14 +1748,18 @@ ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
                               struct wpabuf *buf)
 {
        struct ieee802_1x_mka_icv_body *body;
-       unsigned int length;
+       unsigned int icv_indicator_length;
+       unsigned int icv_length;
        u8 cmac[MAX_ICV_LEN];

-       length = ieee802_1x_mka_get_icv_length(participant);
-       if (length != DEFAULT_ICV_LEN)  {
-               body = wpabuf_put(buf, MKA_HDR_LEN);
+       icv_indicator_length = sizeof(struct ieee802_1x_mka_icv_body);
+       icv_length = mka_alg_tbl[participant->kay->mka_algindex].icv_len;
+
+       /* Only encode ICV Indicator if it is required */
+       if (ieee802_1x_mka_icv_indicator_required(participant)) {
+               body = wpabuf_put(buf, icv_indicator_length);
                body->type = MKA_ICV_INDICATOR;
-               set_mka_param_body_len(body, length - MKA_HDR_LEN);
+               set_mka_param_body_len(body, icv_length);
        }

        if (mka_alg_tbl[participant->kay->mka_algindex].icv_hash(
@@ -1746,7 +1768,8 @@ ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
                return -1;
        }

-       os_memcpy(wpabuf_put(buf, MKA_ALIGN_LENGTH(length - MKA_HDR_LEN)), cmac, length - MKA_HDR_LEN);
+       /* Always encode ICV */
+       os_memcpy(wpabuf_put(buf, MKA_ALIGN_LENGTH(icv_length)), cmac, icv_length);

        return 0;
 }
--
2.11.1


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From j at w1.fi  Sun Mar 11 03:50:23 2018
From: j at w1.fi (Jouni Malinen)
Date: Sun, 11 Mar 2018 12:50:23 +0200
Subject: [PATCH] nl80211:  Add MLME assoc work-around for -EEXIST errno
In-Reply-To: <1520369745-26312-1-git-send-email-greearb@candelatech.com>
References: <1520369745-26312-1-git-send-email-greearb@candelatech.com>
Message-ID: <20180311105023.GA14803@w1.fi>

On Tue, Mar 06, 2018 at 12:55:45PM -0800, greearb at candelatech.com wrote:
> The 4.9 kernel, at least, can return EEXIST when trying to add
> a station that already exists.

This is a bit confusing commit message since it talks about "assoc" and
adding a station while the code change is actually for authentication
(NL80211_CMD_AUTHENTICATE)..

What is the use case where you see the station (mac80211 STA entry, I'd
assume) being already there?

> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
> @@ -3294,7 +3294,8 @@ retry:
>  		wpa_dbg(drv->ctx, MSG_INFO,
>  			"nl80211: MLME command failed (auth): count=%d ret=%d (%s)",
>  			count, ret, strerror(-ret));
> -		if (ret == -EALREADY && count == 1 && params->bssid &&
> +		if (((ret == -EALREADY) || (ret == -EEXIST))
> +		    && count == 1 && params->bssid &&
>  		    !params->local_state_change) {
>  			/* Nov 9, 2017:  Re-enable this...user saw endless loop of
>  			 * hitting this case.  Maybe the original reason I put this hack

This does not apply due to a missing "count++" and extra "Nov 9, 2017"
comment, i.e., the baseline is quite different compared to what exists
in hostap.git.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Sun Mar 11 03:57:57 2018
From: j at w1.fi (Jouni Malinen)
Date: Sun, 11 Mar 2018 12:57:57 +0200
Subject: wpa_supplicant stops carrying traffic after some hours
In-Reply-To: <02a56001-37a0-168e-b741-4219d8ed8c41@nurealm.net>
References: <02a56001-37a0-168e-b741-4219d8ed8c41@nurealm.net>
Message-ID: <20180311105757.GB14803@w1.fi>

On Sat, Mar 03, 2018 at 08:13:54AM -0700, James Feeney wrote:
> After a few hours, the wireless traffic continues to work on the local network, but just stops working across the outside network.  Now, this sounds like some problem with the Access Point or with the router - which is a linux desktop machine - but restarting wpa_supplicant on the remote machine fixes the problem.  The IP addresses and the routing table seem normal, but outside traffic seems to be dropped at the interface.  There is no firewall running, so that should not be an issue.
> 
> I suspect that wpa_supplicant is the problem, because a wpa_supplicant restart fixes things, but I don't know how else to troubleshoot this.  Any suggestions?

Restarting wpa_supplicant may clear whatever was broken here because
that forces the station to reassociate with the AP and practically clear
all state, but if I understood your description correctly, this is very
unlikely to be an issue caused by wpa_supplicant. If the traffic goes
through fine to the AP and to the local network, but fails to go through
to "outside network" (which I'm assuming is referring to going through
an IP router), the Wi-Fi connection part is likely to be functional and
issue is somewhere in the AP. Debugging this on the AP would likely be
more fruitful path at finding the issue or alternatively, looking at a
wireless sniffer capture to see if the relevant frames make out from the
station to the AP.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Sun Mar 11 04:00:49 2018
From: j at w1.fi (Jouni Malinen)
Date: Sun, 11 Mar 2018 13:00:49 +0200
Subject: Query on WMM AC parameters configuration using netlink
In-Reply-To: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>
References: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>
Message-ID: <20180311110049.GC14803@w1.fi>

On Thu, Mar 01, 2018 at 07:06:11PM -0600, Phani Siriki wrote:
> Now, I want to change the wmm_ac parameters as well, but couldn't get
> the exact netlink parameter to set.
> 
> Could someone point me the nl80211 parameter used to set these
> parameters in AP, so that AP can advertise these values to stations in
> their IE?

There is no nl80211 parameter for this. The WMM element that advertises
values for station is part of the Beacon/Probe Response frame template
that gets set when starting or updating the AP/BSS information. This may
depend on the Wi-Fi driver that is used, but for example with
mac80211_hwsim, you cannot change this independently without updating
the full Beacon template (i.e., you have to update this through hostapd
to avoid conflicts with other Beacon frame information changes).

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Sun Mar 11 04:06:40 2018
From: j at w1.fi (Jouni Malinen)
Date: Sun, 11 Mar 2018 13:06:40 +0200
Subject: Request: add missing standard RADIUS attribute types
In-Reply-To: <b1b21dfc-a399-e2c0-7818-c96e6011f439@um.es>
References: <b1b21dfc-a399-e2c0-7818-c96e6011f439@um.es>
Message-ID: <20180311110640.GD14803@w1.fi>

On Thu, Mar 01, 2018 at 10:57:32AM +0100, Alejandro P?rez M?ndez wrote:
> I'd like to request the addition of four RADIUS attribute types, that are
> missing in the radius/radius.h file. They are defined in section 7.4 of RFC
> 7055. They would be:
> 
> RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 164
> RADIUS_ATTR_GSS_ACCEPTOR_HOST_NAME = 165
> RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_SPECIFICS = 166
> RADIUS_ATTR_GSS_ACCEPTOR_REALM_NAME = 167

Could you please clarify what exactly you are asking for here? Support
for GSS-API in general? Just defining those attribute type values in
radius.h? Printing these in some debug messages? Or something else?

-- 
Jouni Malinen                                            PGP id EFC895FA


From james at nurealm.net  Sun Mar 11 06:39:02 2018
From: james at nurealm.net (James Feeney)
Date: Sun, 11 Mar 2018 07:39:02 -0600
Subject: wpa_supplicant stops carrying traffic after some hours
In-Reply-To: <20180311105757.GB14803@w1.fi>
References: <02a56001-37a0-168e-b741-4219d8ed8c41@nurealm.net>
 <20180311105757.GB14803@w1.fi>
Message-ID: <979ef8f3-624b-e24e-b33a-5cf931c0d3d0@nurealm.net>

On 03/11/2018 04:57 AM, Jouni Malinen wrote:
> Restarting wpa_supplicant may clear whatever was broken here because
> that forces the station to reassociate with the AP and practically clear
> all state

Simply reassociating does not fix the problem.  A full restart is doing something different.

> If the traffic goes
> through fine to the AP and to the local network, but fails to go through
> to "outside network" (which I'm assuming is referring to going through
> an IP router), the Wi-Fi connection part is likely to be functional and
> issue is somewhere in the AP.

No - instead, the traffic seems to stop at the local machine interface.  Packets can be seen on the local network, but the machine stops responding.  Perhaps this is something with the kernel IP stack?  Perhaps the kernel stops talking to wpa_supplicant?  How could I test for that, or prove that?

But, I don't understand how the "local" network could act differently from the "outside" network.  In practice, I am connected to the machine "locally" through ssh.  If then, I try to, say, ping Google, there is no response.  Restart wpa_supplicant and ping works fine again.

And the failure is history dependent.  I only see this fail after a lot of "external" traffic.

And the fact that this network communication has to go through two different bus interfaces, from the PCcard to the PCI layer, and then from the PCI layer to the kernel, could that be causing some problem?  The PCcard driver probably doesn't get much testing these days.  Is there some way to "snoop" communication between these layers?

Thanks
James


From j at w1.fi  Sun Mar 11 07:36:36 2018
From: j at w1.fi (Jouni Malinen)
Date: Sun, 11 Mar 2018 16:36:36 +0200
Subject: [PATCH 03/15] mka: Incorrect conf_offset sent in MKPDU when in
 policy mode "SHOULD_SECURE"
In-Reply-To: <20180302201103.16264-4-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-4-msiedzik@extremenetworks.com>
Message-ID: <20180311143636.GA30889@w1.fi>

On Fri, Mar 02, 2018 at 03:10:51PM -0500, msiedzik at extremenetworks.com wrote:

> diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
> @@ -3166,14 +3167,16 @@ 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;
> +               if (policy == SHOULD_SECURE) {
> +                       kay->macsec_encrypt = FALSE;
> +                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
> +               } else {  /* SHOULD_ENCRYPT */
> +                       kay->macsec_encrypt = TRUE;
> +                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
> +               }
>                 kay->macsec_validate = Strict;
>                 kay->macsec_replay_protect = FALSE;
>                 kay->macsec_replay_window = 0;
> -               if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF)
> -                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
> -               else
> -                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
>         }

Is this change dropping the kay->macsec_capable check on purpose for
SHOULD_ENCRYPT case? The new SHOULD_SECURE case looks fine, but should
the SHOULD_ENCRYPT case still use this kay->macsec_capable >=
MACSEC_CAP_INTEG_AND_CONF before setting CONFIDENTIALITY_OFFSET_0?

-- 
Jouni Malinen                                            PGP id EFC895FA


From alex at um.es  Sun Mar 11 08:24:58 2018
From: alex at um.es (=?UTF-8?Q?Alejandro_P=c3=a9rez_M=c3=a9ndez?=)
Date: Sun, 11 Mar 2018 16:24:58 +0100
Subject: Request: add missing standard RADIUS attribute types
In-Reply-To: <20180311110640.GD14803@w1.fi>
References: <b1b21dfc-a399-e2c0-7818-c96e6011f439@um.es>
 <20180311110640.GD14803@w1.fi>
Message-ID: <43ff828f-3bd4-8507-e68b-d36dcc7b2ee1@um.es>


>> I'd like to request the addition of four RADIUS attribute types, that are
>> missing in the radius/radius.h file. They are defined in section 7.4 of RFC
>> 7055. They would be:
>>
>> RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 164
>> RADIUS_ATTR_GSS_ACCEPTOR_HOST_NAME = 165
>> RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_SPECIFICS = 166
>> RADIUS_ATTR_GSS_ACCEPTOR_REALM_NAME = 167
> Could you please clarify what exactly you are asking for here? Support
> for GSS-API in general? Just defining those attribute type values in
> radius.h? Printing these in some debug messages? Or something else?
>

Hi Jouni,

Sorry I wasn't clear enough in my previous email. All I'd like is having 
those definitions added to radius.h file.
libeap is used by the Moonshot software (an implementation of the GSS 
EAP mechanism - RFC 7055), but those definitions are missing.

If you prefer that, I can create a patch (as others do) with the desired 
modification.

Thanks,
Alejandro


From yvsg.phanis at gmail.com  Sun Mar 11 10:18:21 2018
From: yvsg.phanis at gmail.com (Phani Siriki)
Date: Sun, 11 Mar 2018 12:18:21 -0500
Subject: Query on WMM AC parameters configuration using netlink
In-Reply-To: <20180311110049.GC14803@w1.fi>
References: <CADsGw2aKLJG98UGtsfFPQy49oW7fLiCyr40o_B_u=38AY-EPCQ@mail.gmail.com>
 <20180311110049.GC14803@w1.fi>
Message-ID: <CADsGw2a7Ub+BjJ5C8Xj42dgC+2HAUkXUhhVqRox1TbEfM5Mf6g@mail.gmail.com>

Hi Jouni

Thank you for your reply. I will check on this.

Best Regards
Phani

On Sun, Mar 11, 2018 at 6:00 AM, Jouni Malinen <j at w1.fi> wrote:
> On Thu, Mar 01, 2018 at 07:06:11PM -0600, Phani Siriki wrote:
>> Now, I want to change the wmm_ac parameters as well, but couldn't get
>> the exact netlink parameter to set.
>>
>> Could someone point me the nl80211 parameter used to set these
>> parameters in AP, so that AP can advertise these values to stations in
>> their IE?
>
> There is no nl80211 parameter for this. The WMM element that advertises
> values for station is part of the Beacon/Probe Response frame template
> that gets set when starting or updating the AP/BSS information. This may
> depend on the Wi-Fi driver that is used, but for example with
> mac80211_hwsim, you cannot change this independently without updating
> the full Beacon template (i.e., you have to update this through hostapd
> to avoid conflicts with other Beacon frame information changes).
>
> --
> Jouni Malinen                                            PGP id EFC895FA


From msiedzik at extremenetworks.com  Mon Mar 12 06:21:48 2018
From: msiedzik at extremenetworks.com (Michael Siedzik)
Date: Mon, 12 Mar 2018 13:21:48 +0000
Subject: [PATCH 03/15] mka: Incorrect conf_offset sent in MKPDU when in
 policy mode "SHOULD_SECURE"
In-Reply-To: <20180311143636.GA30889@w1.fi>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-4-msiedzik@extremenetworks.com>
 <20180311143636.GA30889@w1.fi>
Message-ID: <SN2PR04MB22534C7FEFE502184C2CB862C0D30@SN2PR04MB2253.namprd04.prod.outlook.com>

Hi Jouni,

You are correct.  In the case where policy is set to SHOULD_ENCRYPT but MACsec capability is only MACSEC_CAP_INTEGRITY (i.e., integrity without confidentiality), my patch would have attempted to encrypt with offset 0.  The patch should have retained the macsec_capable comparison.  Something like this:

                if ((kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF) &&
                    (policy == SHOULD_ENCRYPT)) {
                        kay->macsec_encrypt = TRUE;
                        kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
                } else {  /* SHOULD_SECURE */
                        kay->macsec_encrypt = FALSE;
                        kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
                }

Thanks,
- Mike


-----Original Message-----
From: Jouni Malinen [mailto:j at w1.fi]
Sent: Sunday, March 11, 2018 10:37 AM
To: Michael Siedzik <msiedzik at extremenetworks.com>
Cc: hostap at lists.infradead.org
Subject: Re: [PATCH 03/15] mka: Incorrect conf_offset sent in MKPDU when in policy mode "SHOULD_SECURE"

On Fri, Mar 02, 2018 at 03:10:51PM -0500, msiedzik at extremenetworks.com wrote:

> diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c @@
> -3166,14 +3167,16 @@ 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;
> +               if (policy == SHOULD_SECURE) {
> +                       kay->macsec_encrypt = FALSE;
> +                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
> +               } else {  /* SHOULD_ENCRYPT */
> +                       kay->macsec_encrypt = TRUE;
> +                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
> +               }
>                 kay->macsec_validate = Strict;
>                 kay->macsec_replay_protect = FALSE;
>                 kay->macsec_replay_window = 0;
> -               if (kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF)
> -                       kay->macsec_confidentiality = CONFIDENTIALITY_OFFSET_0;
> -               else
> -                       kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
>         }

Is this change dropping the kay->macsec_capable check on purpose for SHOULD_ENCRYPT case? The new SHOULD_SECURE case looks fine, but should the SHOULD_ENCRYPT case still use this kay->macsec_capable >= MACSEC_CAP_INTEG_AND_CONF before setting CONFIDENTIALITY_OFFSET_0?

--
Jouni Malinen                                            PGP id EFC895FA


________________________________

DISCLAIMER:
This e-mail and any attachments to it may contain confidential and proprietary material and is solely for the use of the intended recipient. Any review, use, disclosure, distribution or copying of this transmittal is prohibited except by or on behalf of the intended recipient. If you have received this transmittal in error, please notify the sender and destroy this e-mail and any attachments and all copies, whether electronic or printed.



From kkrishnamoorthy at quantenna.com  Mon Mar 12 16:15:15 2018
From: kkrishnamoorthy at quantenna.com (Karthik Krishnamoorthy)
Date: Mon, 12 Mar 2018 23:15:15 +0000
Subject: WPA3 (SAE, OWE) support in hostapd
Message-ID: <BN6PR05MB3602C3E335C05F8AE89DB858BBD30@BN6PR05MB3602.namprd05.prod.outlook.com>

Hi,

I would like to know when will WPA3 support be available in hostapd.

I see that SAE support is there in 2.6 as per release notes , did not check into the code.

Development branch has OWE support being added, not sure if it is fully complete.

The other information I am looking for is if/when DPP support will be added to hostapd.

Any rough timeline would be helpful.

Thanks and Regards,
Karthik.


This email, including its contents and any attachment(s), may contain confidential information of Quantenna Communications, Inc. and is solely for the intended recipient(s). If you may have received this in error, please contact the sender and permanently delete this email, its contents and any attachment(s).


From j at w1.fi  Mon Mar 12 16:47:29 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:47:29 +0200
Subject: WPA3 (SAE, OWE) support in hostapd
In-Reply-To: <BN6PR05MB3602C3E335C05F8AE89DB858BBD30@BN6PR05MB3602.namprd05.prod.outlook.com>
References: <BN6PR05MB3602C3E335C05F8AE89DB858BBD30@BN6PR05MB3602.namprd05.prod.outlook.com>
Message-ID: <20180312234729.GA28946@w1.fi>

On Mon, Mar 12, 2018 at 11:15:15PM +0000, Karthik Krishnamoorthy wrote:
> I would like to know when will WPA3 support be available in hostapd.
> 
> I see that SAE support is there in 2.6 as per release notes , did not check into the code.
> 
> Development branch has OWE support being added, not sure if it is fully complete.
> 
> The other information I am looking for is if/when DPP support will be added to hostapd.

The master branch of hostap.git includes support for WPA3 and DPP.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:49:08 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:49:08 +0200
Subject: [PATCH] wpa_supplicant: fix 2 memory leaks in
 ieee802_1x_create_preshared_mka()
In-Reply-To: <3db3d40417d4190ee071fb858e4d77834f3f709e.1520524691.git.davide.caratti@gmail.com>
References: <3db3d40417d4190ee071fb858e4d77834f3f709e.1520524691.git.davide.caratti@gmail.com>
Message-ID: <20180312234908.GB28946@w1.fi>

On Thu, Mar 08, 2018 at 05:15:02PM +0100, Davide Caratti wrote:
> in case MKA is initialized successfully, local copies of CAK and CKN are
> allocated, but never freed: ensure that such memory is released also when
> ieee802_1x_kay_create_mka() returns a valid pointer.

Thanks, applied.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:50:18 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:50:18 +0200
Subject: [PATCH 01/15] mka: When matching CKNs ensure that lengths are
 identical
In-Reply-To: <20180302201103.16264-2-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-2-msiedzik@extremenetworks.com>
Message-ID: <20180312235018.GC28946@w1.fi>

On Fri, Mar 02, 2018 at 03:10:49PM -0500, msiedzik at extremenetworks.com wrote:
> KaY looks up participants using CAK Name (CKN).  Per IEEE802.1X-2010
> Clause 9.3.1 CAK identification, the CKN is an integral number of octets,
> between 1 and 32 (inclusive).  This fix will ensure that the KaY does not
> inadvertently match CKNs such as 'myCakNamedFoo' and 'myCakNamedFooBar'.

Thanks, applied.


PS.

This series on the mailing list was whitespace damaged (tabs converted
to spaces). I used an earlier version I received to my personal address
instead to avoid having to clean up that mess manually.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:50:37 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:50:37 +0200
Subject: [PATCH 02/15] mka: Ignore MACsec SAK Use Old Key parameter if we
 don't remember our old key
In-Reply-To: <20180302201103.16264-3-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-3-msiedzik@extremenetworks.com>
Message-ID: <20180312235037.GD28946@w1.fi>

On Fri, Mar 02, 2018 at 03:10:50PM -0500, msiedzik at extremenetworks.com wrote:
> Upon receipt of the "MACsec MKPDU SAK Use parameter set" the KaY verifies
> that both the latest key and the old key are valid.  If the local system
> reboots or is reinitalizied, the KaY won't have a copy of it's old key.
> Therefore if the KaY does not have a copy of it's old key it should not
> reject MKPDUs that contain old key data in the MACsec SAK Use parameter.

Thanks, applied.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:50:55 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:50:55 +0200
Subject: [PATCH 04/15] mka: Loss of live peers should result in connect
 PENDING not AUTHENTICATED
In-Reply-To: <20180302201103.16264-5-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-5-msiedzik@extremenetworks.com>
Message-ID: <20180312235055.GE28946@w1.fi>

On Fri, Mar 02, 2018 at 03:10:52PM -0500, msiedzik at extremenetworks.com wrote:
> When the number of live peers becomes 0 the KaY is setting
> 'kay->authenticated' true and telling the CP to connect AUTHENTICATED.
> Per IEEE802.1X-2010 Clause 12.2, MKA.authenticated means "the Key Sever
> has proved mutual authentication but has determiend that Controlled Port
> communication should proceed without the use of MACsec", which means
> port traffic will be passed in the clear.
> When the number of live peers becomes 0 the KaY must instead set
> 'kay->authenticated' false and tell the CP to connect PENDING.  Per
> Clause 12.3 connect PENDING will "prevent connectivity by clearing the
> controlledPortEnabled parameter."

Thanks, applied.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:51:07 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:51:07 +0200
Subject: [PATCH 07/15] mka: Detect duplicate MAC addresses during key
 server election
In-Reply-To: <20180302201103.16264-8-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-8-msiedzik@extremenetworks.com>
Message-ID: <20180312235107.GF28946@w1.fi>

On Fri, Mar 02, 2018 at 03:10:55PM -0500, msiedzik at extremenetworks.com wrote:
> In the unlikely event the local KaY and the elected peer have the same
> actor priority as well as the same MAC address, log a warning message
> and do not elect a key server.  Resolution is for network administrator
> to reconfigure MAC address.

Thanks, applied.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Mon Mar 12 16:51:24 2018
From: j at w1.fi (Jouni Malinen)
Date: Tue, 13 Mar 2018 01:51:24 +0200
Subject: [PATCH 10/15] mka: Do not print contents of SAK to debug log
In-Reply-To: <20180302201103.16264-11-msiedzik@extremenetworks.com>
References: <20180302201103.16264-1-msiedzik@extremenetworks.com>
 <20180302201103.16264-11-msiedzik@extremenetworks.com>
Message-ID: <20180312235124.GG28946@w1.fi>

On Fri, Mar 02, 2018 at 03:10:58PM -0500, msiedzik at extremenetworks.com wrote:
> Log newly generated SAKs as well as unwrapped SAKs with wpa_hexdump_key()
> rather than wpa_hexdump(). By default, the wpa_hexdump_key() function
> will not display sensitive key data.

Thanks, applied.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From desiren77 at gmail.com  Wed Mar 14 01:05:55 2018
From: desiren77 at gmail.com (John Doe)
Date: Wed, 14 Mar 2018 10:05:55 +0200
Subject: 802.11w PMF
Message-ID: <CA+Ws8FtRCfkjPE7P+1faFQf+hwN+yMLgg_LnuPRL0Mu3-k0wMg@mail.gmail.com>

Hello guys,


Can I enquire about 802.11w specific behavior?


I have configured hostapd with ieee80211w set to 2 (PMF required), and
seems like that those management frames that should be encrypted are
encrypted indeed (flag "protected" is set and seen in Wireshark),
however, when I use hostapd_cli and trigger
"disassociate"/"deauthenticate"  my phone/tablet MAC addresses, both
frames are unencrypted. Should it be considered as a proper behavior?
I'm using 2.6 version.



Thank you in advance.


From ilan.peer at intel.com  Thu Mar 15 02:14:52 2018
From: ilan.peer at intel.com (Peer, Ilan)
Date: Thu, 15 Mar 2018 09:14:52 +0000
Subject: 802.11w PMF
In-Reply-To: <CA+Ws8FtRCfkjPE7P+1faFQf+hwN+yMLgg_LnuPRL0Mu3-k0wMg@mail.gmail.com>
References: <CA+Ws8FtRCfkjPE7P+1faFQf+hwN+yMLgg_LnuPRL0Mu3-k0wMg@mail.gmail.com>
Message-ID: <CB3B3D4774441E42AA3EA0E1BA8230A062285AB4@HASMSX110.ger.corp.intel.com>

Hi,

> -----Original Message-----
> From: Hostap [mailto:hostap-bounces at lists.infradead.org] On Behalf Of John
> Doe
> Sent: Wednesday, March 14, 2018 10:06
> To: hostap at lists.infradead.org
> Subject: 802.11w PMF
> 
> Hello guys,
> 
> 
> Can I enquire about 802.11w specific behavior?
> 
> 
> I have configured hostapd with ieee80211w set to 2 (PMF required), and
> seems like that those management frames that should be encrypted are
> encrypted indeed (flag "protected" is set and seen in Wireshark), however,
> when I use hostapd_cli and trigger "disassociate"/"deauthenticate"  my
> phone/tablet MAC addresses, both frames are unencrypted. Should it be
> considered as a proper behavior?
> I'm using 2.6 version.
> 

This would depend on disassociate/deauthentication address. If a broadcast/multicast address was used, then the frame is not encrypted, but should include the MMIE that should contain a MIC to authenticate the frame.

Regards,

Ilan.




From chaitanya.mgit at gmail.com  Thu Mar 15 04:33:18 2018
From: chaitanya.mgit at gmail.com (Krishna Chaitanya)
Date: Thu, 15 Mar 2018 17:03:18 +0530
Subject: nl80211 controlling operational state of the interface
Message-ID: <CABPxzYL63WsQ8_ZJ7UZrt+-92w7aOE-3JR9GUo2WF=KhB3uRDA@mail.gmail.com>

Hi,

As per the kernel documentation @
https://elixir.bootlin.com/linux/latest/source/Documentation/networking/operstates.txt

"userspace applications should follow the procedure for controlling the
operational state of the interface:

-subscribe to RTMGRP_LINK
-set IFLA_LINKMODE to 1 via RTM_SETLINK
-query RTM_GETLINK once to get initial state
-if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until
 netlink multicast signals this state"

The case in question is, lets say if the driver is setting the
interface state to
DORMANT waiting on some event from chip, as per the above the
wpa_supplicant/hostapd
should wait for the kernel to send an UP event. But its not waiting,
instead it sends commands to the driver even when it is in dormant
state.

Is this expected?

netlink: Operstate: ifindex=13 linkmode=-1 (no change), operstate=5
(IF_OPER_DORMANT)
RTM_NEWLINK: ifi_index=13 ifname=wlp8s0f0 operstate=2 linkmode=1
ifi_family=0 ifi_flags=0x21003 ([UP][DORMANT])
wlp8s0f0: State: DISCONNECTED -> SCANNING

-- 
Thanks,
Regards,
Chaitanya T K.


From greearb at candelatech.com  Fri Mar 16 14:31:55 2018
From: greearb at candelatech.com (greearb at candelatech.com)
Date: Fri, 16 Mar 2018 14:31:55 -0700
Subject: [PATCH v2] nl80211: Add MLME auth work-around for -EEXIST errno
Message-ID: <1521235915-27623-1-git-send-email-greearb@candelatech.com>

From: Ben Greear <greearb at candelatech.com>

The 4.9 kernel, at least, can return EEXIST when trying to auth
a station that already exists.

Signed-off-by: Ben Greear <greearb at candelatech.com>
---

NOTE:  I cannot manage to compile top-of-tree hostapd, due to
this:

[greearb at ben-dt3 hostapd]$ make
../src/drivers/driver_nl80211.c:17:31: fatal error: netlink/genl/genl.h: No such file or directory
compilation terminated.
Makefile:1247: recipe for target '../src/drivers/driver_nl80211.o' failed
make: *** [../src/drivers/driver_nl80211.o] Error 1


So, this patch is not even properly compile tested unfortunately.


We have seen this bug in multiple places, but it is difficult to reproduce.
Here is a link to someone else that appears to have hit this issue.

https://github.com/greearb/ath10k-ct/issues/18

 src/drivers/driver_nl80211.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 329be02..fd53e4f 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -3345,10 +3345,10 @@ retry:
 	msg = NULL;
 	if (ret) {
 		wpa_dbg(drv->ctx, MSG_DEBUG,
-			"nl80211: MLME command failed (auth): ret=%d (%s)",
-			ret, strerror(-ret));
+			"nl80211: MLME command failed (auth): count=%d ret=%d (%s)",
+			count, ret, strerror(-ret));
 		count++;
-		if (ret == -EALREADY && count == 1 && params->bssid &&
+		if (((ret == -EALREADY) || (ret == -EEXIST)) && count == 1 && params->bssid &&
 		    !params->local_state_change) {
 			/*
 			 * mac80211 does not currently accept new
-- 
2.4.11



From dcbw at redhat.com  Tue Mar 20 14:31:21 2018
From: dcbw at redhat.com (Dan Williams)
Date: Tue, 20 Mar 2018 16:31:21 -0500
Subject: [PATCH v2] wpa_supplicant: fix auth failure when the MAC is
 updated externally
In-Reply-To: <20180215105001.19229-1-bgalvani@redhat.com>
References: <20180215105001.19229-1-bgalvani@redhat.com>
Message-ID: <1c6b11010ad82cebe504d2044c86e12034d4653b.camel@redhat.com>

On Thu, 2018-02-15 at 11:50 +0100, Beniamino Galvani wrote:
> 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):

Patch looks reasonable to me.  Jouni, any thoughts on this one?

Thanks!
Dan

> 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 <bgalvani at redhat.com>
> ---
> 
> Changes since v1 at http://lists.infradead.org/pipermail/hostap/2017-
> September/037936.html
>  - reworded commit message
> 
>  src/drivers/driver.h         |  9 +++++++++
>  src/drivers/driver_common.c  |  1 +
>  src/drivers/driver_nl80211.c | 13 +++++++++----
>  wpa_supplicant/events.c      |  3 +++
>  4 files changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/src/drivers/driver.h b/src/drivers/driver.h
> index d9c6fd9f5..c250c11f6 100644
> --- a/src/drivers/driver.h
> +++ b/src/drivers/driver.h
> @@ -4307,6 +4307,15 @@ enum wpa_event_type {
>  	 */
>  	EVENT_SIGNAL_CHANGE,
>  
> +	/**
> +	 * 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,
> +
>  	/**
>  	 * EVENT_INTERFACE_ENABLED - Notify that interface was
> enabled
>  	 *
> diff --git a/src/drivers/driver_common.c
> b/src/drivers/driver_common.c
> index 33a6db346..c91d66ab5 100644
> --- a/src/drivers/driver_common.c
> +++ b/src/drivers/driver_common.c
> @@ -53,6 +53,7 @@ const char * event_to_string(enum wpa_event_type
> event)
>  	E2S(NEW_STA);
>  	E2S(EAPOL_RX);
>  	E2S(SIGNAL_CHANGE);
> +	E2S(INTERFACE_MAC_CHANGED);
>  	E2S(INTERFACE_ENABLED);
>  	E2S(INTERFACE_DISABLED);
>  	E2S(CHANNEL_LIST_CHANGED);
> diff --git a/src/drivers/driver_nl80211.c
> b/src/drivers/driver_nl80211.c
> index dfa11834c..13f5959b6 100644
> --- a/src/drivers/driver_nl80211.c
> +++ b/src/drivers/driver_nl80211.c
> @@ -951,7 +951,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, Boolean notify)
>  {
>  	struct i802_bss *bss;
>  	u8 addr[ETH_ALEN];
> @@ -970,6 +970,11 @@ 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_CHA
> NGED,
> +					     NULL);
> +		}
>  	}
>  }
>  
> @@ -1041,11 +1046,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,
> TRUE);
>  			return;
>  		}
>  		wpa_printf(MSG_DEBUG, "nl80211: Interface down
> (%s/%s)",
> @@ -1091,7 +1096,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,
> FALSE);
>  
>  			wpa_printf(MSG_DEBUG, "nl80211: Interface
> up");
>  			drv->if_disabled = 0;
> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> index 4f3604358..e8cbac548 100644
> --- a/wpa_supplicant/events.c
> +++ b/wpa_supplicant/events.c
> @@ -4366,6 +4366,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) {


From hailinx.gu at intel.com  Wed Mar 21 01:41:00 2018
From: hailinx.gu at intel.com (Gu, HailinX)
Date: Wed, 21 Mar 2018 08:41:00 +0000
Subject: result website can't be used for a long time
Message-ID: <3C4C9E317E49F840AE61D81CCBCF62AD97A334@SHSMSX101.ccr.corp.intel.com>

hi, 

It seems this website was broken for several months.
http://buildbot.w1.fi/hwsim/tests.php

Is anybody fix it?

I want to use it to check the test result of hwsim.
I shall appreciate a reply at your earliest convenience.

Thanks,
[Gu, HailinX] 



From j at w1.fi  Wed Mar 21 02:44:51 2018
From: j at w1.fi (Jouni Malinen)
Date: Wed, 21 Mar 2018 11:44:51 +0200
Subject: result website can't be used for a long time
In-Reply-To: <3C4C9E317E49F840AE61D81CCBCF62AD97A334@SHSMSX101.ccr.corp.intel.com>
References: <3C4C9E317E49F840AE61D81CCBCF62AD97A334@SHSMSX101.ccr.corp.intel.com>
Message-ID: <20180321094451.GA4629@w1.fi>

On Wed, Mar 21, 2018 at 08:41:00AM +0000, Gu, HailinX wrote:
> It seems this website was broken for several months.
> http://buildbot.w1.fi/hwsim/tests.php
> 
> Is anybody fix it?

Maybe eventually, but that is of pretty low priority, so it may take
a while. The test setup did not survive OS update and I'm running the
tests on my desktop before pushing anything out, so testing coverage
itself has not really dropped, but there is no publicly available
storage of the test runs.

In practice, I'd rather replace that virtual buildbot.w1.fi server with
something that can run VMs with kvm (i.e., running on real hardware),
but I don't have such a server available for this type of use at the
moment.

-- 
Jouni Malinen                                            PGP id EFC895FA


From andihartmann at 01019freenet.de  Thu Mar 22 03:50:57 2018
From: andihartmann at 01019freenet.de (Andreas Hartmann)
Date: Thu, 22 Mar 2018 11:50:57 +0100
Subject: hostapd / eaptls / IOS 10.2
Message-ID: <c62c4315-e95f-ad98-f10f-8934420ee275@01019freenet.de>

Hello all!

Since years I'm using hostapd with EAPTLS for WLAN and never had any
problem with Linux, Android or Windowsclients.

I'm now trying to configure an iPhone (iOS 10.2) to use EAPTLS, too. I
installed the CA and the client crt. That seems to be all fine. But
connection isn't possible. Hostapd prints out:

IEEE 802.11: No WPA/RSN IE in association request

Does iOS 10.2 need some special configuration in hostapd to get it working?


Thanks,
Andreas


From andihartmann at 01019freenet.de  Thu Mar 22 07:29:26 2018
From: andihartmann at 01019freenet.de (Andreas Hartmann)
Date: Thu, 22 Mar 2018 15:29:26 +0100
Subject: hostapd / eaptls / IOS 10.2
In-Reply-To: <c62c4315-e95f-ad98-f10f-8934420ee275@01019freenet.de>
References: <c62c4315-e95f-ad98-f10f-8934420ee275@01019freenet.de>
Message-ID: <fe306f38-1149-d86b-61e1-2b68942cf740@01019freenet.de>

On 03/22/2018 at 11:50 AM Andreas Hartmann wrote:
> Hello all!
> 
> Since years I'm using hostapd with EAPTLS for WLAN and never had any
> problem with Linux, Android or Windowsclients.
> 
> I'm now trying to configure an iPhone (iOS 10.2) to use EAPTLS, too. I
> installed the CA and the client crt. That seems to be all fine. But
> connection isn't possible. Hostapd prints out:
> 
> IEEE 802.11: No WPA/RSN IE in association request
> 
> Does iOS 10.2 need some special configuration in hostapd to get it working?

Problem seems to be, that iOS 10.2 can't handle WPA2 !?
If I'm setting wpa=1 (normally I'm using wpa=2), it can connect. But
with wpa=3 (enabling WPA and WPA2) it doesn't work, too - I would have
expected, that this would work.

> 
> Thanks,
> Andreas


From andihartmann at 01019freenet.de  Thu Mar 22 13:25:49 2018
From: andihartmann at 01019freenet.de (Andreas Hartmann)
Date: Thu, 22 Mar 2018 21:25:49 +0100
Subject: hostapd / eaptls / IOS 10.2
In-Reply-To: <fe306f38-1149-d86b-61e1-2b68942cf740@01019freenet.de>
References: <c62c4315-e95f-ad98-f10f-8934420ee275@01019freenet.de>
 <fe306f38-1149-d86b-61e1-2b68942cf740@01019freenet.de>
Message-ID: <5f5819b9-3eb6-4bd7-64fa-b27de1349629@01019freenet.de>

On 03/22/2018 at 03:29 PM Andreas Hartmann wrote:
> On 03/22/2018 at 11:50 AM Andreas Hartmann wrote:
>> Hello all!
>>
>> Since years I'm using hostapd with EAPTLS for WLAN and never had any
>> problem with Linux, Android or Windowsclients.
>>
>> I'm now trying to configure an iPhone (iOS 10.2) to use EAPTLS, too. I
>> installed the CA and the client crt. That seems to be all fine. But
>> connection isn't possible. Hostapd prints out:
>>
>> IEEE 802.11: No WPA/RSN IE in association request
>>
>> Does iOS 10.2 need some special configuration in hostapd to get it working?
> 
> Problem seems to be, that iOS 10.2 can't handle WPA2 !?
> If I'm setting wpa=1 (normally I'm using wpa=2), it can connect. But
> with wpa=3 (enabling WPA and WPA2) it doesn't work, too - I would have
> expected, that this would work.

=> iOS 10.2 can't handle
- a list of wpa_key_mgmt methods
- WPA-EAP-SHA256

It only handles WPA_EAP (with eaptls).

>>
>> Thanks,
>> Andreas
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
> 



From eric at smythian.com  Fri Mar 23 21:59:17 2018
From: eric at smythian.com (Eric Smyth)
Date: Fri, 23 Mar 2018 21:59:17 -0700
Subject: Issue with hostapd+RPi3+Alpine
Message-ID: <CAHeyCEvUhYCnLmZF0r3c4xviCDJM7Bf2qvB5CuO66G3tmrEqrw@mail.gmail.com>

Hello all,
I've run into a roadblock trying to debug a hostapd PoC and I could
use some help.

I'm prototyping with hostapd running on Alpine Linux on a Rapsberry Pi
3 and I can't get a working configuration that utilizes RADIUS. If I
configure hostapd with `wpa_passphrase` or `wpa_psk_file`, all is
good. However, when I configure `macaddr_acl=2` as needed for
`wpa_psk_radius` or `wpa_key_mgmt=WPA-EAP`, then the conditional in
src/ap/drv_callbacks.c:190 evaluates to true and I receive a
"STA...not allowed to connect" message and the device is
disassociated; hostapd never checks with the RADIUS server. As far as
I can tell, the issue is due to the driver capabilities for
max_acl_mac_addrs being set to 0
(src/drivers/driver_nl80211_capa.c:635) since the ACL status is
pending (src/ap/ieee802_11_auth.c:215). However, I'm at a loss as to
next steps for debugging the issue. I believe the issue may be due to
my use of Alpine Linux as the same configurations work with Raspbian
(I plan to seek assistance from the Alpine community as well). In
addition to the onboard broadcom-based wifi adapter, I've reproduced
the issue with a Realtek-based Edimax EW-7811Un USB wifi adapter.

Any assistance would be most appreciated.

-- 
v/r
Eric

Minimal WPA-EAP hostapd config
auth_algs=2
wpa=2
wpa_key_mgmt=WPA-EAP
ieee8021x=1
eapol_version=2
channel=1
driver=nl80211
hw_mode=g
interface=wlan0
rsn_pairwise=CCMP
ssid=test
macaddr_acl=2
own_ip_addr=10.1.1.10
auth_server_addr=127.0.0.1
auth_server_port=1812
auth_server_shared_secret=testing123

Minimal wpa_psk_radius config
auth_algs=2
wpa=2
wpa_key_mgmt=WPA-PSK
channel=1
driver=nl80211
interface=wlan0
rsn_pairwise=CCMP
ssid=test
macaddr_acl=2
wpa_psk_radius=2
own_ip_addr= 10.1.1.10
auth_server_addr=127.0.0.1
auth_server_port=1812
auth_server_shared_secret= testing123


From lebed.dmitry at gmail.com  Sat Mar 24 00:54:25 2018
From: lebed.dmitry at gmail.com (Dmitry Lebed)
Date: Sat, 24 Mar 2018 10:54:25 +0300
Subject: [PATCH 0/2] Add generic nl80211 DFS offload support
Message-ID: <20180324075427.3323-1-lebed.dmitry@gmail.com>

This patchset adds support for generic DFS offload nl80211 feature
that was recently added to mac80211-next tree.
It uses already available DFS offload infrastracture of hostapd
and just sets necessary flags and forwards CAC_STARTED event.

Dmitry Lebed (2):
  Sync with mac80211-next.git include/uapi/linux/nl80211.h
  nl80211: add nl80211 DFS offload support

 src/drivers/driver_nl80211_capa.c  |  4 ++++
 src/drivers/driver_nl80211_event.c |  3 +++
 src/drivers/nl80211_copy.h         | 10 ++++++++++
 3 files changed, 17 insertions(+)

-- 
2.16.2



From lebed.dmitry at gmail.com  Sat Mar 24 00:54:27 2018
From: lebed.dmitry at gmail.com (Dmitry Lebed)
Date: Sat, 24 Mar 2018 10:54:27 +0300
Subject: [PATCH 2/2] nl80211: add nl80211 DFS offload support
In-Reply-To: <20180324075427.3323-1-lebed.dmitry@gmail.com>
References: <20180324075427.3323-1-lebed.dmitry@gmail.com>
Message-ID: <20180324075427.3323-3-lebed.dmitry@gmail.com>

Add generic DFS offload support.
DFS_OFFLOAD ext_feature and CAC_STARTED event handling implemented.

Signed-off-by: Dmitry Lebed <lebed.dmitry at gmail.com>
---
 src/drivers/driver_nl80211_capa.c  | 4 ++++
 src/drivers/driver_nl80211_event.c | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
index e5bc7693b..ba053b44c 100644
--- a/src/drivers/driver_nl80211_capa.c
+++ b/src/drivers/driver_nl80211_capa.c
@@ -411,6 +411,10 @@ static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
 	if (ext_feature_isset(ext_features, len,
 			      NL80211_EXT_FEATURE_MFP_OPTIONAL))
 		capa->flags |= WPA_DRIVER_FLAGS_MFP_OPTIONAL;
+
+	if (ext_feature_isset(ext_features, len,
+			      NL80211_EXT_FEATURE_DFS_OFFLOAD))
+		capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
 }
 
 
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index fd9eac970..062b0b318 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1592,6 +1592,9 @@ static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
 		wpa_supplicant_event(drv->ctx, EVENT_DFS_PRE_CAC_EXPIRED,
 				     &data);
 		break;
+	case NL80211_RADAR_CAC_STARTED:
+		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
+		break;
 	default:
 		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
 			   "received", event_type);
-- 
2.16.2



From lebed.dmitry at gmail.com  Sat Mar 24 00:54:26 2018
From: lebed.dmitry at gmail.com (Dmitry Lebed)
Date: Sat, 24 Mar 2018 10:54:26 +0300
Subject: [PATCH 1/2] Sync with mac80211-next.git include/uapi/linux/nl80211.h
In-Reply-To: <20180324075427.3323-1-lebed.dmitry@gmail.com>
References: <20180324075427.3323-1-lebed.dmitry@gmail.com>
Message-ID: <20180324075427.3323-2-lebed.dmitry@gmail.com>

This brings in nl80211 definitions as of 2018-03-22.

Signed-off-by: Dmitry Lebed <lebed.dmitry at gmail.com>
---
 src/drivers/nl80211_copy.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h
index c13c84304..60fefc5a2 100644
--- a/src/drivers/nl80211_copy.h
+++ b/src/drivers/nl80211_copy.h
@@ -4999,6 +4999,12 @@ enum nl80211_feature_flags {
  * @NL80211_EXT_FEATURE_LOW_SPAN_SCAN: Driver supports low span scan.
  * @NL80211_EXT_FEATURE_LOW_POWER_SCAN: Driver supports low power scan.
  * @NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN: Driver supports high accuracy scan.
+ * @NL80211_EXT_FEATURE_DFS_OFFLOAD: HW/driver will offload DFS actions.
+ *	Device or driver will do all DFS-related actions by itself,
+ *	informing user-space about CAC progress, radar detection event,
+ *	channel change triggered by radar detection event.
+ *	No need to start CAC from user-space, no need to react to
+ *	"radar detected" event.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5029,6 +5035,7 @@ enum nl80211_ext_feature_index {
 	NL80211_EXT_FEATURE_LOW_SPAN_SCAN,
 	NL80211_EXT_FEATURE_LOW_POWER_SCAN,
 	NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
+	NL80211_EXT_FEATURE_DFS_OFFLOAD,
 
 	/* add new features before the definition below */
 	NUM_NL80211_EXT_FEATURES,
@@ -5204,6 +5211,8 @@ enum nl80211_smps_mode {
  *	non-operating channel is expired and no longer valid. New CAC must
  *	be done on this channel before starting the operation. This is not
  *	applicable for ETSI dfs domain where pre-CAC is valid for ever.
+ * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
+ *	should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
  */
 enum nl80211_radar_event {
 	NL80211_RADAR_DETECTED,
@@ -5211,6 +5220,7 @@ enum nl80211_radar_event {
 	NL80211_RADAR_CAC_ABORTED,
 	NL80211_RADAR_NOP_FINISHED,
 	NL80211_RADAR_PRE_CAC_EXPIRED,
+	NL80211_RADAR_CAC_STARTED,
 };
 
 /**
-- 
2.16.2



From j at w1.fi  Sat Mar 24 02:16:12 2018
From: j at w1.fi (Jouni Malinen)
Date: Sat, 24 Mar 2018 11:16:12 +0200
Subject: Issue with hostapd+RPi3+Alpine
In-Reply-To: <CAHeyCEvUhYCnLmZF0r3c4xviCDJM7Bf2qvB5CuO66G3tmrEqrw@mail.gmail.com>
References: <CAHeyCEvUhYCnLmZF0r3c4xviCDJM7Bf2qvB5CuO66G3tmrEqrw@mail.gmail.com>
Message-ID: <20180324091612.GA5307@w1.fi>

On Fri, Mar 23, 2018 at 09:59:17PM -0700, Eric Smyth wrote:
> I'm prototyping with hostapd running on Alpine Linux on a Rapsberry Pi
> 3 and I can't get a working configuration that utilizes RADIUS. If I
> configure hostapd with `wpa_passphrase` or `wpa_psk_file`, all is
> good. However, when I configure `macaddr_acl=2` as needed for
> `wpa_psk_radius` or `wpa_key_mgmt=WPA-EAP`, then the conditional in
> src/ap/drv_callbacks.c:190 evaluates to true and I receive a
> "STA...not allowed to connect" message and the device is
> disassociated; hostapd never checks with the RADIUS server.

wpa_key_mgmt=WPA-EAP does not require macaddr_acl=2. macaddr_acl=2 is
supported properly only with drivers that use hostapd for processing
the management frames. It does not sound like the driver you are testing
with would be in that category.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Sat Mar 24 02:20:27 2018
From: j at w1.fi (Jouni Malinen)
Date: Sat, 24 Mar 2018 11:20:27 +0200
Subject: Request: add missing standard RADIUS attribute types
In-Reply-To: <43ff828f-3bd4-8507-e68b-d36dcc7b2ee1@um.es>
References: <b1b21dfc-a399-e2c0-7818-c96e6011f439@um.es>
 <20180311110640.GD14803@w1.fi>
 <43ff828f-3bd4-8507-e68b-d36dcc7b2ee1@um.es>
Message-ID: <20180324092027.GB5307@w1.fi>

On Sun, Mar 11, 2018 at 04:24:58PM +0100, Alejandro P?rez M?ndez wrote:
> >>I'd like to request the addition of four RADIUS attribute types, that are
> >>missing in the radius/radius.h file. They are defined in section 7.4 of RFC
> >>7055. They would be:
> >>
> >>RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 164
> >>RADIUS_ATTR_GSS_ACCEPTOR_HOST_NAME = 165
> >>RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_SPECIFICS = 166
> >>RADIUS_ATTR_GSS_ACCEPTOR_REALM_NAME = 167
> >Could you please clarify what exactly you are asking for here? Support
> >for GSS-API in general? Just defining those attribute type values in
> >radius.h? Printing these in some debug messages? Or something else?

> Sorry I wasn't clear enough in my previous email. All I'd like is having
> those definitions added to radius.h file.
> libeap is used by the Moonshot software (an implementation of the GSS EAP
> mechanism - RFC 7055), but those definitions are missing.
> 
> If you prefer that, I can create a patch (as others do) with the desired
> modification.

A contributed patch would be the best way of getting something like this
added. The commit message should describe the need, since simply adding
defined values without any obvious use within hostap.git does not make
it clear that there is reason for applying the change.

-- 
Jouni Malinen                                            PGP id EFC895FA


From chaitanya.mgit at gmail.com  Sun Mar 25 04:44:00 2018
From: chaitanya.mgit at gmail.com (Krishna Chaitanya)
Date: Sun, 25 Mar 2018 17:14:00 +0530
Subject: nl80211 controlling operational state of the interface
In-Reply-To: <CABPxzYL63WsQ8_ZJ7UZrt+-92w7aOE-3JR9GUo2WF=KhB3uRDA@mail.gmail.com>
References: <CABPxzYL63WsQ8_ZJ7UZrt+-92w7aOE-3JR9GUo2WF=KhB3uRDA@mail.gmail.com>
Message-ID: <CABPxzY+65MzsxFG=i5GBe-1UG+dBCXCtPp5mCjLkuVzaYQX4Mw@mail.gmail.com>

On Thu, Mar 15, 2018 at 5:03 PM, Krishna Chaitanya
<chaitanya.mgit at gmail.com> wrote:
>
> Hi,
>
> As per the kernel documentation @
> https://elixir.bootlin.com/linux/latest/source/Documentation/networking/operstates.txt
>
> "userspace applications should follow the procedure for controlling the
> operational state of the interface:
>
> -subscribe to RTMGRP_LINK
> -set IFLA_LINKMODE to 1 via RTM_SETLINK
> -query RTM_GETLINK once to get initial state
> -if initial flags are not (IFF_LOWER_UP && !IFF_DORMANT), wait until
>  netlink multicast signals this state"
>
> The case in question is, lets say if the driver is setting the
> interface state to
> DORMANT waiting on some event from chip, as per the above the
> wpa_supplicant/hostapd
> should wait for the kernel to send an UP event. But its not waiting,
> instead it sends commands to the driver even when it is in dormant
> state.
>
> Is this expected?
>
> netlink: Operstate: ifindex=13 linkmode=-1 (no change), operstate=5
> (IF_OPER_DORMANT)
> RTM_NEWLINK: ifi_index=13 ifname=wlp8s0f0 operstate=2 linkmode=1
> ifi_family=0 ifi_flags=0x21003 ([UP][DORMANT])
> wlp8s0f0: State: DISCONNECTED -> SCANNING
>
Any hints? Can Driver use dormant feature to block interface?


From iboukris at gmail.com  Sun Mar 25 18:51:14 2018
From: iboukris at gmail.com (Isaac Boukris)
Date: Mon, 26 Mar 2018 04:51:14 +0300
Subject: [PATCH] TLS: Load chain certificates from client_cert file
In-Reply-To: <1516498604-20963-1-git-send-email-iboukris@gmail.com>
References: <1516498604-20963-1-git-send-email-iboukris@gmail.com>
Message-ID: <CAC-fF8RQhFhtML--WEd35A-D4ZPMu7d+kV+j-5iRswn9gZ-o=w@mail.gmail.com>

Hi,

On Sun, Jan 21, 2018 at 4:36 AM, Isaac Boukris <iboukris at gmail.com> wrote:
> This helps the server to build the chain to trusted CA.
>
> Signed-off-by: Isaac Boukris <iboukris at gmail.com>
> ---
>  src/crypto/tls_openssl.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
> index ce73848..3d789bb 100644
> --- a/src/crypto/tls_openssl.c
> +++ b/src/crypto/tls_openssl.c
> @@ -2653,10 +2653,9 @@ static int tls_connection_client_cert(struct tls_connection *conn,
>                 return 0;
>         }
>
> -       if (SSL_use_certificate_file(conn->ssl, client_cert,
> -                                    SSL_FILETYPE_PEM) == 1) {
> +       if (SSL_use_certificate_chain_file(conn->ssl, client_cert) == 1) {
>                 ERR_clear_error();
> -               wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)"
> +               wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_chain_file"
>                            " --> OK");
>                 return 0;
>         }
> --


I'd like to reference the case where I found this useful against
FreeRadius server, see:
http://lists.freeradius.org/pipermail/freeradius-users/2018-January/090245.html

I left it unconditional as I assumed that without this change it
wouldn't make much sense having the chain included.

Review appreciated.

Thank you,
Isaac B.


From xbing6 at gmail.com  Mon Mar 26 02:02:42 2018
From: xbing6 at gmail.com (Xuebing Wang)
Date: Mon, 26 Mar 2018 17:02:42 +0800
Subject: [hostapd] [batman-adv] Is dot11RSNAConfigPMKLifetime the correct
 setting to configure IBSS reauth timer?
Message-ID: <79817dd4-1fb2-a491-fa9f-9056906cab00@gmail.com>

Hi community,

We have batman-adv mesh network of 136 nodes perfectly running for about 
6 months.

Our configure is:
- OpenWRT tag 15.05.1
- wpa_supplicant hostap_2_4
- 802.11 IBSS
- proto=WPA2
- key_mgmt=WPA-PSK
- pairwise=CCMP
- group=CCMP

The minor issue we have is that memory is fragmented after running 6 
months for a large network of 136 nodes. I am speculating that it is 
because of the periodical RNSA? reauthentication.

If I read 802.11 spec "11.5.10 RSNA authentication in an IBSS" 
correctly, there is reauth timer.? Is dot11RSNAConfigPMKLifetime in 
wpa_supplicant.conf the setting for the reauthentication timer?

The default value is 43200 (12 hours). What about I change this value to 
be 2 weeks or a year?

Thanks.
Xuebing Wang



From alex at um.es  Tue Mar 27 14:50:48 2018
From: alex at um.es (=?UTF-8?Q?Alejandro_P=c3=a9rez_M=c3=a9ndez?=)
Date: Tue, 27 Mar 2018 23:50:48 +0200
Subject: [PATCH] - Add definitions for RADIUS attributes standardised in RFC
 7055.
Message-ID: <e09aa34d-c816-9e34-8f4f-5677e9313fae@um.es>

 ??? Add definitions for RADIUS attributes standardised in RFC 7055.

 ??? hostap code is used by the Moonshot software (an implementation of the
 ??? GSS EAP mechanism - RFC 7055), and those definitions are required
 ??? but missing.

 ??? Signed-off-by: Alejandro Perez <alex.perez-mendez at jisc.ac.uk>

diff --git a/src/radius/radius.h b/src/radius/radius.h
index 96551c62e..a75922d44 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -102,6 +102,10 @@ enum { RADIUS_ATTR_USER_NAME = 1,
 ??????? RADIUS_ATTR_EXTENDED_LOCATION_POLICY_RULES = 130,
 ??????? RADIUS_ATTR_LOCATION_CAPABLE = 131,
 ??????? RADIUS_ATTR_REQUESTED_LOCATION_INFO = 132,
+?????? RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_NAME = 164,
+?????? RADIUS_ATTR_GSS_ACCEPTOR_HOST_NAME = 165,
+?????? RADIUS_ATTR_GSS_ACCEPTOR_SERVICE_SPECIFICS = 166,
+?????? RADIUS_ATTR_GSS_ACCEPTOR_REALM_NAME = 167,
 ??????? RADIUS_ATTR_MOBILITY_DOMAIN_ID = 177,
 ??????? RADIUS_ATTR_WLAN_HESSID = 181,
 ??????? RADIUS_ATTR_WLAN_REASON_CODE = 185,



From davide.caratti at gmail.com  Wed Mar 28 07:34:56 2018
From: davide.caratti at gmail.com (Davide Caratti)
Date: Wed, 28 Mar 2018 16:34:56 +0200
Subject: [PATCH RESEND] wpa_supplicant: don't reply to EAPOL if pkt_type is
 PACKET_OTHERHOST
Message-ID: <3aad4ba1bf34bfbe2105345b8ef0a0a10bfd4981.1522246953.git.davide.caratti@gmail.com>

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 <davide.caratti at gmail.com>
---
 src/l2_packet/l2_packet.h       |  1 +
 src/l2_packet/l2_packet_linux.c | 22 ++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.c |  5 +++++
 3 files changed, 28 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..c5d889dca 100644
--- a/src/l2_packet/l2_packet_linux.c
+++ b/src/l2_packet/l2_packet_linux.c
@@ -84,6 +84,25 @@ 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 - <<-EOF
+ * > 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 +490,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 fcb267764..7e6844a75 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3993,6 +3993,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_msg(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



From arabawy at google.com  Wed Mar 28 17:48:44 2018
From: arabawy at google.com (Ahmed ElArabawy)
Date: Wed, 28 Mar 2018 17:48:44 -0700
Subject: [PATCH 1/2] Propagate the EAP method error code
Message-ID: <CABo_UfPYjt7Yc=23fZfnCEC_o_VKnTkg6P8RDbTuj_Cgm=-h3Q@mail.gmail.com>

In current implementaion, upon an EAP method failure, followed
by an EAP failure, the EAP Status is propagated up in wpa_supplicant
with a general failure parameter string "failure". This parameter is
used for a notification on the dbus.

This patch reports the EAP method failure error code in a separate
callback.  We want this to have visibility into the error code and act
accordingly.

The solution in this patch is generic to all EAP methods, and can be
used by any method that need to pass its error code. However, this
patch only implements the reporting for EAP-SIM, EAP-AKA, and EAP-AKA'
methods.

Signed-off-by: Ahmed ElArabawy <arabawy at google.com>
---
 src/eap_peer/eap.c             | 14 ++++++++++++++
 src/eap_peer/eap.h             |  7 +++++++
 src/eap_peer/eap_aka.c         | 21 +++++++++++++++++++++
 src/eap_peer/eap_i.h           | 13 +++++++++++++
 src/eap_peer/eap_sim.c         | 20 ++++++++++++++++++++
 src/eapol_supp/eapol_supp_sm.c |  8 ++++++++
 src/eapol_supp/eapol_supp_sm.h |  7 +++++++
 wpa_supplicant/notify.c        |  5 +++++
 wpa_supplicant/notify.h        |  1 +
 wpa_supplicant/wpas_glue.c     |  7 +++++++
 10 files changed, 103 insertions(+)

diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 0043707..11d8129 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -94,6 +94,12 @@ static void eap_notify_status(struct eap_sm *sm,
const char *status,
        sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
 }

+static void eap_report_error(struct eap_sm *sm, int error_code)
+{
+   wpa_printf(MSG_DEBUG, "EAP: Error notification: %d", error_code);
+   if (sm->eapol_cb->notify_eap_error)
+       sm->eapol_cb->notify_eap_error(sm->eapol_ctx, error_code);
+}

 static void eap_sm_free_key(struct eap_sm *sm)
 {
@@ -1934,6 +1940,7 @@ static void eap_sm_parseEapReq(struct eap_sm
*sm, const struct wpabuf *req)
    const struct eap_hdr *hdr;
    size_t plen;
    const u8 *pos;
+        int error_code;

    sm->rxReq = sm->rxResp = sm->rxSuccess = sm->rxFailure = FALSE;
    sm->reqId = 0;
@@ -2018,6 +2025,13 @@ static void eap_sm_parseEapReq(struct eap_sm
*sm, const struct wpabuf *req)
    case EAP_CODE_FAILURE:
        wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
        eap_notify_status(sm, "completion", "failure");
+
+       /* Get the error code from method */
+       if (sm->m->get_error_code) {
+           error_code = sm->m->get_error_code(sm->eap_method_priv);
+           if (error_code != NO_EAP_METHOD_ERROR)
+               eap_report_error(sm, error_code);
+       }
        sm->rxFailure = TRUE;
        break;
    case EAP_CODE_INITIATE:
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index b5591a0..d0837e3 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -246,6 +246,13 @@ struct eapol_callbacks {
    void (*notify_status)(void *ctx, const char *status,
                  const char *parameter);

+   /**
+    * notify_eap_error - Report EAP method error code
+    * @ctx: eapol_ctx from eap_peer_sm_init() call
+    * @error_code: Error code from the used EAP method
+    */
+   void (*notify_eap_error)(void *ctx, int error_code);
+
 #ifdef CONFIG_EAP_PROXY
    /**
     * eap_proxy_cb - Callback signifying any updates from eap_proxy
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 7a6bfc9..679f101 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -56,6 +56,7 @@ struct eap_aka_data {
    int kdf_negotiation;
    u16 last_kdf_attrs[EAP_AKA_PRIME_KDF_MAX];
    size_t last_kdf_count;
+   int error_code;
 };


@@ -99,6 +100,9 @@ static void * eap_aka_init(struct eap_sm *sm)

    data->eap_method = EAP_TYPE_AKA;

+   /* Zero is a valid error code, so we need to initialize */
+   data->error_code = NO_EAP_METHOD_ERROR;
+
    eap_aka_state(data, CONTINUE);
    data->prev_id = -1;

@@ -1180,6 +1184,7 @@ static struct wpabuf * eap_aka_process_notification(

    eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
    if (attr->notification >= 0 && attr->notification < 32768) {
+       data->error_code = attr->notification;
        eap_aka_state(data, FAILURE);
    } else if (attr->notification == EAP_SIM_SUCCESS &&
           data->state == RESULT_SUCCESS)
@@ -1523,6 +1528,20 @@ static u8 * eap_aka_get_emsk(struct eap_sm *sm,
void *priv, size_t *len)
    return key;
 }

+static int eap_aka_get_error_code(void *priv)
+{
+   struct eap_aka_data *data = priv;
+
+   if (!data)
+       return NO_EAP_METHOD_ERROR;
+
+   int current_data_error = data->error_code;
+
+   /* Now reset for next transaction */
+   data->error_code = NO_EAP_METHOD_ERROR;
+
+   return current_data_error;
+}

 int eap_peer_aka_register(void)
 {
@@ -1544,6 +1563,7 @@ int eap_peer_aka_register(void)
    eap->init_for_reauth = eap_aka_init_for_reauth;
    eap->get_identity = eap_aka_get_identity;
    eap->get_emsk = eap_aka_get_emsk;
+   eap->get_error_code = eap_aka_get_error_code;

    return eap_peer_method_register(eap);
 }
@@ -1571,6 +1591,7 @@ int eap_peer_aka_prime_register(void)
    eap->init_for_reauth = eap_aka_init_for_reauth;
    eap->get_identity = eap_aka_get_identity;
    eap->get_emsk = eap_aka_get_emsk;
+   eap->get_error_code = eap_aka_get_error_code;

    return eap_peer_method_register(eap);
 }
diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h
index 6ab2483..5b38969 100644
--- a/src/eap_peer/eap_i.h
+++ b/src/eap_peer/eap_i.h
@@ -14,6 +14,8 @@
 #include "eap_peer/eap.h"
 #include "eap_common/eap_common.h"

+#define NO_EAP_METHOD_ERROR (-1)
+
 /* RFC 4137 - EAP Peer state machine */

 typedef enum {
@@ -205,6 +207,17 @@ struct eap_method {
     */
    const u8 * (*get_identity)(struct eap_sm *sm, void *priv, size_t *len);

+   /**
+    * get_error_code - Get latest EAP method error code
+    * @priv: Pointer to private EAP method data from eap_method::init()
+    * Returns: An int for the EAP Method Error code if exists or
+    * NO_EAP_METHOD_ERROR otherwise
+    *
+    * This method is an optional handler that only EAP methods that need to
+    * report their error code need to implement.
+    */
+   int (*get_error_code)(void *priv);
+
    /**
     * free - Free EAP method data
     * @method: Pointer to the method data registered with
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index cd687cb..c0896aa 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -47,6 +47,7 @@ struct eap_sim_data {
    } state;
    int result_ind, use_result_ind;
    int use_pseudonym;
+   int error_code;
 };


@@ -94,6 +95,9 @@ static void * eap_sim_init(struct eap_sm *sm)
        return NULL;
    }

+   /* Zero is a valid error code, so we need to initialize */
+   data->error_code = NO_EAP_METHOD_ERROR;
+
    data->min_num_chal = 2;
    if (config && config->phase1) {
        char *pos = os_strstr(config->phase1, "sim_min_num_chal=");
@@ -920,6 +924,7 @@ static struct wpabuf * eap_sim_process_notification(

    eap_sim_report_notification(sm->msg_ctx, attr->notification, 0);
    if (attr->notification >= 0 && attr->notification < 32768) {
+       data->error_code = attr->notification;
        eap_sim_state(data, FAILURE);
    } else if (attr->notification == EAP_SIM_SUCCESS &&
           data->state == RESULT_SUCCESS)
@@ -1243,6 +1248,20 @@ static u8 * eap_sim_get_emsk(struct eap_sm *sm,
void *priv, size_t *len)
    return key;
 }

+static int eap_sim_get_error_code(void *priv)
+{
+   struct eap_sim_data *data = priv;
+
+   if (!data)
+       return NO_EAP_METHOD_ERROR;
+
+   int current_data_error = data->error_code;
+
+   /* Now reset for next transaction */
+   data->error_code = NO_EAP_METHOD_ERROR;
+
+   return current_data_error;
+}

 int eap_peer_sim_register(void)
 {
@@ -1264,6 +1283,7 @@ int eap_peer_sim_register(void)
    eap->init_for_reauth = eap_sim_init_for_reauth;
    eap->get_identity = eap_sim_get_identity;
    eap->get_emsk = eap_sim_get_emsk;
+   eap->get_error_code = eap_sim_get_error_code;

    return eap_peer_method_register(eap);
 }
diff --git a/src/eapol_supp/eapol_supp_sm.c b/src/eapol_supp/eapol_supp_sm.c
index 8e4f0e4..cb463ef 100644
--- a/src/eapol_supp/eapol_supp_sm.c
+++ b/src/eapol_supp/eapol_supp_sm.c
@@ -2014,6 +2014,13 @@ static void eapol_sm_notify_status(void *ctx,
const char *status,
        sm->ctx->status_cb(sm->ctx->ctx, status, parameter);
 }

+static void eapol_sm_notify_eap_error(void *ctx, int error_code)
+{
+   struct eapol_sm *sm = ctx;
+
+   if (sm->ctx->eap_error_cb)
+       sm->ctx->eap_error_cb(sm->ctx->ctx, error_code);
+}

 #ifdef CONFIG_EAP_PROXY

@@ -2062,6 +2069,7 @@ static const struct eapol_callbacks eapol_cb =
    eapol_sm_eap_param_needed,
    eapol_sm_notify_cert,
    eapol_sm_notify_status,
+   eapol_sm_notify_eap_error,
 #ifdef CONFIG_EAP_PROXY
    eapol_sm_eap_proxy_cb,
    eapol_sm_eap_proxy_notify_sim_status,
diff --git a/src/eapol_supp/eapol_supp_sm.h b/src/eapol_supp/eapol_supp_sm.h
index a25c799..74f40bb 100644
--- a/src/eapol_supp/eapol_supp_sm.h
+++ b/src/eapol_supp/eapol_supp_sm.h
@@ -271,6 +271,13 @@ struct eapol_ctx {
    void (*status_cb)(void *ctx, const char *status,
              const char *parameter);

+   /**
+    * eap_error_cb - Notification of EAP method error
+    * @ctx: Callback context (ctx)
+    * @error_code: EAP method error code
+    */
+   void (*eap_error_cb)(void *ctx, int error_code);
+
 #ifdef CONFIG_EAP_PROXY
    /**
     * eap_proxy_cb - Callback signifying any updates from eap_proxy
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a5db82c..8b62a6d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -887,6 +887,11 @@ void wpas_notify_eap_status(struct wpa_supplicant
*wpa_s, const char *status,
             status, parameter);
 }

+void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
+{
+   wpa_dbg(wpa_s, MSG_ERROR,
+       "EAP Error code = %d", error_code);
+}

 void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
                       struct wpa_ssid *ssid)
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 26b07f5..c3ac3d1 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -138,6 +138,7 @@ void wpas_notify_preq(struct wpa_supplicant *wpa_s,
              const u8 *ie, size_t ie_len, u32 ssi_signal);
 void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
                const char *parameter);
+void wpas_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code);
 void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
                       struct wpa_ssid *ssid);
 void wpas_notify_network_type_changed(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index e44f6af..e29f13b 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1037,6 +1037,12 @@ static void wpa_supplicant_status_cb(void *ctx,
const char *status,
    wpas_notify_eap_status(wpa_s, status, parameter);
 }

+static void wpa_supplicant_eap_error_cb(void *ctx, int error_code)
+{
+   struct wpa_supplicant *wpa_s = ctx;
+
+   wpas_notify_eap_error(wpa_s, error_code);
+}

 static void wpa_supplicant_set_anon_id(void *ctx, const u8 *id, size_t len)
 {
@@ -1115,6 +1121,7 @@ int wpa_supplicant_init_eapol(struct
wpa_supplicant *wpa_s)
    ctx->cert_cb = wpa_supplicant_cert_cb;
    ctx->cert_in_cb = wpa_s->conf->cert_in_cb;
    ctx->status_cb = wpa_supplicant_status_cb;
+   ctx->eap_error_cb = wpa_supplicant_eap_error_cb;
    ctx->set_anon_id = wpa_supplicant_set_anon_id;
    ctx->cb_ctx = wpa_s;
    wpa_s->eapol = eapol_sm_init(ctx);
--
2.17.0.rc1.321.gba9d0f2565-goog
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Propagate-the-EAP-method-error-code.patch
Type: text/x-patch
Size: 11465 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/hostap/attachments/20180328/e18bf6eb/attachment-0001.bin>

From sean at wolfssl.com  Wed Mar 28 21:55:55 2018
From: sean at wolfssl.com (Sean Parkinson)
Date: Thu, 29 Mar 2018 14:55:55 +1000
Subject: Proposed Patch: Support for wolfSSL
In-Reply-To: <20180303191907.GA13466@w1.fi>
References: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
 <20180303191907.GA13466@w1.fi>
Message-ID: <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>

Jouni,

(Excuse the previous email. This one in plaintext.)

I?ve looked into the failures and made changes as needed.
There were changes to wolfSSL as well.

To reproduce the setup I tested:
 - download wolfSSL latest from master (https://github.com/wolfssl/wolfssl)
 - configure wolfSSL with option -enable-wpas
 - build wolfSSL
 - in wpa_supplicant change .config
   - CONFIG_TLS=wolfssl
   - disable CONFIG_DPP

The proposed new patch is below.

Thanks,
Sean
?
Sean Parkinson
sean at wolfssl.com
wolfSSL Inc


From 80ba12c7fecdd650d7528211e68e6fd7ededd736 Mon Sep 17 00:00:00 2001
From: Sean Parkinson <sparki at wolfssl.com>
Date: Mon, 19 Mar 2018 13:19:08 +1000
Subject: [PATCH] Fixes for wolfSSL integration.

Use new digest namespace.
Changes for memory allocation failure testing.
Use same certificates as used for GnuTLS in tests.
Implement tls_connection_get_eap_fast_key using cryptographic primitives
as wolfSSL implements different spec.
Use a valid key exchange value in test.
Fix loading of client certificate to use 'chain' APIs.

Signed-off-by: Sean Parkinson <sean at wolfssl.com>
---
 hostapd/Makefile              |   2 +
 src/crypto/crypto_wolfssl.c   | 192 +++++++++++++++++++++++++++++++++---------
 src/crypto/fips_prf_wolfssl.c |   3 +-
 src/crypto/tls_wolfssl.c      | 109 ++++++++++++++----------
 tests/hwsim/test_ap_eap.py    |  10 +--
 tests/hwsim/test_eap_proto.py |   2 +-
 wpa_supplicant/Makefile       |   1 +
 7 files changed, 228 insertions(+), 91 deletions(-)

diff --git a/hostapd/Makefile b/hostapd/Makefile
index 98ce115..9f8c6cf 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -899,9 +899,11 @@ AESOBJS += ../src/crypto/aes-encblock.o
 endif
 ifdef NEED_AES_OMAC1
 ifneq ($(CONFIG_TLS), linux)
+ifneq ($(CONFIG_TLS), wolfssl)
 AESOBJS += ../src/crypto/aes-omac1.o
 endif
 endif
+endif
 ifdef NEED_AES_UNWRAP
 ifneq ($(CONFIG_TLS), openssl)
 ifneq ($(CONFIG_TLS), linux)
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 90163c4..7e68716 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -11,18 +11,8 @@
 #include "common.h"
 #include "crypto.h"
 
-#define WOLFSSL_AES_DIRECT
-#define HAVE_AESGCM
-#define HAVE_AES_KEYWRAP
-#define WOLFSSL_SHA384
-#define WOLFSSL_SHA512
-#define WOLFSSL_CMAC
-#define HAVE_ECC
-#define USE_FAST_MATH
-#define WOLFSSL_KEY_GEN
-
-#include <wolfssl/options.h>
 /* wolfSSL headers */
+#include <wolfssl/options.h>
 #include <wolfssl/wolfcrypt/md4.h>
 #include <wolfssl/wolfcrypt/md5.h>
 #include <wolfssl/wolfcrypt/sha.h>
@@ -62,7 +52,7 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-	Md5 md5;
+	wc_Md5 md5;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -83,7 +73,7 @@ int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-	Sha sha;
+	wc_Sha sha;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -104,7 +94,7 @@ int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha256 sha256;
+	wc_Sha256 sha256;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -126,7 +116,7 @@ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha384 sha384;
+	wc_Sha384 sha384;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -148,7 +138,7 @@ int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha512 sha512;
+	wc_Sha512 sha512;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -186,6 +176,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
 			return -1;
 	if (wc_HmacFinal(&hmac, mac) != 0)
 		return -1;
+
 	return 0;
 }
 
@@ -195,7 +186,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
 int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
 		    const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(MD5, key, key_len, num_elem, addr, len, mac,
+	return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len, mac,
 				   16);
 }
 
@@ -212,7 +203,7 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
 		     const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA, key, key_len, num_elem, addr, len, mac,
+	return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len, mac,
 				   20);
 }
 
@@ -229,7 +220,7 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
 		       const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA256, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
 				   mac, 32);
 }
 
@@ -248,7 +239,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
 int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
 		       const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA384, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
 				   mac, 48);
 }
 
@@ -267,7 +258,7 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
 		       const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA512, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
 				   mac, 64);
 }
 
@@ -285,7 +276,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
 		int iterations, u8 *buf, size_t buflen)
 {
 	if (wc_PBKDF2(buf, (const byte*)passphrase, os_strlen(passphrase), ssid,
-		      ssid_len, iterations, buflen, SHA) != 0)
+		      ssid_len, iterations, buflen, WC_SHA) != 0)
 		return -1;
 	return 0;
 }
@@ -423,6 +414,9 @@ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
 {
 	int ret;
 
+	if (TEST_FAIL())
+		return -1;
+
 	ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
 			    NULL);
 	return ret != (n + 1) * 8 ? -1 : 0;
@@ -434,6 +428,9 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
 {
 	int ret;
 
+	if (TEST_FAIL())
+		return -1;
+
 	ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
 			      NULL);
 	return ret != n * 8 ? -1 : 0;
@@ -654,13 +651,13 @@ void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
 	wpabuf_free(*publ);
 	*publ = NULL;
 
-	dh = os_malloc(sizeof(DhKey));
+	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!dh)
 		return NULL;
 	wc_InitDhKey(dh);
 
 	if (wc_InitRng(&rng) != 0) {
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 		return NULL;
 	}
 
@@ -692,7 +689,7 @@ done:
 	wpabuf_clear_free(privkey);
 	if (dh) {
 		wc_FreeDhKey(dh);
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	}
 	wc_FreeRng(&rng);
 	return ret;
@@ -706,12 +703,12 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 	byte *secret;
 	word32 secret_sz;
 
-	dh = os_malloc(sizeof(DhKey));
+	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!dh)
 		return NULL;
 	wc_InitDhKey(dh);
 
-	secret = os_malloc(RFC3526_LEN);
+	secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!secret)
 		goto done;
 
@@ -734,9 +731,9 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 done:
 	if (dh) {
 		wc_FreeDhKey(dh);
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	}
-	os_free(secret);
+	XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	return ret;
 }
 
@@ -773,7 +770,7 @@ void dh5_free(void *ctx)
 		return;
 
 	wc_FreeDhKey(ctx);
-	os_free(ctx);
+	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 }
 
 #endif /* CONFIG_WPS_NFC */
@@ -787,9 +784,6 @@ int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
 	DhKey *dh = NULL;
 	word32 priv_sz, pub_sz;
 
-	if (TEST_FAIL())
-		return -1;
-
 	dh = os_malloc(sizeof(DhKey));
 	if (!dh)
 		return -1;
@@ -889,7 +883,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 	struct crypto_hash *hash;
 	int type;
 
-	hash = os_malloc(sizeof(*hash));
+	hash = os_zalloc(sizeof(*hash));
 	if (!hash)
 		goto done;
 
@@ -897,19 +891,19 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 #ifndef NO_MD5
 	case CRYPTO_HASH_ALG_HMAC_MD5:
 		hash->size = 16;
-		type = MD5;
+		type = WC_MD5;
 		break;
 #endif /* NO_MD5 */
 #ifndef NO_SHA
 	case CRYPTO_HASH_ALG_HMAC_SHA1:
-		type = SHA;
+		type = WC_SHA;
 		hash->size = 20;
 		break;
 #endif /* NO_SHA */
 #ifdef CONFIG_SHA256
 #ifndef NO_SHA256
 	case CRYPTO_HASH_ALG_HMAC_SHA256:
-		type = SHA256;
+		type = WC_SHA256;
 		hash->size = 32;
 		break;
 #endif /* NO_SHA256 */
@@ -1597,7 +1591,7 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
 	ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len);
 	if (ret <= 0)
 		return -1;
-	ret = wc_ecc_import_point_der(buf, ret + 1, e->key.idx,
+	ret = wc_ecc_import_point_der(buf, ret * 2 + 1, e->key.idx,
 				      (ecc_point *) p);
 	if (ret != 0)
 		return -1;
@@ -1625,7 +1619,7 @@ crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
 		goto done;
 
 	if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
-	    mp_mulmod((mp_int *) x, &t, &e->prime, y2) != 0 ||
+	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
 	    mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
 	    mp_addmod(y2, &t, &e->prime, y2) != 0 ||
 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0)
@@ -1667,4 +1661,124 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
 }
 
+struct crypto_ecdh {
+	struct crypto_ec *ec;
+};
+
+struct crypto_ecdh * crypto_ecdh_init(int group)
+{
+	struct crypto_ecdh *ecdh = NULL;
+	WC_RNG rng;
+	int ret;
+
+	if (wc_InitRng(&rng) != 0)
+		goto fail;
+
+	ecdh = os_zalloc(sizeof(*ecdh));
+	if (!ecdh)
+		goto fail;
+
+	ecdh->ec = crypto_ec_init(group);
+	if (!ecdh->ec)
+		goto fail;
+
+	ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
+				 ecdh->ec->key.dp->id);
+	if (ret < 0)
+		goto fail;
+
+done:
+	wc_FreeRng(&rng);
+
+	return ecdh;
+fail:
+	crypto_ecdh_deinit(ecdh);
+	ecdh = NULL;
+	goto done;
+}
+
+void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
+{
+	if (ecdh) {
+		crypto_ec_deinit(ecdh->ec);
+		os_free(ecdh);
+	}
+}
+
+struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
+{
+	struct wpabuf *buf = NULL;
+	int ret;
+	int len = ecdh->ec->key.dp->size;
+
+	buf = wpabuf_alloc(inc_y ? 2 * len : len);
+	if (!buf)
+		goto fail;
+
+	ret = crypto_bignum_to_bin((struct crypto_bignum *)
+				   ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
+				   len, len);
+	if (ret < 0)
+		goto fail;
+	if (inc_y) {
+		ret = crypto_bignum_to_bin((struct crypto_bignum *)
+					   ecdh->ec->key.pubkey.y,
+					   wpabuf_put(buf, len), len, len);
+		if (ret < 0)
+			goto fail;
+	}
+
+done:
+	return buf;
+fail:
+	wpabuf_free(buf);
+	buf = NULL;
+	goto done;
+}
+
+struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
+					const u8 *key, size_t len)
+{
+	int ret;
+	struct wpabuf *pubkey = NULL;
+	struct wpabuf *secret = NULL;
+	word32 key_len = ecdh->ec->key.dp->size;
+	ecc_point *point = NULL;
+
+	pubkey = wpabuf_alloc(key_len + 1);
+	if (!pubkey)
+		goto fail;
+	wpabuf_put_u8(pubkey, inc_y ? 0x04 : 0x02);
+	wpabuf_put_data(pubkey, key, key_len);
+
+	point = wc_ecc_new_point();
+	if (!point)
+		goto fail;
+
+	ret = wc_ecc_import_point_der(wpabuf_put(pubkey, key_len + 1), key_len,
+				      ecdh->ec->key.dp->id, point);
+	if (ret != MP_OKAY)
+		goto fail;
+
+	secret = wpabuf_alloc(key_len);
+	if (!secret)
+		goto fail;
+
+	ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
+				      (byte*)wpabuf_put(secret, key_len),
+				      &key_len);
+	if (ret != MP_OKAY)
+		goto fail;
+
+done:
+	wc_ecc_del_point(point);
+	wpabuf_free(pubkey);
+	return secret;
+fail:
+	wpabuf_free(secret);
+	secret = NULL;
+	goto done;
+}
+
+
 #endif /* CONFIG_ECC */
diff --git a/src/crypto/fips_prf_wolfssl.c b/src/crypto/fips_prf_wolfssl.c
index 1709932..feb39db 100644
--- a/src/crypto/fips_prf_wolfssl.c
+++ b/src/crypto/fips_prf_wolfssl.c
@@ -7,6 +7,7 @@
  */
 
 #include "includes.h"
+#include <wolfssl/options.h>
 #include <wolfssl/wolfcrypt/sha.h>
 
 #include "common.h"
@@ -15,7 +16,7 @@
 
 static void sha1_transform(u32 *state, const u8 data[64])
 {
-	Sha sha;
+	wc_Sha sha;
 
 	os_memset(&sha, 0, sizeof(sha));
 	sha.digest[0] = state[0];
diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
index b7c452e..82ced39 100644
--- a/src/crypto/tls_wolfssl.c
+++ b/src/crypto/tls_wolfssl.c
@@ -10,24 +10,16 @@
 
 #include "common.h"
 #include "crypto.h"
+#include "sha1.h"
 #include "tls.h"
 
-#define OPENSSL_EXTRA
-#define HAVE_STUNNEL
-#define HAVE_SECRET_CALLBACK
-#define HAVE_SESSION_TICKET
-#define HAVE_OCSP
-#define HAVE_CERTIFICATE_STATUS_REQUEST
-#define HAVE_CERTIFICATE_STATUS_REQUEST_V2
-#ifndef WOLFSSL_DER_LOAD
-#define WOLFSSL_DER_LOAD
-#endif
-#if 0
-/* Enable if a debug build of wolfSSL is installed. */
-#define DEBUG_WOLFSSL
-#endif
+/* sha256.h is a wolfSSL header file. */
+extern void tls_prf_sha256(const u8 *secret, size_t secret_len,
+			   const char *label, const u8 *seed, size_t seed_len,
+			   u8 *out, size_t outlen);
 
 /* wolfSSL includes */
+#include <wolfssl/options.h>
 #include <wolfssl/ssl.h>
 #include <wolfssl/error-ssl.h>
 #include <wolfssl/wolfcrypt/asn.h>
@@ -470,9 +462,9 @@ static int tls_connection_client_cert(struct tls_connection *conn,
 		return 0;
 
 	if (client_cert_blob) {
-		if (wolfSSL_use_certificate_buffer(conn->ssl, client_cert_blob,
-						   blob_len,
-						   SSL_FILETYPE_ASN1) < 0) {
+		if (wolfSSL_use_certificate_chain_buffer_format(conn->ssl,
+			    client_cert_blob, blob_len,
+			    SSL_FILETYPE_ASN1) < 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert DER blob failed");
 			return -1;
@@ -482,11 +474,11 @@ static int tls_connection_client_cert(struct tls_connection *conn,
 	}
 
 	if (client_cert) {
-		if (wolfSSL_use_certificate_file(conn->ssl, client_cert,
-						 SSL_FILETYPE_PEM) < 0) {
+		if (wolfSSL_use_certificate_chain_file(conn->ssl,
+						       client_cert) < 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert PEM file failed");
-			if (wolfSSL_use_certificate_file(
+			if (wolfSSL_use_certificate_chain_file_format(
 				    conn->ssl, client_cert,
 				    SSL_FILETYPE_ASN1) < 0) {
 				wpa_printf(MSG_INFO,
@@ -577,10 +569,6 @@ static int tls_connection_private_key(void *tls_ctx,
 }
 
 
-#define GEN_EMAIL	1
-#define GEN_DNS		ALT_NAMES_OID
-#define GEN_URI		6
-
 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
 					   const char *value, size_t len)
 {
@@ -590,7 +578,6 @@ static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
 	int i;
 
 	ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
-
 	for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
 		gen = wolfSSL_sk_value(ext, i);
 		if (gen->type != type)
@@ -893,19 +880,16 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
 		if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
 			break;
 		gen = wolfSSL_sk_value((void *) ext, i);
-#if 0
 		if (gen->type != GEN_EMAIL &&
 		    gen->type != GEN_DNS &&
 		    gen->type != GEN_URI)
 			continue;
-#endif
 
 		pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
 		if (!pos)
 			break;
 		alt_subject[num_alt_subject++] = pos;
 
-#if 0
 		switch (gen->type) {
 		case GEN_EMAIL:
 			os_memcpy(pos, "EMAIL:", 6);
@@ -920,10 +904,6 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
 			pos += 4;
 			break;
 		}
-#else
-		os_memcpy(pos, "DNS:", 4);
-		pos += 4;
-#endif
 
 		os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
 		pos += os_strlen((char *)gen->obj);
@@ -1099,7 +1079,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
 				       TLS_FAIL_SERVER_CHAIN_PROBE);
 	}
 
-#ifdef HAVE_OCSP_OPENSSL
+#ifdef HAVE_OCSP_WOLFSSL
 	if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
 	    preverify_ok) {
 		enum ocsp_result res;
@@ -1123,7 +1103,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
 					       TLS_FAIL_UNSPECIFIED);
 		}
 	}
-#endif /* HAVE_OCSP */
+#endif /* HAVE_OCSP_WOLFSSL */
 	if (depth == 0 && preverify_ok && context->event_cb != NULL)
 		context->event_cb(context->cb_ctx,
 				  TLS_CERT_CHAIN_SUCCESS, NULL);
@@ -1204,7 +1184,6 @@ static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
 			return -1;
 		}
 		wolfSSL_CTX_set_cert_store(ctx, cm);
-		XFREE(cm, NULL, DYNAMIC_TYPE_X509_STORE);
 
 		if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
 		    SSL_SUCCESS) {
@@ -1370,11 +1349,11 @@ static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
 	if (!client_cert)
 		return 0;
 
-	if (wolfSSL_CTX_use_certificate_file(ctx, client_cert,
-					     SSL_FILETYPE_ASN1) !=
+	if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
+							  SSL_FILETYPE_ASN1) !=
 	    SSL_SUCCESS &&
-	    wolfSSL_CTX_use_certificate_file(ctx, client_cert,
-					     SSL_FILETYPE_PEM) != SSL_SUCCESS) {
+	    wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
+	    SSL_SUCCESS) {
 		wpa_printf(MSG_INFO, "Failed to load client certificate");
 		return -1;
 	}
@@ -1988,18 +1967,58 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
 }
 
 
+#define SEED_LEN	(RAN_LEN + RAN_LEN)
+
 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
 				    u8 *out, size_t out_len)
 {
-	int ret;
+	byte seed[SEED_LEN];
+	int ret = -1;
+	WOLFSSL *ssl;
+	byte *tmp_out = NULL;
+	byte *_out;
+	int skip = 0;
+	byte *master_key;
+	unsigned int master_key_len;
+	byte *server_random;
+	unsigned int server_len;
+	byte *client_random;
+	unsigned int client_len;
 
 	if (!conn || !conn->ssl)
 		return -1;
+	ssl = conn->ssl;
 
-	ret = wolfSSL_make_eap_keys(conn->ssl, out, out_len, "key expansion");
-	if (ret != 0)
+	skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
+		    wolfSSL_GetIVSize(ssl));
+
+	tmp_out = os_malloc(skip + out_len);
+	if (!tmp_out)
 		return -1;
-	return 0;
+	_out = tmp_out;
+
+	wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
+			 &server_len, &client_random, &client_len);
+	XMEMCPY(seed          , server_random, RAN_LEN);
+	XMEMCPY(seed + RAN_LEN, client_random, RAN_LEN);
+
+	if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
+		tls_prf_sha256(master_key, master_key_len,
+			       "key expansion", seed, sizeof(seed),
+			       _out, skip + out_len);
+		ret = 0;
+	} else if (tls_prf_sha1_md5(master_key, master_key_len,
+				    "key expansion", seed, sizeof(seed),
+				    _out, skip + out_len) == 0) {
+		ret = 0;
+	}
+
+	os_memset(master_key, 0, master_key_len);
+	if (ret == 0)
+		os_memcpy(out, _out + skip, out_len);
+	bin_clear_free(tmp_out, skip);
+
+	return ret;
 }
 
 
@@ -2037,14 +2056,14 @@ static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
 				      sizeof(client_random)) == 0 ||
 	    wolfSSL_get_server_random(s, server_random,
 				      sizeof(server_random)) == 0 ||
-	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticketLen) != 1)
+	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticket_len) != 1)
 		return 1;
 
 	if (ticket_len == 0)
 		return 0;
 
 	ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
-				      conn->session_ticket, ticketLen,
+				      conn->session_ticket, ticket_len,
 				      client_random, server_random, secret);
 	if (ret <= 0)
 		return 1;
diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
index 88041ca..804cbca 100644
--- a/tests/hwsim/test_ap_eap.py
+++ b/tests/hwsim/test_ap_eap.py
@@ -4115,7 +4115,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca(dev, apdev, params):
     params["private_key"] = "auth_serv/iCA-server/server.key"
     hostapd.add_ap(apdev[0], params)
     tls = dev[0].request("GET tls_library")
-    if "GnuTLS" in tls:
+    if "GnuTLS" in tls or "wolfSSL" in tls:
         ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
         client_cert = "auth_serv/iCA-user/user_and_ica.pem"
     else:
@@ -4223,7 +4223,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md):
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4258,7 +4258,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked(dev, apdev, params, md):
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4308,7 +4308,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi_missing_resp(dev, apdev, par
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4375,7 +4375,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi(dev, apdev, params):
 
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
diff --git a/tests/hwsim/test_eap_proto.py b/tests/hwsim/test_eap_proto.py
index d97a6f1..2ff6743 100644
--- a/tests/hwsim/test_eap_proto.py
+++ b/tests/hwsim/test_eap_proto.py
@@ -5124,7 +5124,7 @@ def test_eap_proto_ikev2(dev, apdev):
 
         def build_ke(next=0):
             ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
-            ke += 192*'\x00'
+            ke += 191*'\x00'+'\x02'
             return ke
 
         idx += 1
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index c761c22..eca20a9 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -1067,6 +1067,7 @@ OBJS_p += ../src/crypto/crypto_wolfssl.o
 ifdef NEED_FIPS186_2_PRF
 OBJS += ../src/crypto/fips_prf_wolfssl.o
 endif
+NEED_TLS_PRF_SHA256=y
 LIBS += -lwolfssl -lm
 LIBS_p += -lwolfssl -lm
 endif
-- 
1.9.1
> On 4 Mar 2018, at 5:19 am, Jouni Malinen <j at w1.fi> wrote:
> 
> On Thu, Jan 18, 2018 at 12:26:39PM +1000, Sean Parkinson wrote:
>> I?ve prepared a new patch with the changes as asked for by Jouni.
>> 
>> This patch was written to allow hostap to be compiled with the wolfSSL cryptography and TLS library.
> 
> Thanks! I'm seeing number of errors in the hwsim test cases, but it
> looks like it is easiest to move ahead with this if I push in the
> cleaned up version that I've been testing with some fixes to avoid
> breaking non-wolfSSL builds. I'd welcome any incremental changes on top
> of the current hostap.git master branch snapshot to address things that
> I list below or maybe a recommendation on how to configure the wolfSSL
> build properly to avoid the issues. I ran my tests with wolfSSL 3.13.0
> and ended up adding various configure options until the build went
> through cleanly. This ended up with following options:
> 
> ./configure --prefix=/home/jm/wolfssl/3.13.0 --enable-des3 --enable-md4 --enable-harden --enable-pwdbased --enable-tlsv10 --enable-oldtls --enable-cmac --enable-aeskeywrap --enable-keygen --enable-crl --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 --enable-pkcallbacks --enable-tls13 --enable-fortress --enable-wpas --enable-static=yes --enable-shared=no
> 
> 
> These are the notes from my hwsim test runs:
> 
> SAE:
> - SAE: Could not solve y
> - SAE: Could not pick PWE
> --> check crypto_ec_point_solve_y_coord() implementation
>   (wc_ecc_import_point_der() returns -1)
> sae
> sae_anti_clogging
> sae_anti_clogging_proto
> sae_bignum_failure
> sae_forced_anti_clogging
> sae_group_nego
> sae_groups
> sae_invalid_anti_clogging_token_req
> sae_key_lifetime_in_memory
> sae_mixed
> sae_mixed_mfp
> sae_no_random
> sae_oom_wpas
> sae_password
> sae_password_ecc
> sae_password_long
> sae_password_short
> sae_pmksa_caching
> sae_pmksa_caching_disabled
> sae_proto_confirm_replay
> sae_proto_ecc
> sae_pwe_failure
> ap_ft_sae
> ap_ft_sae_over_ds
> sigma_dut_ap_psk_sae
> sigma_dut_ap_sae
> sigma_dut_ap_sae_group
> sigma_dut_ap_sae_password
> sigma_dut_sae
> sigma_dut_sae_password
> wpas_mesh_password_mismatch
> mesh_forwarding_secure
> ap_mixed_security
> 
> 
> TLS interop(?) issue with OpenSSL server:
> - OpenSSL server:
>  * SSL: SSL3 alert: write (local SSL3 detected an error):fatal:bad record mac
>  * SSL: SSL_accept:error in SSLv3 read finished A
>  * OpenSSL: openssl_handshake - SSL_connect error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
> ap_hs20_remediation_sql
> eap_tls_no_session_resumption_radius
> authsrv_testing_options
> ap_wpa2_eap_tls_versions
> 
> 
> OpenSSL authentication server:
> - OpenSSL: openssl_handshake - SSL_connect error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
> ap_wpa2_eap_ttls_dh_params
> ap_wpa2_eap_ttls_dh_params_blob
> ap_wpa2_eap_ttls_dh_params_dsa
> 
> 
> OpenSSL authentication server:
> - TLS: Certificate verification failed, error 20 (unable to get local issuer certificate) depth 0 for '/C=FI/O=w1.fi/CN=user.w1.fi'
> - SSL: SSL3 alert: write (local SSL3 detected an error):fatal:unknown CA
> - OpenSSL: openssl_handshake - SSL_connect error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
> ap_wpa2_eap_tls_intermediate_ca
> ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1
> ap_wpa2_eap_tls_intermediate_ca_ocsp
> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked
> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked_sha1
> 
> 
> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
> TLS: altSubjectName match 'EMAIL:noone at example.com;DNS:server.w1.fi;URI:http://example.com/' not found
> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
> ap_wpa2_eap_ttls_pap_subject_match
> 
> 
> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
> TLS: altSubjectName match 'EMAIL:noone at example.com;URI:http://example.com/;DNS:server.w1.fi' not found
> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
> ap_wpa2_eap_ttls_chap_altsubject_match
> 
> 
> TLS: Certificate verification failed, error -407 (Invalid OCSP Status Error) depth 2 for '/C=FI/O=w1.fi/CN=server.w1.fi'
> ap_wpa2_eap_ttls_ocsp_revoked
> ap_wpa2_eap_ttls_ocsp_unknown
> ap_wpa2_eap_ttls_optional_ocsp_unknown
> 
> 
> Missing altsubject in D-Bus output?!
> dbus_connect_eap
> 
> 
> DH: crypto_dh_derive_secret failed
> eap_proto_ikev2
> 
> 
> TLS: Certificate verification failed, error -238 (ASN CA path length larger than signer error) depth 2 for '/C=FI/O=w1.fi/CN=sha384.server.w1.fi'
> eap_tls_sha384
> eap_tls_sha512
> 
> 
> 
> GET_FAIL/GET_ALLOC_FAIL failure did not trigger:
> radius_mppe_failure
> authsrv_oom
> 
> 
> -- 
> Jouni Malinen                                            PGP id EFC895FA
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap



From sean at wolfssl.com  Thu Mar 29 16:58:14 2018
From: sean at wolfssl.com (Sean Parkinson)
Date: Fri, 30 Mar 2018 09:58:14 +1000
Subject: Proposed Patch: Support for wolfSSL
In-Reply-To: <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>
References: <35F71B52-8428-4A0E-B14C-20CFF8CBCA65@wolfssl.com>
 <20180303191907.GA13466@w1.fi>
 <CE258BE9-FCBE-47C0-B7AB-C95AA65320ED@wolfssl.com>
Message-ID: <A401EC30-BDBF-4066-9099-F334552F309E@wolfssl.com>

Jouni,

Also note that the OCSP is not supported yet.

Thanks,
Sean
?
Sean Parkinson
sean at wolfssl.com
wolfSSL Inc



> On 29 Mar 2018, at 2:55 pm, Sean Parkinson <sean at wolfssl.com> wrote:
> 
> Jouni,
> 
> (Excuse the previous email. This one in plaintext.)
> 
> I?ve looked into the failures and made changes as needed.
> There were changes to wolfSSL as well.
> 
> To reproduce the setup I tested:
> - download wolfSSL latest from master (https://github.com/wolfssl/wolfssl)
> - configure wolfSSL with option -enable-wpas
> - build wolfSSL
> - in wpa_supplicant change .config
>   - CONFIG_TLS=wolfssl
>   - disable CONFIG_DPP
> 
> The proposed new patch is below.
> 
> Thanks,
> Sean
> ?
> Sean Parkinson
> sean at wolfssl.com
> wolfSSL Inc
> 
> 
> From 80ba12c7fecdd650d7528211e68e6fd7ededd736 Mon Sep 17 00:00:00 2001
> From: Sean Parkinson <sparki at wolfssl.com>
> Date: Mon, 19 Mar 2018 13:19:08 +1000
> Subject: [PATCH] Fixes for wolfSSL integration.
> 
> Use new digest namespace.
> Changes for memory allocation failure testing.
> Use same certificates as used for GnuTLS in tests.
> Implement tls_connection_get_eap_fast_key using cryptographic primitives
> as wolfSSL implements different spec.
> Use a valid key exchange value in test.
> Fix loading of client certificate to use 'chain' APIs.
> 
> Signed-off-by: Sean Parkinson <sean at wolfssl.com>
> ---
> hostapd/Makefile              |   2 +
> src/crypto/crypto_wolfssl.c   | 192 +++++++++++++++++++++++++++++++++---------
> src/crypto/fips_prf_wolfssl.c |   3 +-
> src/crypto/tls_wolfssl.c      | 109 ++++++++++++++----------
> tests/hwsim/test_ap_eap.py    |  10 +--
> tests/hwsim/test_eap_proto.py |   2 +-
> wpa_supplicant/Makefile       |   1 +
> 7 files changed, 228 insertions(+), 91 deletions(-)
> 
> diff --git a/hostapd/Makefile b/hostapd/Makefile
> index 98ce115..9f8c6cf 100644
> --- a/hostapd/Makefile
> +++ b/hostapd/Makefile
> @@ -899,9 +899,11 @@ AESOBJS += ../src/crypto/aes-encblock.o
> endif
> ifdef NEED_AES_OMAC1
> ifneq ($(CONFIG_TLS), linux)
> +ifneq ($(CONFIG_TLS), wolfssl)
> AESOBJS += ../src/crypto/aes-omac1.o
> endif
> endif
> +endif
> ifdef NEED_AES_UNWRAP
> ifneq ($(CONFIG_TLS), openssl)
> ifneq ($(CONFIG_TLS), linux)
> diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
> index 90163c4..7e68716 100644
> --- a/src/crypto/crypto_wolfssl.c
> +++ b/src/crypto/crypto_wolfssl.c
> @@ -11,18 +11,8 @@
> #include "common.h"
> #include "crypto.h"
> 
> -#define WOLFSSL_AES_DIRECT
> -#define HAVE_AESGCM
> -#define HAVE_AES_KEYWRAP
> -#define WOLFSSL_SHA384
> -#define WOLFSSL_SHA512
> -#define WOLFSSL_CMAC
> -#define HAVE_ECC
> -#define USE_FAST_MATH
> -#define WOLFSSL_KEY_GEN
> -
> -#include <wolfssl/options.h>
> /* wolfSSL headers */
> +#include <wolfssl/options.h>
> #include <wolfssl/wolfcrypt/md4.h>
> #include <wolfssl/wolfcrypt/md5.h>
> #include <wolfssl/wolfcrypt/sha.h>
> @@ -62,7 +52,7 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
> 
> int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	Md5 md5;
> +	wc_Md5 md5;
> 	size_t i;
> 
> 	if (TEST_FAIL())
> @@ -83,7 +73,7 @@ int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
> 
> int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	Sha sha;
> +	wc_Sha sha;
> 	size_t i;
> 
> 	if (TEST_FAIL())
> @@ -104,7 +94,7 @@ int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
> int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
> 		  u8 *mac)
> {
> -	Sha256 sha256;
> +	wc_Sha256 sha256;
> 	size_t i;
> 
> 	if (TEST_FAIL())
> @@ -126,7 +116,7 @@ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
> int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
> 		  u8 *mac)
> {
> -	Sha384 sha384;
> +	wc_Sha384 sha384;
> 	size_t i;
> 
> 	if (TEST_FAIL())
> @@ -148,7 +138,7 @@ int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
> int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
> 		  u8 *mac)
> {
> -	Sha512 sha512;
> +	wc_Sha512 sha512;
> 	size_t i;
> 
> 	if (TEST_FAIL())
> @@ -186,6 +176,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
> 			return -1;
> 	if (wc_HmacFinal(&hmac, mac) != 0)
> 		return -1;
> +
> 	return 0;
> }
> 
> @@ -195,7 +186,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
> int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
> 		    const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	return wolfssl_hmac_vector(MD5, key, key_len, num_elem, addr, len, mac,
> +	return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len, mac,
> 				   16);
> }
> 
> @@ -212,7 +203,7 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
> int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
> 		     const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	return wolfssl_hmac_vector(SHA, key, key_len, num_elem, addr, len, mac,
> +	return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len, mac,
> 				   20);
> }
> 
> @@ -229,7 +220,7 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
> int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
> 		       const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	return wolfssl_hmac_vector(SHA256, key, key_len, num_elem, addr, len,
> +	return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
> 				   mac, 32);
> }
> 
> @@ -248,7 +239,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
> int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
> 		       const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	return wolfssl_hmac_vector(SHA384, key, key_len, num_elem, addr, len,
> +	return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
> 				   mac, 48);
> }
> 
> @@ -267,7 +258,7 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
> int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
> 		       const u8 *addr[], const size_t *len, u8 *mac)
> {
> -	return wolfssl_hmac_vector(SHA512, key, key_len, num_elem, addr, len,
> +	return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
> 				   mac, 64);
> }
> 
> @@ -285,7 +276,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
> 		int iterations, u8 *buf, size_t buflen)
> {
> 	if (wc_PBKDF2(buf, (const byte*)passphrase, os_strlen(passphrase), ssid,
> -		      ssid_len, iterations, buflen, SHA) != 0)
> +		      ssid_len, iterations, buflen, WC_SHA) != 0)
> 		return -1;
> 	return 0;
> }
> @@ -423,6 +414,9 @@ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
> {
> 	int ret;
> 
> +	if (TEST_FAIL())
> +		return -1;
> +
> 	ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
> 			    NULL);
> 	return ret != (n + 1) * 8 ? -1 : 0;
> @@ -434,6 +428,9 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
> {
> 	int ret;
> 
> +	if (TEST_FAIL())
> +		return -1;
> +
> 	ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
> 			      NULL);
> 	return ret != n * 8 ? -1 : 0;
> @@ -654,13 +651,13 @@ void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
> 	wpabuf_free(*publ);
> 	*publ = NULL;
> 
> -	dh = os_malloc(sizeof(DhKey));
> +	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	if (!dh)
> 		return NULL;
> 	wc_InitDhKey(dh);
> 
> 	if (wc_InitRng(&rng) != 0) {
> -		os_free(dh);
> +		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 		return NULL;
> 	}
> 
> @@ -692,7 +689,7 @@ done:
> 	wpabuf_clear_free(privkey);
> 	if (dh) {
> 		wc_FreeDhKey(dh);
> -		os_free(dh);
> +		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	}
> 	wc_FreeRng(&rng);
> 	return ret;
> @@ -706,12 +703,12 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
> 	byte *secret;
> 	word32 secret_sz;
> 
> -	dh = os_malloc(sizeof(DhKey));
> +	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	if (!dh)
> 		return NULL;
> 	wc_InitDhKey(dh);
> 
> -	secret = os_malloc(RFC3526_LEN);
> +	secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	if (!secret)
> 		goto done;
> 
> @@ -734,9 +731,9 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
> done:
> 	if (dh) {
> 		wc_FreeDhKey(dh);
> -		os_free(dh);
> +		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	}
> -	os_free(secret);
> +	XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> 	return ret;
> }
> 
> @@ -773,7 +770,7 @@ void dh5_free(void *ctx)
> 		return;
> 
> 	wc_FreeDhKey(ctx);
> -	os_free(ctx);
> +	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
> }
> 
> #endif /* CONFIG_WPS_NFC */
> @@ -787,9 +784,6 @@ int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
> 	DhKey *dh = NULL;
> 	word32 priv_sz, pub_sz;
> 
> -	if (TEST_FAIL())
> -		return -1;
> -
> 	dh = os_malloc(sizeof(DhKey));
> 	if (!dh)
> 		return -1;
> @@ -889,7 +883,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
> 	struct crypto_hash *hash;
> 	int type;
> 
> -	hash = os_malloc(sizeof(*hash));
> +	hash = os_zalloc(sizeof(*hash));
> 	if (!hash)
> 		goto done;
> 
> @@ -897,19 +891,19 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
> #ifndef NO_MD5
> 	case CRYPTO_HASH_ALG_HMAC_MD5:
> 		hash->size = 16;
> -		type = MD5;
> +		type = WC_MD5;
> 		break;
> #endif /* NO_MD5 */
> #ifndef NO_SHA
> 	case CRYPTO_HASH_ALG_HMAC_SHA1:
> -		type = SHA;
> +		type = WC_SHA;
> 		hash->size = 20;
> 		break;
> #endif /* NO_SHA */
> #ifdef CONFIG_SHA256
> #ifndef NO_SHA256
> 	case CRYPTO_HASH_ALG_HMAC_SHA256:
> -		type = SHA256;
> +		type = WC_SHA256;
> 		hash->size = 32;
> 		break;
> #endif /* NO_SHA256 */
> @@ -1597,7 +1591,7 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
> 	ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len);
> 	if (ret <= 0)
> 		return -1;
> -	ret = wc_ecc_import_point_der(buf, ret + 1, e->key.idx,
> +	ret = wc_ecc_import_point_der(buf, ret * 2 + 1, e->key.idx,
> 				      (ecc_point *) p);
> 	if (ret != 0)
> 		return -1;
> @@ -1625,7 +1619,7 @@ crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
> 		goto done;
> 
> 	if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
> -	    mp_mulmod((mp_int *) x, &t, &e->prime, y2) != 0 ||
> +	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
> 	    mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
> 	    mp_addmod(y2, &t, &e->prime, y2) != 0 ||
> 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0)
> @@ -1667,4 +1661,124 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
> 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
> }
> 
> +struct crypto_ecdh {
> +	struct crypto_ec *ec;
> +};
> +
> +struct crypto_ecdh * crypto_ecdh_init(int group)
> +{
> +	struct crypto_ecdh *ecdh = NULL;
> +	WC_RNG rng;
> +	int ret;
> +
> +	if (wc_InitRng(&rng) != 0)
> +		goto fail;
> +
> +	ecdh = os_zalloc(sizeof(*ecdh));
> +	if (!ecdh)
> +		goto fail;
> +
> +	ecdh->ec = crypto_ec_init(group);
> +	if (!ecdh->ec)
> +		goto fail;
> +
> +	ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
> +				 ecdh->ec->key.dp->id);
> +	if (ret < 0)
> +		goto fail;
> +
> +done:
> +	wc_FreeRng(&rng);
> +
> +	return ecdh;
> +fail:
> +	crypto_ecdh_deinit(ecdh);
> +	ecdh = NULL;
> +	goto done;
> +}
> +
> +void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
> +{
> +	if (ecdh) {
> +		crypto_ec_deinit(ecdh->ec);
> +		os_free(ecdh);
> +	}
> +}
> +
> +struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
> +{
> +	struct wpabuf *buf = NULL;
> +	int ret;
> +	int len = ecdh->ec->key.dp->size;
> +
> +	buf = wpabuf_alloc(inc_y ? 2 * len : len);
> +	if (!buf)
> +		goto fail;
> +
> +	ret = crypto_bignum_to_bin((struct crypto_bignum *)
> +				   ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
> +				   len, len);
> +	if (ret < 0)
> +		goto fail;
> +	if (inc_y) {
> +		ret = crypto_bignum_to_bin((struct crypto_bignum *)
> +					   ecdh->ec->key.pubkey.y,
> +					   wpabuf_put(buf, len), len, len);
> +		if (ret < 0)
> +			goto fail;
> +	}
> +
> +done:
> +	return buf;
> +fail:
> +	wpabuf_free(buf);
> +	buf = NULL;
> +	goto done;
> +}
> +
> +struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
> +					const u8 *key, size_t len)
> +{
> +	int ret;
> +	struct wpabuf *pubkey = NULL;
> +	struct wpabuf *secret = NULL;
> +	word32 key_len = ecdh->ec->key.dp->size;
> +	ecc_point *point = NULL;
> +
> +	pubkey = wpabuf_alloc(key_len + 1);
> +	if (!pubkey)
> +		goto fail;
> +	wpabuf_put_u8(pubkey, inc_y ? 0x04 : 0x02);
> +	wpabuf_put_data(pubkey, key, key_len);
> +
> +	point = wc_ecc_new_point();
> +	if (!point)
> +		goto fail;
> +
> +	ret = wc_ecc_import_point_der(wpabuf_put(pubkey, key_len + 1), key_len,
> +				      ecdh->ec->key.dp->id, point);
> +	if (ret != MP_OKAY)
> +		goto fail;
> +
> +	secret = wpabuf_alloc(key_len);
> +	if (!secret)
> +		goto fail;
> +
> +	ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
> +				      (byte*)wpabuf_put(secret, key_len),
> +				      &key_len);
> +	if (ret != MP_OKAY)
> +		goto fail;
> +
> +done:
> +	wc_ecc_del_point(point);
> +	wpabuf_free(pubkey);
> +	return secret;
> +fail:
> +	wpabuf_free(secret);
> +	secret = NULL;
> +	goto done;
> +}
> +
> +
> #endif /* CONFIG_ECC */
> diff --git a/src/crypto/fips_prf_wolfssl.c b/src/crypto/fips_prf_wolfssl.c
> index 1709932..feb39db 100644
> --- a/src/crypto/fips_prf_wolfssl.c
> +++ b/src/crypto/fips_prf_wolfssl.c
> @@ -7,6 +7,7 @@
>  */
> 
> #include "includes.h"
> +#include <wolfssl/options.h>
> #include <wolfssl/wolfcrypt/sha.h>
> 
> #include "common.h"
> @@ -15,7 +16,7 @@
> 
> static void sha1_transform(u32 *state, const u8 data[64])
> {
> -	Sha sha;
> +	wc_Sha sha;
> 
> 	os_memset(&sha, 0, sizeof(sha));
> 	sha.digest[0] = state[0];
> diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
> index b7c452e..82ced39 100644
> --- a/src/crypto/tls_wolfssl.c
> +++ b/src/crypto/tls_wolfssl.c
> @@ -10,24 +10,16 @@
> 
> #include "common.h"
> #include "crypto.h"
> +#include "sha1.h"
> #include "tls.h"
> 
> -#define OPENSSL_EXTRA
> -#define HAVE_STUNNEL
> -#define HAVE_SECRET_CALLBACK
> -#define HAVE_SESSION_TICKET
> -#define HAVE_OCSP
> -#define HAVE_CERTIFICATE_STATUS_REQUEST
> -#define HAVE_CERTIFICATE_STATUS_REQUEST_V2
> -#ifndef WOLFSSL_DER_LOAD
> -#define WOLFSSL_DER_LOAD
> -#endif
> -#if 0
> -/* Enable if a debug build of wolfSSL is installed. */
> -#define DEBUG_WOLFSSL
> -#endif
> +/* sha256.h is a wolfSSL header file. */
> +extern void tls_prf_sha256(const u8 *secret, size_t secret_len,
> +			   const char *label, const u8 *seed, size_t seed_len,
> +			   u8 *out, size_t outlen);
> 
> /* wolfSSL includes */
> +#include <wolfssl/options.h>
> #include <wolfssl/ssl.h>
> #include <wolfssl/error-ssl.h>
> #include <wolfssl/wolfcrypt/asn.h>
> @@ -470,9 +462,9 @@ static int tls_connection_client_cert(struct tls_connection *conn,
> 		return 0;
> 
> 	if (client_cert_blob) {
> -		if (wolfSSL_use_certificate_buffer(conn->ssl, client_cert_blob,
> -						   blob_len,
> -						   SSL_FILETYPE_ASN1) < 0) {
> +		if (wolfSSL_use_certificate_chain_buffer_format(conn->ssl,
> +			    client_cert_blob, blob_len,
> +			    SSL_FILETYPE_ASN1) < 0) {
> 			wpa_printf(MSG_INFO,
> 				   "SSL: use client cert DER blob failed");
> 			return -1;
> @@ -482,11 +474,11 @@ static int tls_connection_client_cert(struct tls_connection *conn,
> 	}
> 
> 	if (client_cert) {
> -		if (wolfSSL_use_certificate_file(conn->ssl, client_cert,
> -						 SSL_FILETYPE_PEM) < 0) {
> +		if (wolfSSL_use_certificate_chain_file(conn->ssl,
> +						       client_cert) < 0) {
> 			wpa_printf(MSG_INFO,
> 				   "SSL: use client cert PEM file failed");
> -			if (wolfSSL_use_certificate_file(
> +			if (wolfSSL_use_certificate_chain_file_format(
> 				    conn->ssl, client_cert,
> 				    SSL_FILETYPE_ASN1) < 0) {
> 				wpa_printf(MSG_INFO,
> @@ -577,10 +569,6 @@ static int tls_connection_private_key(void *tls_ctx,
> }
> 
> 
> -#define GEN_EMAIL	1
> -#define GEN_DNS		ALT_NAMES_OID
> -#define GEN_URI		6
> -
> static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
> 					   const char *value, size_t len)
> {
> @@ -590,7 +578,6 @@ static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
> 	int i;
> 
> 	ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
> -
> 	for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
> 		gen = wolfSSL_sk_value(ext, i);
> 		if (gen->type != type)
> @@ -893,19 +880,16 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
> 		if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
> 			break;
> 		gen = wolfSSL_sk_value((void *) ext, i);
> -#if 0
> 		if (gen->type != GEN_EMAIL &&
> 		    gen->type != GEN_DNS &&
> 		    gen->type != GEN_URI)
> 			continue;
> -#endif
> 
> 		pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
> 		if (!pos)
> 			break;
> 		alt_subject[num_alt_subject++] = pos;
> 
> -#if 0
> 		switch (gen->type) {
> 		case GEN_EMAIL:
> 			os_memcpy(pos, "EMAIL:", 6);
> @@ -920,10 +904,6 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
> 			pos += 4;
> 			break;
> 		}
> -#else
> -		os_memcpy(pos, "DNS:", 4);
> -		pos += 4;
> -#endif
> 
> 		os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
> 		pos += os_strlen((char *)gen->obj);
> @@ -1099,7 +1079,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
> 				       TLS_FAIL_SERVER_CHAIN_PROBE);
> 	}
> 
> -#ifdef HAVE_OCSP_OPENSSL
> +#ifdef HAVE_OCSP_WOLFSSL
> 	if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
> 	    preverify_ok) {
> 		enum ocsp_result res;
> @@ -1123,7 +1103,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
> 					       TLS_FAIL_UNSPECIFIED);
> 		}
> 	}
> -#endif /* HAVE_OCSP */
> +#endif /* HAVE_OCSP_WOLFSSL */
> 	if (depth == 0 && preverify_ok && context->event_cb != NULL)
> 		context->event_cb(context->cb_ctx,
> 				  TLS_CERT_CHAIN_SUCCESS, NULL);
> @@ -1204,7 +1184,6 @@ static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
> 			return -1;
> 		}
> 		wolfSSL_CTX_set_cert_store(ctx, cm);
> -		XFREE(cm, NULL, DYNAMIC_TYPE_X509_STORE);
> 
> 		if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
> 		    SSL_SUCCESS) {
> @@ -1370,11 +1349,11 @@ static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
> 	if (!client_cert)
> 		return 0;
> 
> -	if (wolfSSL_CTX_use_certificate_file(ctx, client_cert,
> -					     SSL_FILETYPE_ASN1) !=
> +	if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
> +							  SSL_FILETYPE_ASN1) !=
> 	    SSL_SUCCESS &&
> -	    wolfSSL_CTX_use_certificate_file(ctx, client_cert,
> -					     SSL_FILETYPE_PEM) != SSL_SUCCESS) {
> +	    wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
> +	    SSL_SUCCESS) {
> 		wpa_printf(MSG_INFO, "Failed to load client certificate");
> 		return -1;
> 	}
> @@ -1988,18 +1967,58 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
> }
> 
> 
> +#define SEED_LEN	(RAN_LEN + RAN_LEN)
> +
> int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
> 				    u8 *out, size_t out_len)
> {
> -	int ret;
> +	byte seed[SEED_LEN];
> +	int ret = -1;
> +	WOLFSSL *ssl;
> +	byte *tmp_out = NULL;
> +	byte *_out;
> +	int skip = 0;
> +	byte *master_key;
> +	unsigned int master_key_len;
> +	byte *server_random;
> +	unsigned int server_len;
> +	byte *client_random;
> +	unsigned int client_len;
> 
> 	if (!conn || !conn->ssl)
> 		return -1;
> +	ssl = conn->ssl;
> 
> -	ret = wolfSSL_make_eap_keys(conn->ssl, out, out_len, "key expansion");
> -	if (ret != 0)
> +	skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
> +		    wolfSSL_GetIVSize(ssl));
> +
> +	tmp_out = os_malloc(skip + out_len);
> +	if (!tmp_out)
> 		return -1;
> -	return 0;
> +	_out = tmp_out;
> +
> +	wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
> +			 &server_len, &client_random, &client_len);
> +	XMEMCPY(seed          , server_random, RAN_LEN);
> +	XMEMCPY(seed + RAN_LEN, client_random, RAN_LEN);
> +
> +	if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
> +		tls_prf_sha256(master_key, master_key_len,
> +			       "key expansion", seed, sizeof(seed),
> +			       _out, skip + out_len);
> +		ret = 0;
> +	} else if (tls_prf_sha1_md5(master_key, master_key_len,
> +				    "key expansion", seed, sizeof(seed),
> +				    _out, skip + out_len) == 0) {
> +		ret = 0;
> +	}
> +
> +	os_memset(master_key, 0, master_key_len);
> +	if (ret == 0)
> +		os_memcpy(out, _out + skip, out_len);
> +	bin_clear_free(tmp_out, skip);
> +
> +	return ret;
> }
> 
> 
> @@ -2037,14 +2056,14 @@ static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
> 				      sizeof(client_random)) == 0 ||
> 	    wolfSSL_get_server_random(s, server_random,
> 				      sizeof(server_random)) == 0 ||
> -	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticketLen) != 1)
> +	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticket_len) != 1)
> 		return 1;
> 
> 	if (ticket_len == 0)
> 		return 0;
> 
> 	ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
> -				      conn->session_ticket, ticketLen,
> +				      conn->session_ticket, ticket_len,
> 				      client_random, server_random, secret);
> 	if (ret <= 0)
> 		return 1;
> diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
> index 88041ca..804cbca 100644
> --- a/tests/hwsim/test_ap_eap.py
> +++ b/tests/hwsim/test_ap_eap.py
> @@ -4115,7 +4115,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca(dev, apdev, params):
>     params["private_key"] = "auth_serv/iCA-server/server.key"
>     hostapd.add_ap(apdev[0], params)
>     tls = dev[0].request("GET tls_library")
> -    if "GnuTLS" in tls:
> +    if "GnuTLS" in tls or "wolfSSL" in tls:
>         ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
>         client_cert = "auth_serv/iCA-user/user_and_ica.pem"
>     else:
> @@ -4223,7 +4223,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md):
>     try:
>         hostapd.add_ap(apdev[0], params)
>         tls = dev[0].request("GET tls_library")
> -        if "GnuTLS" in tls:
> +        if "GnuTLS" in tls or "wolfSSL" in tls:
>             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
>             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
>         else:
> @@ -4258,7 +4258,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked(dev, apdev, params, md):
>     try:
>         hostapd.add_ap(apdev[0], params)
>         tls = dev[0].request("GET tls_library")
> -        if "GnuTLS" in tls:
> +        if "GnuTLS" in tls or "wolfSSL" in tls:
>             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
>             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
>         else:
> @@ -4308,7 +4308,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi_missing_resp(dev, apdev, par
>     try:
>         hostapd.add_ap(apdev[0], params)
>         tls = dev[0].request("GET tls_library")
> -        if "GnuTLS" in tls:
> +        if "GnuTLS" in tls or "wolfSSL" in tls:
>             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
>             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
>         else:
> @@ -4375,7 +4375,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi(dev, apdev, params):
> 
>         hostapd.add_ap(apdev[0], params)
>         tls = dev[0].request("GET tls_library")
> -        if "GnuTLS" in tls:
> +        if "GnuTLS" in tls or "wolfSSL" in tls:
>             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
>             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
>         else:
> diff --git a/tests/hwsim/test_eap_proto.py b/tests/hwsim/test_eap_proto.py
> index d97a6f1..2ff6743 100644
> --- a/tests/hwsim/test_eap_proto.py
> +++ b/tests/hwsim/test_eap_proto.py
> @@ -5124,7 +5124,7 @@ def test_eap_proto_ikev2(dev, apdev):
> 
>         def build_ke(next=0):
>             ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
> -            ke += 192*'\x00'
> +            ke += 191*'\x00'+'\x02'
>             return ke
> 
>         idx += 1
> diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
> index c761c22..eca20a9 100644
> --- a/wpa_supplicant/Makefile
> +++ b/wpa_supplicant/Makefile
> @@ -1067,6 +1067,7 @@ OBJS_p += ../src/crypto/crypto_wolfssl.o
> ifdef NEED_FIPS186_2_PRF
> OBJS += ../src/crypto/fips_prf_wolfssl.o
> endif
> +NEED_TLS_PRF_SHA256=y
> LIBS += -lwolfssl -lm
> LIBS_p += -lwolfssl -lm
> endif
> -- 
> 1.9.1
>> On 4 Mar 2018, at 5:19 am, Jouni Malinen <j at w1.fi> wrote:
>> 
>> On Thu, Jan 18, 2018 at 12:26:39PM +1000, Sean Parkinson wrote:
>>> I?ve prepared a new patch with the changes as asked for by Jouni.
>>> 
>>> This patch was written to allow hostap to be compiled with the wolfSSL cryptography and TLS library.
>> 
>> Thanks! I'm seeing number of errors in the hwsim test cases, but it
>> looks like it is easiest to move ahead with this if I push in the
>> cleaned up version that I've been testing with some fixes to avoid
>> breaking non-wolfSSL builds. I'd welcome any incremental changes on top
>> of the current hostap.git master branch snapshot to address things that
>> I list below or maybe a recommendation on how to configure the wolfSSL
>> build properly to avoid the issues. I ran my tests with wolfSSL 3.13.0
>> and ended up adding various configure options until the build went
>> through cleanly. This ended up with following options:
>> 
>> ./configure --prefix=/home/jm/wolfssl/3.13.0 --enable-des3 --enable-md4 --enable-harden --enable-pwdbased --enable-tlsv10 --enable-oldtls --enable-cmac --enable-aeskeywrap --enable-keygen --enable-crl --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 --enable-pkcallbacks --enable-tls13 --enable-fortress --enable-wpas --enable-static=yes --enable-shared=no
>> 
>> 
>> These are the notes from my hwsim test runs:
>> 
>> SAE:
>> - SAE: Could not solve y
>> - SAE: Could not pick PWE
>> --> check crypto_ec_point_solve_y_coord() implementation
>>  (wc_ecc_import_point_der() returns -1)
>> sae
>> sae_anti_clogging
>> sae_anti_clogging_proto
>> sae_bignum_failure
>> sae_forced_anti_clogging
>> sae_group_nego
>> sae_groups
>> sae_invalid_anti_clogging_token_req
>> sae_key_lifetime_in_memory
>> sae_mixed
>> sae_mixed_mfp
>> sae_no_random
>> sae_oom_wpas
>> sae_password
>> sae_password_ecc
>> sae_password_long
>> sae_password_short
>> sae_pmksa_caching
>> sae_pmksa_caching_disabled
>> sae_proto_confirm_replay
>> sae_proto_ecc
>> sae_pwe_failure
>> ap_ft_sae
>> ap_ft_sae_over_ds
>> sigma_dut_ap_psk_sae
>> sigma_dut_ap_sae
>> sigma_dut_ap_sae_group
>> sigma_dut_ap_sae_password
>> sigma_dut_sae
>> sigma_dut_sae_password
>> wpas_mesh_password_mismatch
>> mesh_forwarding_secure
>> ap_mixed_security
>> 
>> 
>> TLS interop(?) issue with OpenSSL server:
>> - OpenSSL server:
>> * SSL: SSL3 alert: write (local SSL3 detected an error):fatal:bad record mac
>> * SSL: SSL_accept:error in SSLv3 read finished A
>> * OpenSSL: openssl_handshake - SSL_connect error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
>> ap_hs20_remediation_sql
>> eap_tls_no_session_resumption_radius
>> authsrv_testing_options
>> ap_wpa2_eap_tls_versions
>> 
>> 
>> OpenSSL authentication server:
>> - OpenSSL: openssl_handshake - SSL_connect error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
>> ap_wpa2_eap_ttls_dh_params
>> ap_wpa2_eap_ttls_dh_params_blob
>> ap_wpa2_eap_ttls_dh_params_dsa
>> 
>> 
>> OpenSSL authentication server:
>> - TLS: Certificate verification failed, error 20 (unable to get local issuer certificate) depth 0 for '/C=FI/O=w1.fi/CN=user.w1.fi'
>> - SSL: SSL3 alert: write (local SSL3 detected an error):fatal:unknown CA
>> - OpenSSL: openssl_handshake - SSL_connect error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
>> ap_wpa2_eap_tls_intermediate_ca
>> ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1
>> ap_wpa2_eap_tls_intermediate_ca_ocsp
>> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked
>> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked_sha1
>> 
>> 
>> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
>> TLS: altSubjectName match 'EMAIL:noone at example.com;DNS:server.w1.fi;URI:http://example.com/' not found
>> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
>> ap_wpa2_eap_ttls_pap_subject_match
>> 
>> 
>> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
>> TLS: altSubjectName match 'EMAIL:noone at example.com;URI:http://example.com/;DNS:server.w1.fi' not found
>> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
>> ap_wpa2_eap_ttls_chap_altsubject_match
>> 
>> 
>> TLS: Certificate verification failed, error -407 (Invalid OCSP Status Error) depth 2 for '/C=FI/O=w1.fi/CN=server.w1.fi'
>> ap_wpa2_eap_ttls_ocsp_revoked
>> ap_wpa2_eap_ttls_ocsp_unknown
>> ap_wpa2_eap_ttls_optional_ocsp_unknown
>> 
>> 
>> Missing altsubject in D-Bus output?!
>> dbus_connect_eap
>> 
>> 
>> DH: crypto_dh_derive_secret failed
>> eap_proto_ikev2
>> 
>> 
>> TLS: Certificate verification failed, error -238 (ASN CA path length larger than signer error) depth 2 for '/C=FI/O=w1.fi/CN=sha384.server.w1.fi'
>> eap_tls_sha384
>> eap_tls_sha512
>> 
>> 
>> 
>> GET_FAIL/GET_ALLOC_FAIL failure did not trigger:
>> radius_mppe_failure
>> authsrv_oom
>> 
>> 
>> -- 
>> Jouni Malinen                                            PGP id EFC895FA
>> 
>> _______________________________________________
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap
> 
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap



From j at w1.fi  Fri Mar 30 06:31:48 2018
From: j at w1.fi (Jouni Malinen)
Date: Fri, 30 Mar 2018 16:31:48 +0300
Subject: [PATCH v2] wpa_supplicant: fix auth failure when the MAC is
 updated externally
In-Reply-To: <20180215105001.19229-1-bgalvani@redhat.com>
References: <20180215105001.19229-1-bgalvani@redhat.com>
Message-ID: <20180330133148.GA19524@w1.fi>

On Thu, Feb 15, 2018 at 11:50:01AM +0100, Beniamino Galvani wrote:
> 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):
...
> 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.

Thanks, applied.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Fri Mar 30 06:31:48 2018
From: j at w1.fi (Jouni Malinen)
Date: Fri, 30 Mar 2018 16:31:48 +0300
Subject: [PATCH v2] wpa_supplicant: fix auth failure when the MAC is
 updated externally
In-Reply-To: <20180215105001.19229-1-bgalvani@redhat.com>
References: <20180215105001.19229-1-bgalvani@redhat.com>
Message-ID: <20180330133148.GA19524@w1.fi>

On Thu, Feb 15, 2018 at 11:50:01AM +0100, Beniamino Galvani wrote:
> 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):
...
> 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.

Thanks, applied.

-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Fri Mar 30 06:32:03 2018
From: j at w1.fi (Jouni Malinen)
Date: Fri, 30 Mar 2018 16:32:03 +0300
Subject: [PATCH 2/2] nl80211: add nl80211 DFS offload support
In-Reply-To: <20180324075427.3323-3-lebed.dmitry@gmail.com>
References: <20180324075427.3323-1-lebed.dmitry@gmail.com>
 <20180324075427.3323-3-lebed.dmitry@gmail.com>
Message-ID: <20180330133203.GB19524@w1.fi>

On Sat, Mar 24, 2018 at 10:54:27AM +0300, Dmitry Lebed wrote:
> Add generic DFS offload support.
> DFS_OFFLOAD ext_feature and CAC_STARTED event handling implemented.

Thanks, applied.
 
-- 
Jouni Malinen                                            PGP id EFC895FA


From j at w1.fi  Fri Mar 30 06:32:16 2018
From: j at w1.fi (Jouni Malinen)
Date: Fri, 30 Mar 2018 16:32:16 +0300
Subject: [PATCH] - Add definitions for RADIUS attributes standardised in
 RFC 7055.
In-Reply-To: <e09aa34d-c816-9e34-8f4f-5677e9313fae@um.es>
References: <e09aa34d-c816-9e34-8f4f-5677e9313fae@um.es>
Message-ID: <20180330133216.GC19524@w1.fi>

On Tue, Mar 27, 2018 at 11:50:48PM +0200, Alejandro P?rez M?ndez wrote:
> ??? Add definitions for RADIUS attributes standardised in RFC 7055.
> 
> ??? hostap code is used by the Moonshot software (an implementation of the
> ??? GSS EAP mechanism - RFC 7055), and those definitions are required
> ??? but missing.

Thanks, applied.

-- 
Jouni Malinen                                            PGP id EFC895FA


