@@ -2846,6 +2846,8 @@ struct cfg80211_pmk_conf {
* the real status code for failures. Used only for the authentication
* response command interface (user space to driver).
* @pmkid: The identifier to refer a PMKSA.
+ * @pmk_len: Length of PMK if present.
+ * @pmk: Derived PMK
*/
struct cfg80211_external_auth_params {
enum nl80211_external_auth_action action;
@@ -2854,6 +2856,8 @@ struct cfg80211_external_auth_params {
unsigned int key_mgmt_suite;
u16 status;
const u8 *pmkid;
+ int pmk_len;
+ const u8 *pmk;
};
/**
@@ -1022,7 +1022,9 @@
* further with the association after getting successful authentication
* status. User space indicates the authentication status through
* %NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
- * command interface.
+ * command interface. In case of success, user space also includes the
+ * derived PMK and PMKID through %NL80211_ATTR_PMK and
+ * %NL80211_ATTR_PMKID.
*
* Host driver reports this status on an authentication failure to the
* user space through the connect result as the user space would have
@@ -13098,6 +13098,12 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NL80211_ATTR_STATUS_CODE])
return -EINVAL;
+ if ((info->attrs[NL80211_ATTR_PMK] &&
+ !info->attrs[NL80211_ATTR_PMKID]) ||
+ (info->attrs[NL80211_ATTR_PMKID] &&
+ !info->attrs[NL80211_ATTR_PMK]))
+ return -EINVAL;
+
memset(¶ms, 0, sizeof(params));
if (info->attrs[NL80211_ATTR_SSID]) {
@@ -13115,8 +13121,13 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
- if (info->attrs[NL80211_ATTR_PMKID])
+ if (info->attrs[NL80211_ATTR_PMKID]) {
+ if (info->attrs[NL80211_ATTR_PMK]) {
+ params.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
+ params.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
+ }
params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
+ }
return rdev_external_auth(rdev, dev, ¶ms);
}