const u8 *wpa_ie, size_t wpa_ie_len,
struct wpa_ptk *ptk)
{
- size_t mic_len, hdrlen, rlen;
+ size_t mic_len, hdrlen, rlen, extra_len = 0;
struct wpa_eapol_key *reply;
u8 *rbuf, *key_mic;
u8 *rsn_ie_buf = NULL;
wpa_hexdump(MSG_DEBUG, "WPA: WPA IE for msg 2/4", wpa_ie, wpa_ie_len);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (sm->test_eapol_m2_elems)
+ extra_len = wpabuf_len(sm->test_eapol_m2_elems);
+#endif /* CONFIG_TESTING_OPTIONS */
+
mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
hdrlen = sizeof(*reply) + mic_len + 2;
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY,
- NULL, hdrlen + wpa_ie_len,
+ NULL, hdrlen + wpa_ie_len + extra_len,
&rlen, (void *) &reply);
if (rbuf == NULL) {
os_free(rsn_ie_buf);
WPA_REPLAY_COUNTER_LEN);
key_mic = (u8 *) (reply + 1);
- WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len); /* Key Data Length */
+ /* Key Data Length */
+ WPA_PUT_BE16(key_mic + mic_len, wpa_ie_len + extra_len);
os_memcpy(key_mic + mic_len + 2, wpa_ie, wpa_ie_len); /* Key Data */
os_free(rsn_ie_buf);
+#ifdef CONFIG_TESTING_OPTIONS
+ if (sm->test_eapol_m2_elems) {
+ os_memcpy(key_mic + mic_len + 2 + wpa_ie_len,
+ wpabuf_head(sm->test_eapol_m2_elems),
+ wpabuf_len(sm->test_eapol_m2_elems));
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
os_memcpy(reply->key_nonce, nonce, WPA_NONCE_LEN);
struct wpa_eapol_key *reply;
u8 *rbuf, *key_mic;
u8 *kde = NULL;
- size_t kde_len = 0;
+ size_t kde_len = 0, extra_len = 0;
if (sm->mlo.valid_links) {
u8 *pos;
kde_len = pos - kde;
}
+#ifdef CONFIG_TESTING_OPTIONS
+ if (sm->test_eapol_m4_elems)
+ extra_len = wpabuf_len(sm->test_eapol_m4_elems);
+#endif /* CONFIG_TESTING_OPTIONS */
+
mic_len = wpa_mic_len(sm->key_mgmt, sm->pmk_len);
hdrlen = sizeof(*reply) + mic_len + 2;
rbuf = wpa_sm_alloc_eapol(sm, IEEE802_1X_TYPE_EAPOL_KEY, NULL,
- hdrlen + kde_len, &rlen, (void *) &reply);
+ hdrlen + kde_len + extra_len, &rlen,
+ (void *) &reply);
if (!rbuf) {
os_free(kde);
return -1;
WPA_REPLAY_COUNTER_LEN);
key_mic = (u8 *) (reply + 1);
- WPA_PUT_BE16(key_mic + mic_len, kde_len); /* Key Data length */
+ /* Key Data length */
+ WPA_PUT_BE16(key_mic + mic_len, kde_len + extra_len);
if (kde) {
os_memcpy(key_mic + mic_len + 2, kde, kde_len); /* Key Data */
os_free(kde);
}
+#ifdef CONFIG_TESTING_OPTIONS
+ if (sm->test_eapol_m4_elems) {
+ os_memcpy(key_mic + mic_len + 2 + kde_len,
+ wpabuf_head(sm->test_eapol_m4_elems),
+ wpabuf_len(sm->test_eapol_m4_elems));
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Sending EAPOL-Key 4/4");
return wpa_eapol_key_send(sm, ptk, ver, dst, ETH_P_EAPOL, rbuf, rlen,
key_mic);
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_TESTING_OPTIONS
wpabuf_free(sm->test_assoc_ie);
+ wpabuf_free(sm->test_eapol_m2_elems);
+ wpabuf_free(sm->test_eapol_m4_elems);
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_FILS_SK_PFS
crypto_ecdh_deinit(sm->fils_ecdh);
}
+void wpa_sm_set_test_eapol_m2_elems(struct wpa_sm *sm, struct wpabuf *buf)
+{
+ wpabuf_free(sm->test_eapol_m2_elems);
+ sm->test_eapol_m2_elems = buf;
+}
+
+
+void wpa_sm_set_test_eapol_m4_elems(struct wpa_sm *sm, struct wpabuf *buf)
+{
+ wpabuf_free(sm->test_eapol_m4_elems);
+ sm->test_eapol_m4_elems = buf;
+}
+
+
const u8 * wpa_sm_get_anonce(struct wpa_sm *sm)
{
return sm->anonce;
wpa_s->ft_rsnxe_used = 0;
wpa_s->reject_btm_req_reason = 0;
wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL);
+ wpa_sm_set_test_eapol_m2_elems(wpa_s->wpa, NULL);
+ wpa_sm_set_test_eapol_m4_elems(wpa_s->wpa, NULL);
os_free(wpa_s->get_pref_freq_list_override);
wpa_s->get_pref_freq_list_override = NULL;
wpabuf_free(wpa_s->sae_commit_override);
}
-static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s,
- const char *cmd)
+static int wpas_get_hex_buf(const char *val, struct wpabuf **ret)
{
struct wpabuf *buf;
size_t len;
- len = os_strlen(cmd);
+ len = os_strlen(val);
if (len & 1)
return -1;
len /= 2;
buf = NULL;
} else {
buf = wpabuf_alloc(len);
- if (buf == NULL)
+ if (!buf)
return -1;
- if (hexstr2bin(cmd, wpabuf_put(buf, len), len) < 0) {
+ if (hexstr2bin(val, wpabuf_put(buf, len), len) < 0) {
wpabuf_free(buf);
return -1;
}
}
+ *ret = buf;
+ return 0;
+}
+
+
+static int wpas_ctrl_test_assoc_ie(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ struct wpabuf *buf;
+
+ if (wpas_get_hex_buf(cmd, &buf) < 0)
+ return -1;
wpa_sm_set_test_assoc_ie(wpa_s->wpa, buf);
return 0;
}
+static int wpas_ctrl_test_eapol_m2_elems(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ struct wpabuf *buf;
+
+ if (wpas_get_hex_buf(cmd, &buf) < 0)
+ return -1;
+ wpa_sm_set_test_eapol_m2_elems(wpa_s->wpa, buf);
+ return 0;
+}
+
+
+static int wpas_ctrl_test_eapol_m4_elems(struct wpa_supplicant *wpa_s,
+ const char *cmd)
+{
+ struct wpabuf *buf;
+
+ if (wpas_get_hex_buf(cmd, &buf) < 0)
+ return -1;
+ wpa_sm_set_test_eapol_m4_elems(wpa_s->wpa, buf);
+ return 0;
+}
+
+
static int wpas_ctrl_reset_pn(struct wpa_supplicant *wpa_s)
{
u8 zero[WPA_TK_MAX_LEN];
} else if (os_strncmp(buf, "TEST_ASSOC_IE ", 14) == 0) {
if (wpas_ctrl_test_assoc_ie(wpa_s, buf + 14) < 0)
reply_len = -1;
+ } else if (os_strncmp(buf, "TEST_EAPOL_M2_ELEMS ", 20) == 0) {
+ if (wpas_ctrl_test_eapol_m2_elems(wpa_s, buf + 20) < 0)
+ reply_len = -1;
+ } else if (os_strncmp(buf, "TEST_EAPOL_M4_ELEMS ", 20) == 0) {
+ if (wpas_ctrl_test_eapol_m4_elems(wpa_s, buf + 20) < 0)
+ reply_len = -1;
} else if (os_strcmp(buf, "RESET_PN") == 0) {
if (wpas_ctrl_reset_pn(wpa_s) < 0)
reply_len = -1;