]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Add API to set the PMK to the driver
authorAvraham Stern <avraham.stern@intel.com>
Sun, 28 Jan 2018 12:45:34 +0000 (14:45 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 17 Feb 2018 16:36:16 +0000 (18:36 +0200)
Add support for setting the PMK to the driver. This is used for
drivers that support 4-way handshake offload.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
src/drivers/driver_nl80211.c

index 50c472de7360d14ee803d4712ce8631e4bf49794..b7fcbc6dc981284071e930173e99bd4d6785f84e 100644 (file)
@@ -2812,6 +2812,44 @@ static int issue_key_mgmt_set_key(struct wpa_driver_nl80211_data *drv,
 #endif /* CONFIG_DRIVER_NL80211_QCA */
 
 
+static int nl80211_set_pmk(struct wpa_driver_nl80211_data *drv,
+                          const u8 *key, size_t key_len,
+                          const u8 *addr)
+{
+       struct nl_msg *msg = NULL;
+       int ret;
+
+       /*
+        * If the authenticator address is not set, assume it is
+        * the current BSSID.
+        */
+       if (!addr && drv->associated)
+               addr = drv->bssid;
+       else if (!addr)
+               return -1;
+
+       wpa_printf(MSG_DEBUG, "nl80211: Set PMK to the driver for " MACSTR,
+                  MAC2STR(addr));
+       wpa_hexdump_key(MSG_DEBUG, "nl80211: PMK", key, key_len);
+       msg = nl80211_drv_msg(drv, 0, NL80211_CMD_SET_PMK);
+       if (!msg ||
+           nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
+           nla_put(msg, NL80211_ATTR_PMK, key_len, key)) {
+               nl80211_nlmsg_clear(msg);
+               nlmsg_free(msg);
+               return -ENOBUFS;
+       }
+
+       ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1);
+       if (ret) {
+               wpa_printf(MSG_DEBUG, "nl80211: Set PMK failed: ret=%d (%s)",
+                          ret, strerror(-ret));
+       }
+
+       return ret;
+}
+
+
 static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
                                      enum wpa_alg alg, const u8 *addr,
                                      int key_idx, int set_tx,
@@ -2850,6 +2888,10 @@ static int wpa_driver_nl80211_set_key(const char *ifname, struct i802_bss *bss,
        }
 #endif /* CONFIG_DRIVER_NL80211_QCA */
 
+       if (alg == WPA_ALG_PMK &&
+           (drv->capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
+               return nl80211_set_pmk(drv, key, key_len, addr);
+
        if (alg == WPA_ALG_NONE) {
                msg = nl80211_ifindex_msg(drv, ifindex, 0, NL80211_CMD_DEL_KEY);
                if (!msg)