2 + sm->assoc_resp_ftie[1]);
res = 2 + sm->assoc_resp_ftie[1];
} else {
- int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
-
- res = wpa_write_ftie(conf, use_sha384,
+ res = wpa_write_ftie(conf, sm->wpa_key_mgmt,
+ sm->xxkey_len,
conf->r0_key_holder,
conf->r0_key_holder_len,
NULL, NULL, pos,
#ifdef CONFIG_IEEE80211R_AP
-int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth, int use_sha384,
+int wpa_auth_write_fte(struct wpa_authenticator *wpa_auth,
+ struct wpa_state_machine *sm,
u8 *buf, size_t len)
{
struct wpa_auth_config *conf = &wpa_auth->conf;
- return wpa_write_ftie(conf, use_sha384, conf->r0_key_holder,
- conf->r0_key_holder_len,
+ return wpa_write_ftie(conf, sm->wpa_key_mgmt, sm->xxkey_len,
+ conf->r0_key_holder, conf->r0_key_holder_len,
NULL, NULL, buf, len, NULL, 0, 0);
}
#endif /* CONFIG_IEEE80211R_AP */
2 + sm->assoc_resp_ftie[1]);
res = 2 + sm->assoc_resp_ftie[1];
} else {
- int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt);
-
- res = wpa_write_ftie(conf, use_sha384,
+ res = wpa_write_ftie(conf, sm->wpa_key_mgmt,
+ sm->xxkey_len,
conf->r0_key_holder,
conf->r0_key_holder_len,
NULL, NULL, pos,
#include "crypto/aes_siv.h"
#include "crypto/aes_wrap.h"
#include "crypto/sha384.h"
+#include "crypto/sha512.h"
#include "crypto/random.h"
#include "ap_config.h"
#include "ieee802_11.h"
}
-int wpa_write_ftie(struct wpa_auth_config *conf, int use_sha384,
+int wpa_write_ftie(struct wpa_auth_config *conf, int key_mgmt, size_t key_len,
const u8 *r0kh_id, size_t r0kh_id_len,
const u8 *anonce, const u8 *snonce,
u8 *buf, size_t len, const u8 *subelem,
size_t subelem_len, int rsnxe_used)
{
u8 *pos = buf, *ielen;
- size_t hdrlen = use_sha384 ? sizeof(struct rsn_ftie_sha384) :
- sizeof(struct rsn_ftie);
+ size_t hdrlen;
+
+ if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ key_len == SHA256_MAC_LEN)
+ hdrlen = sizeof(struct rsn_ftie);
+ else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ key_len == SHA384_MAC_LEN)
+ hdrlen = sizeof(struct rsn_ftie_sha384);
+ else if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ key_len == SHA512_MAC_LEN)
+ hdrlen = sizeof(struct rsn_ftie_sha512);
+ else if (wpa_key_mgmt_sha384(key_mgmt))
+ hdrlen = sizeof(struct rsn_ftie_sha384);
+ else
+ hdrlen = sizeof(struct rsn_ftie);
if (len < 2 + hdrlen + 2 + FT_R1KH_ID_LEN + 2 + r0kh_id_len +
subelem_len)
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
ielen = pos++;
- if (use_sha384) {
+ if (key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ key_len == SHA512_MAC_LEN) {
+ struct rsn_ftie_sha512 *hdr = (struct rsn_ftie_sha512 *) pos;
+
+ os_memset(hdr, 0, sizeof(*hdr));
+ pos += sizeof(*hdr);
+ WPA_PUT_LE16(hdr->mic_control, !!rsnxe_used);
+ if (anonce)
+ os_memcpy(hdr->anonce, anonce, WPA_NONCE_LEN);
+ if (snonce)
+ os_memcpy(hdr->snonce, snonce, WPA_NONCE_LEN);
+ } else if ((key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ key_len == SHA384_MAC_LEN) ||
+ wpa_key_mgmt_sha384(key_mgmt)) {
struct rsn_ftie_sha384 *hdr = (struct rsn_ftie_sha384 *) pos;
os_memset(hdr, 0, sizeof(*hdr));
const u8 *kck;
size_t kck_len;
int use_sha384;
+ size_t key_len;
if (sm == NULL)
return pos;
rsnxe_used);
}
#endif /* CONFIG_TESTING_OPTIONS */
- res = wpa_write_ftie(conf, use_sha384, r0kh_id, r0kh_id_len,
+ key_len = sm->xxkey_len;
+ if (!key_len)
+ key_len = sm->pmk_r1_len;
+ if (!key_len && sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+ sm->wpa_auth->cb->get_psk) {
+ size_t psk_len;
+
+ if (sm->wpa_auth->cb->get_psk(sm->wpa_auth->cb_ctx,
+ sm->addr, sm->p2p_dev_addr,
+ NULL, &psk_len, NULL))
+ key_len = psk_len;
+ }
+ res = wpa_write_ftie(conf, sm->wpa_key_mgmt, key_len,
+ r0kh_id, r0kh_id_len,
anonce, snonce, pos, end - pos,
subelem, subelem_len, rsnxe_used);
os_free(subelem);
goto fail;
pos += ret;
- ret = wpa_write_ftie(conf, use_sha384, parse.r0kh_id, parse.r0kh_id_len,
+ ret = wpa_write_ftie(conf, parse.key_mgmt, pmk_r1_len,
+ parse.r0kh_id, parse.r0kh_id_len,
sm->ANonce, sm->SNonce, pos, end - pos, NULL, 0,
0);
if (ret < 0)