/* PMKSA cache entry removed; parameters: <BSSID> <network_id> */
#define PMKSA_CACHE_REMOVED "PMKSA-CACHE-REMOVED "
+/* FILS HLP Container receive; parameters: dst=<addr> src=<addr> frame=<hexdump>
+ */
+#define FILS_HLP_RX "FILS-HLP-RX "
+
/* BSS command information masks */
#define WPA_BSS_MASK_ALL 0xFFFDFFFF
}
+static void fils_process_hlp_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
+{
+ const u8 *pos, *end;
+
+ wpa_hexdump(MSG_MSGDUMP, "FILS: HLP response", resp, len);
+ if (len < 2 * ETH_ALEN)
+ return;
+ pos = resp + 2 * ETH_ALEN;
+ end = resp + len;
+ if (end - pos >= 6 &&
+ os_memcmp(pos, "\xaa\xaa\x03\x00\x00\x00", 6) == 0)
+ pos += 6; /* Remove SNAP/LLC header */
+ wpa_sm_fils_hlp_rx(sm, resp, resp + ETH_ALEN, pos, end - pos);
+}
+
+
+static void fils_process_hlp_container(struct wpa_sm *sm, const u8 *pos,
+ size_t len)
+{
+ const u8 *end = pos + len;
+ u8 *tmp, *tmp_pos;
+
+ /* Check if there are any FILS HLP Container elements */
+ while (end - pos >= 2) {
+ if (2 + pos[1] > end - pos)
+ return;
+ if (pos[0] == WLAN_EID_EXTENSION &&
+ pos[1] >= 1 + 2 * ETH_ALEN &&
+ pos[2] == WLAN_EID_EXT_FILS_HLP_CONTAINER)
+ break;
+ pos += 2 + pos[1];
+ }
+ if (end - pos < 2)
+ return; /* No FILS HLP Container elements */
+
+ tmp = os_malloc(end - pos);
+ if (!tmp)
+ return;
+
+ while (end - pos >= 2) {
+ if (2 + pos[1] > end - pos ||
+ pos[0] != WLAN_EID_EXTENSION ||
+ pos[1] < 1 + 2 * ETH_ALEN ||
+ pos[2] != WLAN_EID_EXT_FILS_HLP_CONTAINER)
+ break;
+ tmp_pos = tmp;
+ os_memcpy(tmp_pos, pos + 3, pos[1] - 1);
+ tmp_pos += pos[1] - 1;
+ pos += 2 + pos[1];
+
+ /* Add possible fragments */
+ while (end - pos >= 2 && pos[0] == WLAN_EID_FRAGMENT &&
+ 2 + pos[1] <= end - pos) {
+ os_memcpy(tmp_pos, pos + 2, pos[1]);
+ tmp_pos += pos[1];
+ pos += 2 + pos[1];
+ }
+
+ fils_process_hlp_resp(sm, tmp, tmp_pos - tmp);
+ }
+
+ os_free(tmp);
+}
+
+
int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len)
{
const struct ieee80211_mgmt *mgmt;
/* TK is not needed anymore in supplicant */
os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
- /* TODO: FILS HLP Container */
+ /* FILS HLP Container */
+ fils_process_hlp_container(sm, ie_start, end - ie_start);
/* TODO: FILS IP Address Assignment */
const u8 *kck, size_t kck_len,
const u8 *replay_ctr);
int (*key_mgmt_set_pmk)(void *ctx, const u8 *pmk, size_t pmk_len);
+ void (*fils_hlp_rx)(void *ctx, const u8 *dst, const u8 *src,
+ const u8 *pkt, size_t pkt_len);
};
return sm->ctx->key_mgmt_set_pmk(sm->ctx->ctx, pmk, pmk_len);
}
+static inline void wpa_sm_fils_hlp_rx(struct wpa_sm *sm,
+ const u8 *dst, const u8 *src,
+ const u8 *pkt, size_t pkt_len)
+{
+ if (sm->ctx->fils_hlp_rx)
+ sm->ctx->fils_hlp_rx(sm->ctx->ctx, dst, src, pkt, pkt_len);
+}
+
+
int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
int ver, const u8 *dest, u16 proto,
u8 *msg, size_t msg_len, u8 *key_mic);
#ifndef CONFIG_NO_WPA
+
static void wpa_supplicant_set_rekey_offload(void *ctx,
const u8 *kek, size_t kek_len,
const u8 *kck, size_t kck_len,
else
return 0;
}
+
+
+static void wpa_supplicant_fils_hlp_rx(void *ctx, const u8 *dst, const u8 *src,
+ const u8 *pkt, size_t pkt_len)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ char *hex;
+ size_t hexlen;
+
+ hexlen = pkt_len * 2 + 1;
+ hex = os_malloc(hexlen);
+ if (!hex)
+ return;
+ wpa_snprintf_hex(hex, hexlen, pkt, pkt_len);
+ wpa_msg(wpa_s, MSG_INFO, FILS_HLP_RX "dst=" MACSTR " src=" MACSTR
+ " frame=%s", MAC2STR(dst), MAC2STR(src), hex);
+ os_free(hex);
+}
+
#endif /* CONFIG_NO_WPA */
#endif /* CONFIG_TDLS */
ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk;
+ ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
wpa_s->wpa = wpa_sm_init(ctx);
if (wpa_s->wpa == NULL) {