mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 21:22:37 +01:00
network: Also support SAE PT for group 20
Generalize loading / saving of SAE PTs and add support for saving / loading of ECC group 20 based SAE PT.
This commit is contained in:
parent
a46269d5b0
commit
9c07741a0a
104
src/network.c
104
src/network.c
@ -56,6 +56,8 @@
|
|||||||
#include "src/erp.h"
|
#include "src/erp.h"
|
||||||
#include "src/handshake.h"
|
#include "src/handshake.h"
|
||||||
|
|
||||||
|
#define SAE_PT_SETTING "SAE-PT-Group%u"
|
||||||
|
|
||||||
static uint32_t known_networks_watch;
|
static uint32_t known_networks_watch;
|
||||||
static uint32_t anqp_watch;
|
static uint32_t anqp_watch;
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ struct network {
|
|||||||
unsigned char *psk;
|
unsigned char *psk;
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
struct l_ecc_point *sae_pt_19; /* SAE PT for Group 19 */
|
struct l_ecc_point *sae_pt_19; /* SAE PT for Group 19 */
|
||||||
|
struct l_ecc_point *sae_pt_20; /* SAE PT for Group 20 */
|
||||||
unsigned int agent_request;
|
unsigned int agent_request;
|
||||||
struct l_queue *bss_list;
|
struct l_queue *bss_list;
|
||||||
struct l_settings *settings;
|
struct l_settings *settings;
|
||||||
@ -118,6 +121,11 @@ static void network_reset_passphrase(struct network *network)
|
|||||||
l_ecc_point_free(network->sae_pt_19);
|
l_ecc_point_free(network->sae_pt_19);
|
||||||
network->sae_pt_19 = NULL;
|
network->sae_pt_19 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (network->sae_pt_20) {
|
||||||
|
l_ecc_point_free(network->sae_pt_20);
|
||||||
|
network->sae_pt_20 = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void network_settings_close(struct network *network)
|
static void network_settings_close(struct network *network)
|
||||||
@ -288,18 +296,19 @@ static const uint8_t *network_get_psk(struct network *network)
|
|||||||
return network->psk;
|
return network->psk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void network_generate_sae_pt_19(struct network *network)
|
static struct l_ecc_point *network_generate_sae_pt(struct network *network,
|
||||||
|
unsigned int group)
|
||||||
{
|
{
|
||||||
l_debug("Generating PT for Group 19");
|
struct l_ecc_point *pt;
|
||||||
|
|
||||||
network->sae_pt_19 = crypto_derive_sae_pt_ecc(19, network->ssid,
|
l_debug("Generating PT for Group %u", group);
|
||||||
|
|
||||||
|
pt = crypto_derive_sae_pt_ecc(group, network->ssid,
|
||||||
network->passphrase, NULL);
|
network->passphrase, NULL);
|
||||||
if (!network->sae_pt_19) {
|
if (!pt)
|
||||||
l_warn("SAE PT generation for Group 19 failed");
|
l_warn("SAE PT generation for Group %u failed", group);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
network->sync_settings = true;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool __network_set_passphrase(struct network *network,
|
static bool __network_set_passphrase(struct network *network,
|
||||||
@ -311,7 +320,9 @@ static bool __network_set_passphrase(struct network *network,
|
|||||||
network_reset_passphrase(network);
|
network_reset_passphrase(network);
|
||||||
network->passphrase = l_strdup(passphrase);
|
network->passphrase = l_strdup(passphrase);
|
||||||
|
|
||||||
network_generate_sae_pt_19(network);
|
network->sae_pt_19 = network_generate_sae_pt(network, 19);
|
||||||
|
network->sae_pt_20 = network_generate_sae_pt(network, 20);
|
||||||
|
|
||||||
network->sync_settings = true;
|
network->sync_settings = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -512,6 +523,45 @@ int network_handshake_setup(struct network *network,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int network_settings_load_pt_ecc(struct network *network,
|
||||||
|
const char *path,
|
||||||
|
unsigned int group,
|
||||||
|
struct l_ecc_point **out_pt)
|
||||||
|
{
|
||||||
|
_auto_(l_free) char *key = l_strdup_printf(SAE_PT_SETTING, group);
|
||||||
|
size_t pt_len;
|
||||||
|
_auto_(l_free) uint8_t *pt = l_settings_get_bytes(network->settings,
|
||||||
|
"Security", key, &pt_len);
|
||||||
|
const struct l_ecc_curve *curve = l_ecc_curve_from_ike_group((group));
|
||||||
|
|
||||||
|
if (!curve)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!pt)
|
||||||
|
goto generate;
|
||||||
|
|
||||||
|
if (pt_len != l_ecc_curve_get_scalar_bytes(curve) * 2)
|
||||||
|
goto bad_format;
|
||||||
|
|
||||||
|
*out_pt = l_ecc_point_from_data(curve, L_ECC_POINT_TYPE_FULL,
|
||||||
|
pt, pt_len);
|
||||||
|
if (*out_pt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bad_format:
|
||||||
|
l_error("%s: invalid %s format", path, key);
|
||||||
|
|
||||||
|
generate:
|
||||||
|
if (!network->passphrase)
|
||||||
|
return -ENOKEY;
|
||||||
|
|
||||||
|
*out_pt = network_generate_sae_pt(network, group);
|
||||||
|
if (*out_pt)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
static int network_load_psk(struct network *network, bool need_passphrase)
|
static int network_load_psk(struct network *network, bool need_passphrase)
|
||||||
{
|
{
|
||||||
const char *ssid = network_get_ssid(network);
|
const char *ssid = network_get_ssid(network);
|
||||||
@ -523,10 +573,6 @@ static int network_load_psk(struct network *network, bool need_passphrase)
|
|||||||
_auto_(l_free) char *passphrase =
|
_auto_(l_free) char *passphrase =
|
||||||
l_settings_get_string(network->settings,
|
l_settings_get_string(network->settings,
|
||||||
"Security", "Passphrase");
|
"Security", "Passphrase");
|
||||||
size_t pt19_len;
|
|
||||||
_auto_(l_free) uint8_t *pt19 =
|
|
||||||
l_settings_get_bytes(network->settings, "Security",
|
|
||||||
"SAE-PT-Group19", &pt19_len);
|
|
||||||
_auto_(l_free) char *path =
|
_auto_(l_free) char *path =
|
||||||
storage_get_network_file_path(security, ssid);
|
storage_get_network_file_path(security, ssid);
|
||||||
|
|
||||||
@ -552,29 +598,25 @@ static int network_load_psk(struct network *network, bool need_passphrase)
|
|||||||
network_reset_psk(network);
|
network_reset_psk(network);
|
||||||
network->passphrase = l_steal_ptr(passphrase);
|
network->passphrase = l_steal_ptr(passphrase);
|
||||||
|
|
||||||
if (pt19) {
|
if (network_settings_load_pt_ecc(network, path,
|
||||||
const struct l_ecc_curve *curve =
|
19, &network->sae_pt_19) > 0)
|
||||||
l_ecc_curve_from_ike_group(19);
|
network->sync_settings = true;
|
||||||
|
|
||||||
network->sae_pt_19 = l_ecc_point_from_data(curve,
|
if (network_settings_load_pt_ecc(network, path,
|
||||||
L_ECC_POINT_TYPE_FULL,
|
20, &network->sae_pt_20) > 0)
|
||||||
pt19, pt19_len);
|
network->sync_settings = true;
|
||||||
if (!network->sae_pt_19)
|
|
||||||
l_error("%s: invalid SAE-PT-Group19 format", path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (network->passphrase && !network->sae_pt_19)
|
|
||||||
network_generate_sae_pt_19(network);
|
|
||||||
|
|
||||||
network->psk = l_steal_ptr(psk);
|
network->psk = l_steal_ptr(psk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void network_settings_save_sae_pt(struct l_settings *settings,
|
static void network_settings_save_sae_pt_ecc(struct l_settings *settings,
|
||||||
struct l_ecc_point *pt,
|
struct l_ecc_point *pt)
|
||||||
const char *key)
|
|
||||||
{
|
{
|
||||||
|
const struct l_ecc_curve *curve = l_ecc_point_get_curve(pt);
|
||||||
|
unsigned int group = l_ecc_curve_get_ike_group(curve);
|
||||||
|
_auto_(l_free) char *key = l_strdup_printf(SAE_PT_SETTING, group);
|
||||||
uint8_t buf[256];
|
uint8_t buf[256];
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
@ -618,8 +660,10 @@ void network_sync_settings(struct network *network)
|
|||||||
network->passphrase);
|
network->passphrase);
|
||||||
|
|
||||||
if (network->sae_pt_19)
|
if (network->sae_pt_19)
|
||||||
network_settings_save_sae_pt(settings, network->sae_pt_19,
|
network_settings_save_sae_pt_ecc(settings, network->sae_pt_19);
|
||||||
"SAE-PT-Group19");
|
|
||||||
|
if (network->sae_pt_20)
|
||||||
|
network_settings_save_sae_pt_ecc(settings, network->sae_pt_20);
|
||||||
|
|
||||||
storage_network_sync(SECURITY_PSK, ssid, settings);
|
storage_network_sync(SECURITY_PSK, ssid, settings);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user