3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-21 03:32:42 +01:00

wiphy: added wiphy_select_akm

This is a replacement for station's static select_akm_suite. This was
done because wiphy can make a much more intellegent decision about the
akm suite by checking the wiphy supported features e.g. SAE support.

This allows a connection to hybrid WPA2/WPA3 AP's if SAE is not
supported in the kernel.
This commit is contained in:
James Prestwood 2018-09-24 14:29:53 -07:00 committed by Denis Kenzior
parent 272cb441cd
commit 50acc11f07
3 changed files with 59 additions and 45 deletions

View File

@ -358,48 +358,6 @@ void station_set_scan_results(struct station *station, struct l_queue *bss_list,
l_queue_destroy(old_bss_list, bss_free); l_queue_destroy(old_bss_list, bss_free);
} }
static enum ie_rsn_akm_suite select_akm_suite(struct network *network,
struct scan_bss *bss,
struct ie_rsn_info *info)
{
enum security security = network_get_security(network);
/*
* If FT is available, use FT authentication to keep the door open
* for fast transitions. Otherwise use SHA256 version if present.
*/
if (security == SECURITY_8021X) {
if ((info->akm_suites & IE_RSN_AKM_SUITE_FT_OVER_8021X) &&
bss->rsne && bss->mde_present)
return IE_RSN_AKM_SUITE_FT_OVER_8021X;
if (info->akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256)
return IE_RSN_AKM_SUITE_8021X_SHA256;
if (info->akm_suites & IE_RSN_AKM_SUITE_8021X)
return IE_RSN_AKM_SUITE_8021X;
} else if (security == SECURITY_PSK) {
if (info->akm_suites & IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256)
return IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256;
if (info->akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256)
return IE_RSN_AKM_SUITE_SAE_SHA256;
if ((info->akm_suites & IE_RSN_AKM_SUITE_FT_USING_PSK) &&
bss->rsne && bss->mde_present)
return IE_RSN_AKM_SUITE_FT_USING_PSK;
if (info->akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256)
return IE_RSN_AKM_SUITE_PSK_SHA256;
if (info->akm_suites & IE_RSN_AKM_SUITE_PSK)
return IE_RSN_AKM_SUITE_PSK;
}
return 0;
}
static void station_handshake_event(struct handshake_state *hs, static void station_handshake_event(struct handshake_state *hs,
enum handshake_event event, enum handshake_event event,
void *event_data, void *user_data) void *event_data, void *user_data)
@ -451,7 +409,7 @@ static int station_build_handshake_rsn(struct handshake_state *hs,
memset(&bss_info, 0, sizeof(bss_info)); memset(&bss_info, 0, sizeof(bss_info));
scan_bss_get_rsn_info(bss, &bss_info); scan_bss_get_rsn_info(bss, &bss_info);
info.akm_suites = select_akm_suite(network, bss, &bss_info); info.akm_suites = wiphy_select_akm(wiphy, bss);
if (!info.akm_suites) if (!info.akm_suites)
goto not_supported; goto not_supported;

View File

@ -2,7 +2,7 @@
* *
* Wireless daemon for Linux * Wireless daemon for Linux
* *
* Copyright (C) 2013-2014 Intel Corporation. All rights reserved. * Copyright (C) 2013-2018 Intel Corporation. All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -44,6 +44,7 @@
#include "src/wiphy.h" #include "src/wiphy.h"
#include "src/storage.h" #include "src/storage.h"
#include "src/util.h" #include "src/util.h"
#include "src/common.h"
static struct l_genl_family *nl80211 = NULL; static struct l_genl_family *nl80211 = NULL;
static struct l_hwdb *hwdb; static struct l_hwdb *hwdb;
@ -91,6 +92,59 @@ enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy, uint16_t mask)
return 0; return 0;
} }
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
struct scan_bss *bss)
{
struct ie_rsn_info info;
enum security security;
memset(&info, 0, sizeof(info));
scan_bss_get_rsn_info(bss, &info);
security = security_determine(bss->capability, &info);
/*
* If FT is available, use FT authentication to keep the door open
* for fast transitions. Otherwise use SHA256 version if present.
*/
if (security == SECURITY_8021X) {
if ((info.akm_suites & IE_RSN_AKM_SUITE_FT_OVER_8021X) &&
bss->rsne && bss->mde_present)
return IE_RSN_AKM_SUITE_FT_OVER_8021X;
if (info.akm_suites & IE_RSN_AKM_SUITE_8021X_SHA256)
return IE_RSN_AKM_SUITE_8021X_SHA256;
if (info.akm_suites & IE_RSN_AKM_SUITE_8021X)
return IE_RSN_AKM_SUITE_8021X;
} else if (security == SECURITY_PSK) {
/*
* Prefer connecting to SAE/WPA3 network, but only if SAE is
* supported. This allows us to connect to a hybrid WPA2/WPA3
* AP even if SAE/WPA3 is not supported.
*/
if (info.akm_suites & IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256 &&
wiphy_has_feature(wiphy, NL80211_FEATURE_SAE))
return IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256;
if (info.akm_suites & IE_RSN_AKM_SUITE_SAE_SHA256 &&
wiphy_has_feature(wiphy, NL80211_FEATURE_SAE))
return IE_RSN_AKM_SUITE_SAE_SHA256;
if ((info.akm_suites & IE_RSN_AKM_SUITE_FT_USING_PSK) &&
bss->rsne && bss->mde_present)
return IE_RSN_AKM_SUITE_FT_USING_PSK;
if (info.akm_suites & IE_RSN_AKM_SUITE_PSK_SHA256)
return IE_RSN_AKM_SUITE_PSK_SHA256;
if (info.akm_suites & IE_RSN_AKM_SUITE_PSK)
return IE_RSN_AKM_SUITE_PSK;
}
return 0;
}
static void wiphy_free(void *data) static void wiphy_free(void *data)
{ {
struct wiphy *wiphy = data; struct wiphy *wiphy = data;

View File

@ -2,7 +2,7 @@
* *
* Wireless daemon for Linux * Wireless daemon for Linux
* *
* Copyright (C) 2013-2014 Intel Corporation. All rights reserved. * Copyright (C) 2013-2018 Intel Corporation. All rights reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -28,6 +28,8 @@ struct scan_bss;
enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy, enum ie_rsn_cipher_suite wiphy_select_cipher(struct wiphy *wiphy,
uint16_t mask); uint16_t mask);
enum ie_rsn_akm_suite wiphy_select_akm(struct wiphy *wiphy,
struct scan_bss *bss);
struct wiphy *wiphy_find(int wiphy_id); struct wiphy *wiphy_find(int wiphy_id);