mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
ap: add profile settings PairwiseCiphers/GroupCipher
These can now be optionally provided in an AP profile and provide a way to limit what ciphers can be chosen. This still is dependent on what the hardware supports.
This commit is contained in:
parent
5f84a78638
commit
262685e818
89
src/ap.c
89
src/ap.c
@ -3132,12 +3132,38 @@ static bool ap_load_psk(struct ap_state *ap, const struct l_settings *config)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: only PTK/GTK ciphers are supported here since this is all these are
|
||||
* used for.
|
||||
*/
|
||||
static enum ie_rsn_cipher_suite ap_string_to_cipher(const char *str)
|
||||
{
|
||||
if (!strcmp(str, "UseGroupCipher"))
|
||||
return IE_RSN_CIPHER_SUITE_USE_GROUP_CIPHER;
|
||||
else if (!strcmp(str, "TKIP"))
|
||||
return IE_RSN_CIPHER_SUITE_TKIP;
|
||||
else if (!strcmp(str, "CCMP-128") || !strcmp(str, "CCMP"))
|
||||
return IE_RSN_CIPHER_SUITE_CCMP;
|
||||
else if (!strcmp(str, "GCMP-128") || !strcmp(str, "GCMP"))
|
||||
return IE_RSN_CIPHER_SUITE_GCMP;
|
||||
else if (!strcmp(str, "GCMP-256"))
|
||||
return IE_RSN_CIPHER_SUITE_GCMP_256;
|
||||
else if (!strcmp(str, "CCMP-256"))
|
||||
return IE_RSN_CIPHER_SUITE_CCMP_256;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
||||
bool *out_cck_rates)
|
||||
{
|
||||
struct wiphy *wiphy = netdev_get_wiphy(ap->netdev);
|
||||
size_t len;
|
||||
L_AUTO_FREE_VAR(char *, strval) = NULL;
|
||||
_auto_(l_strv_free) char **ciphers_str = NULL;
|
||||
uint16_t cipher_mask;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
strval = l_settings_get_string(config, "General", "SSID");
|
||||
if (L_WARN_ON(!strval))
|
||||
@ -3212,6 +3238,8 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
||||
l_error("AP [WSC].PrimaryDeviceType format unknown");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
l_free(l_steal_ptr(strval));
|
||||
} else {
|
||||
/* Make ourselves a WFA standard PC by default */
|
||||
ap->wsc_primary_device_type.category = 1;
|
||||
@ -3260,6 +3288,61 @@ static int ap_load_config(struct ap_state *ap, const struct l_settings *config,
|
||||
} else
|
||||
*out_cck_rates = true;
|
||||
|
||||
cipher_mask = wiphy_get_supported_ciphers(wiphy, IE_GROUP_CIPHERS);
|
||||
|
||||
/* If the config sets a group cipher use that directly */
|
||||
strval = l_settings_get_string(config, "Security", "GroupCipher");
|
||||
if (strval) {
|
||||
enum ie_rsn_cipher_suite cipher = ap_string_to_cipher(strval);
|
||||
|
||||
if (!cipher || !(cipher & cipher_mask)) {
|
||||
l_error("Unsupported or unknown group cipher %s",
|
||||
strval);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ap->group_cipher = cipher;
|
||||
l_free(l_steal_ptr(strval));
|
||||
} else {
|
||||
/* No config override, use CCMP (or TKIP if not supported) */
|
||||
if (cipher_mask & IE_RSN_CIPHER_SUITE_CCMP)
|
||||
ap->group_cipher = IE_RSN_CIPHER_SUITE_CCMP;
|
||||
else
|
||||
ap->group_cipher = IE_RSN_CIPHER_SUITE_TKIP;
|
||||
}
|
||||
|
||||
cipher_mask = wiphy_get_supported_ciphers(wiphy, IE_PAIRWISE_CIPHERS);
|
||||
|
||||
ciphers_str = l_settings_get_string_list(config, "Security",
|
||||
"PairwiseCiphers", ',');
|
||||
for (i = 0; ciphers_str && ciphers_str[i]; i++) {
|
||||
enum ie_rsn_cipher_suite cipher =
|
||||
ap_string_to_cipher(ciphers_str[i]);
|
||||
|
||||
/*
|
||||
* Constrain list to only values in both supported ciphers and
|
||||
* the cipher list provided.
|
||||
*/
|
||||
if (!cipher || !(cipher & cipher_mask)) {
|
||||
l_error("Unsupported or unknown pairwise cipher %s",
|
||||
ciphers_str[i]);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ap->ciphers |= cipher;
|
||||
}
|
||||
|
||||
if (!ap->ciphers) {
|
||||
/*
|
||||
* Default behavior if no ciphers are specified, disable TKIP
|
||||
* for security if CCMP is available
|
||||
*/
|
||||
if (cipher_mask & IE_RSN_CIPHER_SUITE_CCMP)
|
||||
cipher_mask &= ~IE_RSN_CIPHER_SUITE_TKIP;
|
||||
|
||||
ap->ciphers = cipher_mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3302,12 +3385,6 @@ struct ap_state *ap_start(struct netdev *netdev, struct l_settings *config,
|
||||
|
||||
err = -EINVAL;
|
||||
|
||||
/* TODO: Add all ciphers supported by wiphy */
|
||||
ap->ciphers = wiphy_select_cipher(wiphy, IE_RSN_CIPHER_SUITE_TKIP |
|
||||
IE_RSN_CIPHER_SUITE_CCMP);
|
||||
ap->group_cipher = wiphy_select_cipher(wiphy,
|
||||
IE_RSN_CIPHER_SUITE_TKIP |
|
||||
IE_RSN_CIPHER_SUITE_CCMP);
|
||||
ap->beacon_interval = 100;
|
||||
ap->networks = l_queue_new();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user