3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

unit: Test a EAP-WSC-R setup with WPA2 credentials

This commit is contained in:
Andrew Zaborowski 2020-08-25 00:34:24 +02:00 committed by Denis Kenzior
parent 6f9b087304
commit 3cf8af2431

View File

@ -2261,6 +2261,278 @@ static void wsc_test_pin_generate(const void *data)
} }
} }
struct test_ap_sta_data {
struct handshake_state *ap_hs;
struct handshake_state *sta_hs;
const uint8_t ap_address[6];
const uint8_t sta_address[6];
uint8_t to_sta_data[1024];
int to_sta_data_len;
int to_sta_msg_cnt;
int to_ap_msg_cnt;
struct eapol_sm *ap_sm;
struct eapol_sm *sta_sm;
};
static int test_ap_sta_eapol_tx(uint32_t ifindex,
const uint8_t *dest, uint16_t proto,
const struct eapol_frame *ef,
bool noencrypt, void *user_data)
{
struct test_ap_sta_data *s = user_data;
size_t len = sizeof(struct eapol_header) +
L_BE16_TO_CPU(ef->header.packet_len);
assert(ifindex == s->ap_hs->ifindex || ifindex == s->sta_hs->ifindex);
assert(proto == ETH_P_PAE && !noencrypt);
if (ifindex == s->ap_hs->ifindex) { /* From AP to STA */
assert(!memcmp(dest, s->sta_address, 6));
assert(len < sizeof(s->to_sta_data));
memcpy(s->to_sta_data, ef, len);
s->to_sta_data_len = len;
s->to_sta_msg_cnt++;
return 0;
}
/* From STA to AP */
assert(!memcmp(dest, s->ap_address, 6));
s->to_ap_msg_cnt++;
__eapol_rx_packet(1, s->sta_address, proto, (const void *) ef, len,
noencrypt);
return 0;
}
static void test_ap_sta_run(struct test_ap_sta_data *s)
{
eap_init();
eapol_init();
__eapol_set_tx_packet_func(test_ap_sta_eapol_tx);
__eapol_set_tx_user_data(s);
s->to_sta_msg_cnt = 0;
s->to_ap_msg_cnt = 0;
s->to_sta_data_len = 0;
s->ap_sm = eapol_sm_new(s->ap_hs);
eapol_register(s->ap_sm);
s->sta_sm = eapol_sm_new(s->sta_hs);
eapol_register(s->sta_sm);
eapol_start(s->sta_sm);
eapol_start(s->ap_sm);
while (s->to_sta_data_len) {
int len = s->to_sta_data_len;
s->to_sta_data_len = 0;
__eapol_rx_packet(s->sta_hs->ifindex, s->ap_address, ETH_P_PAE,
s->to_sta_data, len, false);
}
if (s->ap_sm)
eapol_sm_free(s->ap_sm);
if (s->sta_sm)
eapol_sm_free(s->sta_sm);
eapol_exit();
eap_exit();
}
struct test_ap_sta_hs {
struct handshake_state super;
struct test_ap_sta_data *s;
};
static struct handshake_state *test_ap_sta_hs_new(struct test_ap_sta_data *s,
uint32_t ifindex)
{
struct test_ap_sta_hs *ths = l_new(struct test_ap_sta_hs, 1);
ths->super.ifindex = ifindex;
ths->super.free = (void (*)(struct handshake_state *s)) l_free;
ths->s = s;
return &ths->super;
}
static bool random_nonce(uint8_t nonce[])
{
return l_getrandom(nonce, 32);
}
static void test_ap_sta_install_tk(struct handshake_state *hs,
const uint8_t *tk, uint32_t cipher)
{
assert(false);
}
struct wsc_r_test_success_data {
bool credentials_obtained;
bool credentials_sent;
bool ap_eap_failed;
bool sta_eap_failed;
struct test_ap_sta_data *s;
};
static void test_ap_sta_hs_event_ap(struct handshake_state *hs,
enum handshake_event event,
void *user_data, ...)
{
struct wsc_r_test_success_data *data = user_data;
va_list args;
va_start(args, user_data);
switch (event) {
case HANDSHAKE_EVENT_EAP_NOTIFY:
assert(va_arg(args, unsigned int) ==
EAP_WSC_EVENT_CREDENTIAL_SENT);
assert(!data->credentials_sent);
assert(!data->ap_eap_failed);
data->credentials_sent = true;
break;
case HANDSHAKE_EVENT_FAILED:
assert(va_arg(args, int) ==
MMPDU_REASON_CODE_IEEE8021X_FAILED);
assert(!data->ap_eap_failed);
data->ap_eap_failed = true;
data->s->ap_sm = NULL;
break;
default:
break;
}
va_end(args);
}
static void test_ap_sta_hs_event_sta(struct handshake_state *hs,
enum handshake_event event,
void *user_data, ...)
{
struct wsc_r_test_success_data *data = user_data;
va_list args;
va_start(args, user_data);
switch (event) {
case HANDSHAKE_EVENT_EAP_NOTIFY:
{
unsigned int eap_event = va_arg(args, unsigned int);
const struct wsc_credential *cred;
assert(eap_event == EAP_WSC_EVENT_CREDENTIAL_OBTAINED);
cred = va_arg(args, const struct wsc_credential *);
assert(cred->ssid_len == 7 &&
!memcmp(cred->ssid, "thessid", 7));
assert(cred->auth_type ==
WSC_AUTHENTICATION_TYPE_WPA2_PERSONAL);
assert(cred->encryption_type == WSC_ENCRYPTION_TYPE_AES_TKIP);
assert(cred->network_key_len == 12 &&
!memcmp(cred->network_key, "secretsecret", 12));
assert(!memcmp(cred->addr, data->s->sta_address, 6));
assert(!data->credentials_obtained);
assert(!data->sta_eap_failed);
data->credentials_obtained = true;
break;
}
case HANDSHAKE_EVENT_FAILED:
assert(va_arg(args, int) ==
MMPDU_REASON_CODE_IEEE8021X_FAILED);
assert(!data->sta_eap_failed);
data->sta_eap_failed = true;
data->s->sta_sm = NULL;
break;
default:
break;
}
va_end(args);
}
static void wsc_r_test_pbc_handshake_wpa2(const void *data)
{
static const unsigned char ap_rsne[] = {
0x30, 0x12, 0x01, 0x00, 0x00, 0x0f, 0xac, 0x04,
0x01, 0x00, 0x00, 0x0f, 0xac, 0x04, 0x01, 0x00,
0x00, 0x0f, 0xac, 0x02 };
static const char *ssid = "TestWPA2EAP";
static const char *ap_8021x_str = "[Security]\n"
"EAP-Method=WSC-R\n"
"[WSC]\n"
"UUID-R=00112233445566778899aabbccddeeff\n"
"WPA2-SSID=thessid\n"
"WPA2-Passphrase=secretsecret\n"
"RFBand=1\n"
"ConfigurationMethods=0x680\n";
static const char *sta_8021x_str = "[Security]\n"
"EAP-Identity=WFA-SimpleConfig-Enrollee-1-0\n"
"EAP-Method=WSC\n"
"[WSC]\n"
"RFBand=1\n"
"ConfigurationMethods=0x680\n";
struct l_settings *ap_8021x_settings = l_settings_new();
struct l_settings *sta_8021x_settings = l_settings_new();
struct test_ap_sta_data s = {
.ap_hs = test_ap_sta_hs_new(&s, 1),
.sta_hs = test_ap_sta_hs_new(&s, 2),
.ap_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
.sta_address = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x08 },
};
struct wsc_r_test_success_data wsc_data = {
.s = &s,
};
uint8_t uuid_e[16];
L_AUTO_FREE_VAR(char *, uuid_e_str) = NULL;
wsc_uuid_from_addr(s.sta_address, uuid_e);
uuid_e_str = l_util_hexstring(uuid_e, 16);
__handshake_set_get_nonce_func(random_nonce);
__handshake_set_install_tk_func(test_ap_sta_install_tk);
__handshake_set_install_gtk_func(NULL);
handshake_state_set_authenticator(s.ap_hs, true);
handshake_state_set_event_func(s.ap_hs, test_ap_sta_hs_event_ap,
&wsc_data);
handshake_state_set_authenticator_address(s.ap_hs, s.ap_address);
handshake_state_set_supplicant_address(s.ap_hs, s.sta_address);
handshake_state_set_authenticator_ie(s.ap_hs, ap_rsne);
handshake_state_set_ssid(s.ap_hs, (void *) ssid, strlen(ssid));
l_settings_load_from_data(ap_8021x_settings, ap_8021x_str,
strlen(ap_8021x_str));
l_settings_set_string(ap_8021x_settings, "WSC", "EnrolleeMAC",
util_address_to_string(s.sta_address));
l_settings_set_string(ap_8021x_settings, "WSC", "UUID-E", uuid_e_str);
handshake_state_set_8021x_config(s.ap_hs, ap_8021x_settings);
handshake_state_set_authenticator(s.sta_hs, false);
handshake_state_set_event_func(s.sta_hs, test_ap_sta_hs_event_sta,
&wsc_data);
handshake_state_set_authenticator_address(s.sta_hs, s.ap_address);
handshake_state_set_supplicant_address(s.sta_hs, s.sta_address);
handshake_state_set_authenticator_ie(s.sta_hs, ap_rsne);
handshake_state_set_ssid(s.sta_hs, (void *) ssid, strlen(ssid));
l_settings_load_from_data(sta_8021x_settings, sta_8021x_str,
strlen(sta_8021x_str));
l_settings_set_string(sta_8021x_settings, "WSC", "EnrolleeMAC",
util_address_to_string(s.sta_address));
handshake_state_set_8021x_config(s.sta_hs, sta_8021x_settings);
test_ap_sta_run(&s);
handshake_state_free(s.ap_hs);
handshake_state_free(s.sta_hs);
__handshake_set_install_tk_func(NULL);
l_settings_free(ap_8021x_settings);
l_settings_free(sta_8021x_settings);
assert(wsc_data.sta_eap_failed && wsc_data.credentials_obtained);
assert(wsc_data.ap_eap_failed && wsc_data.credentials_sent);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
l_test_init(&argc, &argv); l_test_init(&argc, &argv);
@ -2374,6 +2646,9 @@ int main(int argc, char *argv[])
l_test_add("/wsc/retransmission/no fragmentation", l_test_add("/wsc/retransmission/no fragmentation",
wsc_test_retransmission_no_fragmentation, NULL); wsc_test_retransmission_no_fragmentation, NULL);
l_test_add("/wsc-r/handshake/PBC Handshake WPA2 Test",
wsc_r_test_pbc_handshake_wpa2, NULL);
done: done:
return l_test_run(); return l_test_run();
} }