eap="PSK", identity="psk.user@example.com",
password_hex="0123456789abcdef0123456789abcdef",
erp="1", scan_freq="2412")
+
+def test_fils_offload_to_driver(dev, apdev, params):
+ """FILS offload to driver"""
+ check_fils_capa(dev[0])
+ check_erp_capa(dev[0])
+ run_fils_offload_to_driver(dev[0], apdev, params)
+
+def test_fils_offload_to_driver2(dev, apdev, params):
+ """FILS offload to driver"""
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
+ run_fils_offload_to_driver(wpas, apdev, params)
+
+def run_fils_offload_to_driver(dev, apdev, params):
+ start_erp_as(msk_dump=os.path.join(params['logdir'], "msk.lst"))
+
+ bssid = apdev[0]['bssid']
+ params = hostapd.wpa2_eap_params(ssid="fils")
+ params['wpa_key_mgmt'] = "FILS-SHA256"
+ params['auth_server_port'] = "18128"
+ params['erp_send_reauth_start'] = '1'
+ params['erp_domain'] = 'example.com'
+ params['fils_realm'] = 'example.com'
+ params['disable_pmksa_caching'] = '1'
+ hapd = hostapd.add_ap(apdev[0]['ifname'], params)
+
+ dev.request("ERP_FLUSH")
+ id = dev.connect("fils", key_mgmt="FILS-SHA256",
+ eap="PSK", identity="psk.user@example.com",
+ password_hex="0123456789abcdef0123456789abcdef",
+ erp="1", scan_freq="2412")
+
+ p = "freq=2412 authorized=1 fils_erp_next_seq_num=4"
+ if "OK" not in dev.request("DRIVER_EVENT ASSOC " + p):
+ raise Exception("DRIVER_EVENT ASSOC did not succeed")
+ dev.wait_connected()
+
+ dev.request("DISCONNECT")
+ dev.wait_disconnected()
+ dev.dump_monitor()
+
+ dev.select_network(id, freq=2412)
+ dev.wait_connected()
+ dev.dump_monitor()
+
+ # This does not really work properly with SME-in-wpa_supplicant case
+ p = "freq=2412 authorized=1 fils_erp_next_seq_num=4"
+ if "OK" not in dev.request("DRIVER_EVENT ASSOC " + p):
+ raise Exception("DRIVER_EVENT ASSOC did not succeed")
+
+ dev.wait_connected()
}
+static int wpas_ctrl_iface_driver_event_assoc(struct wpa_supplicant *wpa_s,
+ char *param)
+{
+ union wpa_event_data event;
+ struct assoc_info *ai;
+ char *ctx = NULL;
+ int ret = -1;
+ struct wpabuf *req_ies = NULL;
+ struct wpabuf *resp_ies = NULL;
+ struct wpabuf *resp_frame = NULL;
+ struct wpabuf *beacon_ies = NULL;
+ struct wpabuf *key_replay_ctr = NULL;
+ struct wpabuf *ptk_kck = NULL;
+ struct wpabuf *ptk_kek = NULL;
+ struct wpabuf *fils_pmk = NULL;
+ char *str, *pos;
+ u8 addr[ETH_ALEN];
+ u8 fils_pmkid[PMKID_LEN];
+
+ os_memset(&event, 0, sizeof(event));
+ ai = &event.assoc_info;
+
+ while ((str = str_token(param, " ", &ctx))) {
+ pos = os_strchr(str, '=');
+ if (!pos)
+ goto fail;
+ *pos++ = '\0';
+
+ if (os_strcmp(str, "reassoc") == 0) {
+ ai->reassoc = atoi(pos);
+ } else if (os_strcmp(str, "req_ies") == 0) {
+ wpabuf_free(req_ies);
+ req_ies = wpabuf_parse_bin(pos);
+ if (!req_ies)
+ goto fail;
+ ai->req_ies = wpabuf_head(req_ies);
+ ai->req_ies_len = wpabuf_len(req_ies);
+ } else if (os_strcmp(str, "resp_ies") == 0) {
+ wpabuf_free(resp_ies);
+ resp_ies = wpabuf_parse_bin(pos);
+ if (!resp_ies)
+ goto fail;
+ ai->resp_ies = wpabuf_head(resp_ies);
+ ai->resp_ies_len = wpabuf_len(resp_ies);
+ } else if (os_strcmp(str, "resp_frame") == 0) {
+ wpabuf_free(resp_frame);
+ resp_frame = wpabuf_parse_bin(pos);
+ if (!resp_frame)
+ goto fail;
+ ai->resp_frame = wpabuf_head(resp_frame);
+ ai->resp_frame_len = wpabuf_len(resp_frame);
+ } else if (os_strcmp(str, "beacon_ies") == 0) {
+ wpabuf_free(beacon_ies);
+ beacon_ies = wpabuf_parse_bin(pos);
+ if (!beacon_ies)
+ goto fail;
+ ai->beacon_ies = wpabuf_head(beacon_ies);
+ ai->beacon_ies_len = wpabuf_len(beacon_ies);
+ } else if (os_strcmp(str, "freq") == 0) {
+ ai->freq = atoi(pos);
+ } else if (os_strcmp(str, "wmm::info_bitmap") == 0) {
+ ai->wmm_params.info_bitmap = atoi(pos);
+ } else if (os_strcmp(str, "wmm::uapsd_queues") == 0) {
+ ai->wmm_params.uapsd_queues = atoi(pos);
+ } else if (os_strcmp(str, "addr") == 0) {
+ if (hwaddr_aton(pos, addr))
+ goto fail;
+ ai->addr = addr;
+ } else if (os_strcmp(str, "authorized") == 0) {
+ ai->authorized = atoi(pos);
+ } else if (os_strcmp(str, "key_replay_ctr") == 0) {
+ wpabuf_free(key_replay_ctr);
+ key_replay_ctr = wpabuf_parse_bin(pos);
+ if (!key_replay_ctr)
+ goto fail;
+ ai->key_replay_ctr = wpabuf_head(key_replay_ctr);
+ ai->key_replay_ctr_len = wpabuf_len(key_replay_ctr);
+ } else if (os_strcmp(str, "ptk_kck") == 0) {
+ wpabuf_free(ptk_kck);
+ ptk_kck = wpabuf_parse_bin(pos);
+ if (!ptk_kck)
+ goto fail;
+ ai->ptk_kck = wpabuf_head(ptk_kck);
+ ai->ptk_kck_len = wpabuf_len(ptk_kck);
+ } else if (os_strcmp(str, "ptk_kek") == 0) {
+ wpabuf_free(ptk_kek);
+ ptk_kek = wpabuf_parse_bin(pos);
+ if (!ptk_kek)
+ goto fail;
+ ai->ptk_kek = wpabuf_head(ptk_kek);
+ ai->ptk_kek_len = wpabuf_len(ptk_kek);
+ } else if (os_strcmp(str, "subnet_status") == 0) {
+ ai->subnet_status = atoi(pos);
+ } else if (os_strcmp(str, "fils_erp_next_seq_num") == 0) {
+ ai->fils_erp_next_seq_num = atoi(pos);
+ } else if (os_strcmp(str, "fils_pmk") == 0) {
+ wpabuf_free(fils_pmk);
+ fils_pmk = wpabuf_parse_bin(pos);
+ if (!fils_pmk)
+ goto fail;
+ ai->fils_pmk = wpabuf_head(fils_pmk);
+ ai->fils_pmk_len = wpabuf_len(fils_pmk);
+ } else if (os_strcmp(str, "fils_pmkid") == 0) {
+ if (hexstr2bin(pos, fils_pmkid, PMKID_LEN) < 0)
+ goto fail;
+ ai->fils_pmkid = fils_pmkid;
+ } else {
+ goto fail;
+ }
+ }
+
+ wpa_supplicant_event(wpa_s, EVENT_ASSOC, &event);
+ ret = 0;
+fail:
+ wpabuf_free(req_ies);
+ wpabuf_free(resp_ies);
+ wpabuf_free(resp_frame);
+ wpabuf_free(beacon_ies);
+ wpabuf_free(key_replay_ctr);
+ wpabuf_free(ptk_kck);
+ wpabuf_free(ptk_kek);
+ wpabuf_free(fils_pmk);
+ return ret;
+}
+
+
static int wpas_ctrl_iface_driver_event(struct wpa_supplicant *wpa_s, char *cmd)
{
char *pos, *param;
return 0;
} else if (os_strcmp(cmd, "SCAN_RES") == 0) {
return wpas_ctrl_iface_driver_scan_res(wpa_s, param);
+ } else if (os_strcmp(cmd, "ASSOC") == 0) {
+ return wpas_ctrl_iface_driver_event_assoc(wpa_s, param);
} else {
wpa_dbg(wpa_s, MSG_DEBUG, "Testing - unknown driver event: %s",
cmd);