mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-25 00:38:24 -05:00
DPP: Update AES-SIV AD for DPP Authentication frames
The protocol design was updated to protect the six octets in the header before the attributes. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
4bb2272bab
commit
dc4d271c6d
@ -73,23 +73,14 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd)
|
|||||||
|
|
||||||
if (auth && auth->response_pending &&
|
if (auth && auth->response_pending &&
|
||||||
dpp_notify_new_qr_code(auth, bi) == 1) {
|
dpp_notify_new_qr_code(auth, bi) == 1) {
|
||||||
struct wpabuf *msg;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: Sending out pending authentication response");
|
"DPP: Sending out pending authentication response");
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
|
|
||||||
wpabuf_len(auth->resp_attr));
|
|
||||||
if (!msg)
|
|
||||||
goto out;
|
|
||||||
wpabuf_put_buf(msg, hapd->dpp_auth->resp_attr);
|
|
||||||
|
|
||||||
hostapd_drv_send_action(hapd, auth->curr_freq, 0,
|
hostapd_drv_send_action(hapd, auth->curr_freq, 0,
|
||||||
auth->peer_mac_addr,
|
auth->peer_mac_addr,
|
||||||
wpabuf_head(msg), wpabuf_len(msg));
|
wpabuf_head(hapd->dpp_auth->resp_msg),
|
||||||
wpabuf_free(msg);
|
wpabuf_len(hapd->dpp_auth->resp_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return bi->id;
|
return bi->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,7 +450,6 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
|
|||||||
{
|
{
|
||||||
const char *pos;
|
const char *pos;
|
||||||
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
|
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
|
||||||
struct wpabuf *msg;
|
|
||||||
const u8 *dst;
|
const u8 *dst;
|
||||||
int res;
|
int res;
|
||||||
int configurator = 1;
|
int configurator = 1;
|
||||||
@ -521,12 +511,6 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
|
|||||||
else
|
else
|
||||||
hapd->dpp_auth->curr_freq = 2412;
|
hapd->dpp_auth->curr_freq = 2412;
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ,
|
|
||||||
wpabuf_len(hapd->dpp_auth->req_attr));
|
|
||||||
if (!msg)
|
|
||||||
return -1;
|
|
||||||
wpabuf_put_buf(msg, hapd->dpp_auth->req_attr);
|
|
||||||
|
|
||||||
if (is_zero_ether_addr(peer_bi->mac_addr)) {
|
if (is_zero_ether_addr(peer_bi->mac_addr)) {
|
||||||
dst = broadcast;
|
dst = broadcast;
|
||||||
} else {
|
} else {
|
||||||
@ -537,8 +521,8 @@ int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd)
|
|||||||
hapd->dpp_auth_ok_on_ack = 0;
|
hapd->dpp_auth_ok_on_ack = 0;
|
||||||
|
|
||||||
res = hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
|
res = hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
|
||||||
dst, wpabuf_head(msg), wpabuf_len(msg));
|
dst, wpabuf_head(hapd->dpp_auth->req_msg),
|
||||||
wpabuf_free(msg);
|
wpabuf_len(hapd->dpp_auth->req_msg));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
fail:
|
fail:
|
||||||
@ -549,12 +533,12 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
|
static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
|
||||||
const u8 *buf, size_t len, unsigned int freq)
|
const u8 *hdr, const u8 *buf, size_t len,
|
||||||
|
unsigned int freq)
|
||||||
{
|
{
|
||||||
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
|
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
|
||||||
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
|
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
|
||||||
struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
|
struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
|
||||||
struct wpabuf *msg;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
|
wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
|
||||||
MAC2STR(src));
|
MAC2STR(src));
|
||||||
@ -630,7 +614,7 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
|
|||||||
hapd->dpp_auth_ok_on_ack = 0;
|
hapd->dpp_auth_ok_on_ack = 0;
|
||||||
hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
|
hapd->dpp_auth = dpp_auth_req_rx(hapd->msg_ctx, hapd->dpp_allowed_roles,
|
||||||
hapd->dpp_qr_mutual,
|
hapd->dpp_qr_mutual,
|
||||||
peer_bi, own_bi, freq, buf,
|
peer_bi, own_bi, freq, hdr, buf,
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
if (!hapd->dpp_auth) {
|
if (!hapd->dpp_auth) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: No response generated");
|
wpa_printf(MSG_DEBUG, "DPP: No response generated");
|
||||||
@ -641,15 +625,9 @@ static void hostapd_dpp_rx_auth_req(struct hostapd_data *hapd, const u8 *src,
|
|||||||
hapd->dpp_configurator_params);
|
hapd->dpp_configurator_params);
|
||||||
os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
|
os_memcpy(hapd->dpp_auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
|
|
||||||
wpabuf_len(hapd->dpp_auth->resp_attr));
|
|
||||||
if (!msg)
|
|
||||||
return;
|
|
||||||
wpabuf_put_buf(msg, hapd->dpp_auth->resp_attr);
|
|
||||||
|
|
||||||
hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
|
hostapd_drv_send_action(hapd, hapd->dpp_auth->curr_freq, 0,
|
||||||
src, wpabuf_head(msg), wpabuf_len(msg));
|
src, wpabuf_head(hapd->dpp_auth->resp_msg),
|
||||||
wpabuf_free(msg);
|
wpabuf_len(hapd->dpp_auth->resp_msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -840,10 +818,10 @@ static void hostapd_dpp_auth_success(struct hostapd_data *hapd, int initiator)
|
|||||||
|
|
||||||
|
|
||||||
static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
|
static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
|
||||||
const u8 *buf, size_t len)
|
const u8 *hdr, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dpp_authentication *auth = hapd->dpp_auth;
|
struct dpp_authentication *auth = hapd->dpp_auth;
|
||||||
struct wpabuf *msg, *attr;
|
struct wpabuf *msg;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
|
wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
|
||||||
MAC2STR(src));
|
MAC2STR(src));
|
||||||
@ -861,8 +839,8 @@ static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = dpp_auth_resp_rx(auth, buf, len);
|
msg = dpp_auth_resp_rx(auth, hdr, buf, len);
|
||||||
if (!attr) {
|
if (!msg) {
|
||||||
if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
|
if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
|
wpa_printf(MSG_DEBUG, "DPP: Wait for full response");
|
||||||
return;
|
return;
|
||||||
@ -872,14 +850,6 @@ static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
|
|||||||
}
|
}
|
||||||
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, wpabuf_len(attr));
|
|
||||||
if (!msg) {
|
|
||||||
wpabuf_free(attr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wpabuf_put_buf(msg, attr);
|
|
||||||
wpabuf_free(attr);
|
|
||||||
|
|
||||||
hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
|
hostapd_drv_send_action(hapd, auth->curr_freq, 0, src,
|
||||||
wpabuf_head(msg), wpabuf_len(msg));
|
wpabuf_head(msg), wpabuf_len(msg));
|
||||||
wpabuf_free(msg);
|
wpabuf_free(msg);
|
||||||
@ -888,7 +858,7 @@ static void hostapd_dpp_rx_auth_resp(struct hostapd_data *hapd, const u8 *src,
|
|||||||
|
|
||||||
|
|
||||||
static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
|
static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
|
||||||
const u8 *buf, size_t len)
|
const u8 *hdr, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dpp_authentication *auth = hapd->dpp_auth;
|
struct dpp_authentication *auth = hapd->dpp_auth;
|
||||||
|
|
||||||
@ -907,7 +877,7 @@ static void hostapd_dpp_rx_auth_conf(struct hostapd_data *hapd, const u8 *src,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpp_auth_conf_rx(auth, buf, len) < 0) {
|
if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1206,9 +1176,15 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
|
|||||||
{
|
{
|
||||||
u8 crypto_suite;
|
u8 crypto_suite;
|
||||||
enum dpp_public_action_frame_type type;
|
enum dpp_public_action_frame_type type;
|
||||||
|
const u8 *hdr;
|
||||||
|
|
||||||
if (len < 2)
|
if (len < DPP_HDR_LEN)
|
||||||
return;
|
return;
|
||||||
|
if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
|
||||||
|
return;
|
||||||
|
hdr = buf;
|
||||||
|
buf += 4;
|
||||||
|
len -= 4;
|
||||||
crypto_suite = *buf++;
|
crypto_suite = *buf++;
|
||||||
type = *buf++;
|
type = *buf++;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
@ -1228,13 +1204,13 @@ void hostapd_dpp_rx_action(struct hostapd_data *hapd, const u8 *src,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DPP_PA_AUTHENTICATION_REQ:
|
case DPP_PA_AUTHENTICATION_REQ:
|
||||||
hostapd_dpp_rx_auth_req(hapd, src, buf, len, freq);
|
hostapd_dpp_rx_auth_req(hapd, src, hdr, buf, len, freq);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_AUTHENTICATION_RESP:
|
case DPP_PA_AUTHENTICATION_RESP:
|
||||||
hostapd_dpp_rx_auth_resp(hapd, src, buf, len);
|
hostapd_dpp_rx_auth_resp(hapd, src, hdr, buf, len);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_AUTHENTICATION_CONF:
|
case DPP_PA_AUTHENTICATION_CONF:
|
||||||
hostapd_dpp_rx_auth_conf(hapd, src, buf, len);
|
hostapd_dpp_rx_auth_conf(hapd, src, hdr, buf, len);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_PEER_DISCOVERY_REQ:
|
case DPP_PA_PEER_DISCOVERY_REQ:
|
||||||
hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
|
hostapd_dpp_rx_peer_disc_req(hapd, src, buf, len, freq);
|
||||||
|
@ -1005,7 +1005,7 @@ static void hostapd_action_rx(struct hostapd_data *hapd,
|
|||||||
DPP_OUI_TYPE) {
|
DPP_OUI_TYPE) {
|
||||||
const u8 *pos, *end;
|
const u8 *pos, *end;
|
||||||
|
|
||||||
pos = &mgmt->u.action.u.vs_public_action.variable[1];
|
pos = mgmt->u.action.u.vs_public_action.oui;
|
||||||
end = drv_mgmt->frame + drv_mgmt->frame_len;
|
end = drv_mgmt->frame + drv_mgmt->frame_len;
|
||||||
hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
|
hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
|
||||||
drv_mgmt->freq);
|
drv_mgmt->freq);
|
||||||
|
@ -3618,7 +3618,7 @@ static int handle_action(struct hostapd_data *hapd,
|
|||||||
DPP_OUI_TYPE) {
|
DPP_OUI_TYPE) {
|
||||||
const u8 *pos, *end;
|
const u8 *pos, *end;
|
||||||
|
|
||||||
pos = &mgmt->u.action.u.vs_public_action.variable[1];
|
pos = mgmt->u.action.u.vs_public_action.oui;
|
||||||
end = ((const u8 *) mgmt) + len;
|
end = ((const u8 *) mgmt) + len;
|
||||||
hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
|
hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
|
||||||
hapd->iface->freq);
|
hapd->iface->freq);
|
||||||
|
202
src/common/dpp.c
202
src/common/dpp.c
@ -1340,8 +1340,9 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
|
|||||||
u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1];
|
u8 clear[4 + DPP_MAX_NONCE_LEN + 4 + 1];
|
||||||
u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE];
|
u8 wrapped_data[4 + DPP_MAX_NONCE_LEN + 4 + 1 + AES_BLOCK_SIZE];
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1], siv_len;
|
size_t len[2], siv_len, attr_len;
|
||||||
|
u8 *attr_start, *attr_end;
|
||||||
|
|
||||||
auth = os_zalloc(sizeof(*auth));
|
auth = os_zalloc(sizeof(*auth));
|
||||||
if (!auth)
|
if (!auth)
|
||||||
@ -1393,11 +1394,14 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Build DPP Authentication Request frame attributes */
|
/* Build DPP Authentication Request frame attributes */
|
||||||
msg = wpabuf_alloc(2 * (4 + SHA256_MAC_LEN) + 4 + wpabuf_len(pi) +
|
attr_len = 2 * (4 + SHA256_MAC_LEN) + 4 + wpabuf_len(pi) +
|
||||||
4 + sizeof(wrapped_data));
|
4 + sizeof(wrapped_data);
|
||||||
|
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ, attr_len);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
goto fail;
|
||||||
auth->req_attr = msg;
|
auth->req_msg = msg;
|
||||||
|
|
||||||
|
attr_start = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* Responder Bootstrapping Key Hash */
|
/* Responder Bootstrapping Key Hash */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
|
wpabuf_put_le16(msg, DPP_ATTR_R_BOOTSTRAP_KEY_HASH);
|
||||||
@ -1437,13 +1441,22 @@ struct dpp_authentication * dpp_auth_init(void *msg_ctx,
|
|||||||
DPP_CAPAB_ENROLLEE;
|
DPP_CAPAB_ENROLLEE;
|
||||||
*pos++ = auth->i_capab;
|
*pos++ = auth->i_capab;
|
||||||
|
|
||||||
addr[0] = wpabuf_head(msg);
|
attr_end = wpabuf_put(msg, 0);
|
||||||
len[0] = wpabuf_len(msg);
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||||
|
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||||
|
len[0] = 3 + 1 + 1 + 1;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
|
||||||
|
/* Attributes before Wrapped Data */
|
||||||
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_end - attr_start;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
|
|
||||||
siv_len = pos - clear;
|
siv_len = pos - clear;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
||||||
if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
|
if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
|
||||||
1, addr, len, wrapped_data) < 0)
|
2, addr, len, wrapped_data) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
siv_len += AES_BLOCK_SIZE;
|
siv_len += AES_BLOCK_SIZE;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
@ -1859,8 +1872,9 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
|||||||
u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
|
u8 clear[DPP_AUTH_RESP_CLEAR_LEN];
|
||||||
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
|
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN + AES_BLOCK_SIZE];
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1], siv_len;
|
size_t len[2], siv_len, attr_len;
|
||||||
|
u8 *attr_start, *attr_end;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
||||||
|
|
||||||
@ -1924,12 +1938,15 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
|||||||
wrapped_r_auth, wrapped_r_auth_len);
|
wrapped_r_auth, wrapped_r_auth_len);
|
||||||
|
|
||||||
/* Build DPP Authentication Response frame attributes */
|
/* Build DPP Authentication Response frame attributes */
|
||||||
msg = wpabuf_alloc(4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
||||||
4 + wpabuf_len(pr) + 4 + sizeof(wrapped_data));
|
4 + wpabuf_len(pr) + 4 + sizeof(wrapped_data);
|
||||||
|
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
goto fail;
|
||||||
wpabuf_free(auth->resp_attr);
|
wpabuf_free(auth->resp_msg);
|
||||||
auth->resp_attr = msg;
|
auth->resp_msg = msg;
|
||||||
|
|
||||||
|
attr_start = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* DPP Status */
|
/* DPP Status */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
||||||
@ -1957,6 +1974,8 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
|||||||
wpabuf_free(pr);
|
wpabuf_free(pr);
|
||||||
pr = NULL;
|
pr = NULL;
|
||||||
|
|
||||||
|
attr_end = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
|
/* Wrapped data ({R-nonce, I-nonce, R-capabilities, {R-auth}ke}k2) */
|
||||||
pos = clear;
|
pos = clear;
|
||||||
/* R-nonce */
|
/* R-nonce */
|
||||||
@ -1989,13 +2008,20 @@ static int dpp_auth_build_resp(struct dpp_authentication *auth)
|
|||||||
os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
|
os_memcpy(pos, wrapped_r_auth, wrapped_r_auth_len);
|
||||||
pos += wrapped_r_auth_len;
|
pos += wrapped_r_auth_len;
|
||||||
|
|
||||||
addr[0] = wpabuf_head(msg);
|
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||||
len[0] = wpabuf_len(msg);
|
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
len[0] = 3 + 1 + 1 + 1;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
|
||||||
|
/* Attributes before Wrapped Data */
|
||||||
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_end - attr_start;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
|
|
||||||
siv_len = pos - clear;
|
siv_len = pos - clear;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
||||||
if (aes_siv_encrypt(auth->k2, auth->curve->hash_len, clear, siv_len,
|
if (aes_siv_encrypt(auth->k2, auth->curve->hash_len, clear, siv_len,
|
||||||
1, addr, len, wrapped_data) < 0)
|
2, addr, len, wrapped_data) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
siv_len += AES_BLOCK_SIZE;
|
siv_len += AES_BLOCK_SIZE;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
@ -2025,18 +2051,21 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
|
|||||||
u8 clear[DPP_AUTH_RESP_CLEAR_LEN2];
|
u8 clear[DPP_AUTH_RESP_CLEAR_LEN2];
|
||||||
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN2 + AES_BLOCK_SIZE];
|
u8 wrapped_data[DPP_AUTH_RESP_CLEAR_LEN2 + AES_BLOCK_SIZE];
|
||||||
u8 *pos;
|
u8 *pos;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1], siv_len;
|
size_t len[2], siv_len, attr_len;
|
||||||
|
u8 *attr_start, *attr_end;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Response");
|
||||||
|
|
||||||
/* Build DPP Authentication Response frame attributes */
|
/* Build DPP Authentication Response frame attributes */
|
||||||
msg = wpabuf_alloc(4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) + 4 + sizeof(wrapped_data);
|
||||||
4 + sizeof(wrapped_data));
|
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP, attr_len);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
goto fail;
|
||||||
wpabuf_free(auth->resp_attr);
|
wpabuf_free(auth->resp_msg);
|
||||||
auth->resp_attr = msg;
|
auth->resp_msg = msg;
|
||||||
|
|
||||||
|
attr_start = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* DPP Status */
|
/* DPP Status */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
||||||
@ -2057,6 +2086,8 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
|
|||||||
SHA256_MAC_LEN);
|
SHA256_MAC_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attr_end = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* Wrapped data ({I-nonce, R-capabilities}k1) */
|
/* Wrapped data ({I-nonce, R-capabilities}k1) */
|
||||||
pos = clear;
|
pos = clear;
|
||||||
/* I-nonce */
|
/* I-nonce */
|
||||||
@ -2076,13 +2107,20 @@ static int dpp_auth_build_resp_status(struct dpp_authentication *auth,
|
|||||||
DPP_CAPAB_ENROLLEE;
|
DPP_CAPAB_ENROLLEE;
|
||||||
*pos++ = auth->r_capab;
|
*pos++ = auth->r_capab;
|
||||||
|
|
||||||
addr[0] = wpabuf_head(msg);
|
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||||
len[0] = wpabuf_len(msg);
|
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
len[0] = 3 + 1 + 1 + 1;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
|
||||||
|
/* Attributes before Wrapped Data */
|
||||||
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_end - attr_start;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
|
|
||||||
siv_len = pos - clear;
|
siv_len = pos - clear;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV cleartext", clear, siv_len);
|
||||||
if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
|
if (aes_siv_encrypt(auth->k1, auth->curve->hash_len, clear, siv_len,
|
||||||
1, addr, len, wrapped_data) < 0)
|
2, addr, len, wrapped_data) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
siv_len += AES_BLOCK_SIZE;
|
siv_len += AES_BLOCK_SIZE;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
@ -2106,14 +2144,14 @@ struct dpp_authentication *
|
|||||||
dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||||
struct dpp_bootstrap_info *peer_bi,
|
struct dpp_bootstrap_info *peer_bi,
|
||||||
struct dpp_bootstrap_info *own_bi,
|
struct dpp_bootstrap_info *own_bi,
|
||||||
unsigned int freq, const u8 *attr_start,
|
unsigned int freq, const u8 *hdr, const u8 *attr_start,
|
||||||
const u8 *wrapped_data, u16 wrapped_data_len)
|
const u8 *wrapped_data, u16 wrapped_data_len)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pi = NULL;
|
EVP_PKEY *pi = NULL;
|
||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
size_t secret_len;
|
size_t secret_len;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1];
|
size_t len[2];
|
||||||
u8 *unwrapped = NULL;
|
u8 *unwrapped = NULL;
|
||||||
size_t unwrapped_len = 0;
|
size_t unwrapped_len = 0;
|
||||||
const u8 *i_proto, *i_nonce, *i_capab, *i_bootstrap;
|
const u8 *i_proto, *i_nonce, *i_capab, *i_bootstrap;
|
||||||
@ -2176,9 +2214,12 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
|||||||
auth->curve->hash_len) < 0)
|
auth->curve->hash_len) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
addr[0] = attr_start;
|
addr[0] = hdr;
|
||||||
len[0] = attr_len;
|
len[0] = DPP_HDR_LEN;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_len;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
||||||
@ -2187,7 +2228,7 @@ dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
|||||||
goto fail;
|
goto fail;
|
||||||
if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
|
if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
|
||||||
wrapped_data, wrapped_data_len,
|
wrapped_data, wrapped_data_len,
|
||||||
1, addr, len, unwrapped) < 0) {
|
2, addr, len, unwrapped) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -2326,19 +2367,23 @@ static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth)
|
|||||||
struct wpabuf *msg;
|
struct wpabuf *msg;
|
||||||
u8 i_auth[4 + DPP_MAX_HASH_LEN];
|
u8 i_auth[4 + DPP_MAX_HASH_LEN];
|
||||||
size_t i_auth_len;
|
size_t i_auth_len;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1];
|
size_t len[2], attr_len;
|
||||||
u8 *wrapped_i_auth;
|
u8 *wrapped_i_auth;
|
||||||
|
u8 *attr_start, *attr_end;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
|
wpa_printf(MSG_DEBUG, "DPP: Build Authentication Confirmation");
|
||||||
|
|
||||||
i_auth_len = 4 + auth->curve->hash_len;
|
i_auth_len = 4 + auth->curve->hash_len;
|
||||||
/* Build DPP Authentication Confirmation frame attributes */
|
/* Build DPP Authentication Confirmation frame attributes */
|
||||||
msg = wpabuf_alloc(4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
attr_len = 4 + 1 + 2 * (4 + SHA256_MAC_LEN) +
|
||||||
4 + i_auth_len + AES_BLOCK_SIZE);
|
4 + i_auth_len + AES_BLOCK_SIZE;
|
||||||
|
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, attr_len);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
attr_start = wpabuf_put(msg, 0);
|
||||||
|
|
||||||
/* DPP Status */
|
/* DPP Status */
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
wpabuf_put_le16(msg, DPP_ATTR_STATUS);
|
||||||
wpabuf_put_le16(msg, 1);
|
wpabuf_put_le16(msg, 1);
|
||||||
@ -2357,8 +2402,18 @@ static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth)
|
|||||||
wpabuf_put_data(msg, auth->own_bi->pubkey_hash, SHA256_MAC_LEN);
|
wpabuf_put_data(msg, auth->own_bi->pubkey_hash, SHA256_MAC_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr[0] = wpabuf_head(msg);
|
attr_end = wpabuf_put(msg, 0);
|
||||||
len[0] = wpabuf_len(msg);
|
|
||||||
|
/* OUI, OUI type, Crypto Suite, DPP frame type */
|
||||||
|
addr[0] = wpabuf_head_u8(msg) + 2;
|
||||||
|
len[0] = 3 + 1 + 1 + 1;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
|
||||||
|
/* Attributes before Wrapped Data */
|
||||||
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_end - attr_start;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
|
|
||||||
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
wpabuf_put_le16(msg, DPP_ATTR_WRAPPED_DATA);
|
||||||
wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
|
wpabuf_put_le16(msg, i_auth_len + AES_BLOCK_SIZE);
|
||||||
wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
|
wrapped_i_auth = wpabuf_put(msg, i_auth_len + AES_BLOCK_SIZE);
|
||||||
@ -2368,7 +2423,7 @@ static struct wpabuf * dpp_auth_build_conf(struct dpp_authentication *auth)
|
|||||||
if (dpp_gen_i_auth(auth, i_auth + 4) < 0 ||
|
if (dpp_gen_i_auth(auth, i_auth + 4) < 0 ||
|
||||||
aes_siv_encrypt(auth->ke, auth->curve->hash_len,
|
aes_siv_encrypt(auth->ke, auth->curve->hash_len,
|
||||||
i_auth, i_auth_len,
|
i_auth, i_auth_len,
|
||||||
1, addr, len, wrapped_i_auth) < 0)
|
2, addr, len, wrapped_i_auth) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
|
wpa_hexdump(MSG_DEBUG, "DPP: {I-auth}ke",
|
||||||
wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
|
wrapped_i_auth, i_auth_len + AES_BLOCK_SIZE);
|
||||||
@ -2386,13 +2441,13 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dpp_auth_resp_rx_status(struct dpp_authentication *auth,
|
dpp_auth_resp_rx_status(struct dpp_authentication *auth, const u8 *hdr,
|
||||||
const u8 *attr_start, size_t attr_len,
|
const u8 *attr_start, size_t attr_len,
|
||||||
const u8 *wrapped_data, u16 wrapped_data_len,
|
const u8 *wrapped_data, u16 wrapped_data_len,
|
||||||
enum dpp_status_error status)
|
enum dpp_status_error status)
|
||||||
{
|
{
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1];
|
size_t len[2];
|
||||||
u8 *unwrapped = NULL;
|
u8 *unwrapped = NULL;
|
||||||
size_t unwrapped_len = 0;
|
size_t unwrapped_len = 0;
|
||||||
const u8 *i_nonce, *r_capab;
|
const u8 *i_nonce, *r_capab;
|
||||||
@ -2411,9 +2466,12 @@ dpp_auth_resp_rx_status(struct dpp_authentication *auth,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr[0] = attr_start;
|
addr[0] = hdr;
|
||||||
len[0] = attr_len;
|
len[0] = DPP_HDR_LEN;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_len;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
||||||
@ -2422,7 +2480,7 @@ dpp_auth_resp_rx_status(struct dpp_authentication *auth,
|
|||||||
goto fail;
|
goto fail;
|
||||||
if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
|
if (aes_siv_decrypt(auth->k1, auth->curve->hash_len,
|
||||||
wrapped_data, wrapped_data_len,
|
wrapped_data, wrapped_data_len,
|
||||||
1, addr, len, unwrapped) < 0) {
|
2, addr, len, unwrapped) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -2470,14 +2528,14 @@ fail:
|
|||||||
|
|
||||||
|
|
||||||
struct wpabuf *
|
struct wpabuf *
|
||||||
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||||
size_t attr_len)
|
const u8 *attr_start, size_t attr_len)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pr;
|
EVP_PKEY *pr;
|
||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
size_t secret_len;
|
size_t secret_len;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1];
|
size_t len[2];
|
||||||
u8 *unwrapped = NULL, *unwrapped2 = NULL;
|
u8 *unwrapped = NULL, *unwrapped2 = NULL;
|
||||||
size_t unwrapped_len = 0, unwrapped2_len = 0;
|
size_t unwrapped_len = 0, unwrapped2_len = 0;
|
||||||
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
|
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *r_proto,
|
||||||
@ -2551,7 +2609,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||||||
wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
|
wpa_printf(MSG_DEBUG, "DPP: Status %u", status[0]);
|
||||||
auth->auth_resp_status = status[0];
|
auth->auth_resp_status = status[0];
|
||||||
if (status[0] != DPP_STATUS_OK) {
|
if (status[0] != DPP_STATUS_OK) {
|
||||||
dpp_auth_resp_rx_status(auth, attr_start,
|
dpp_auth_resp_rx_status(auth, hdr, attr_start,
|
||||||
attr_len, wrapped_data,
|
attr_len, wrapped_data,
|
||||||
wrapped_data_len, status[0]);
|
wrapped_data_len, status[0]);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2599,9 +2657,12 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||||||
auth->curve->hash_len) < 0)
|
auth->curve->hash_len) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
addr[0] = attr_start;
|
addr[0] = hdr;
|
||||||
len[0] = attr_len;
|
len[0] = DPP_HDR_LEN;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_len;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
||||||
@ -2610,7 +2671,7 @@ dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||||||
goto fail;
|
goto fail;
|
||||||
if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
|
if (aes_siv_decrypt(auth->k2, auth->curve->hash_len,
|
||||||
wrapped_data, wrapped_data_len,
|
wrapped_data, wrapped_data_len,
|
||||||
1, addr, len, unwrapped) < 0) {
|
2, addr, len, unwrapped) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -2731,14 +2792,14 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||||
size_t attr_len)
|
const u8 *attr_start, size_t attr_len)
|
||||||
{
|
{
|
||||||
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
|
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data, *status, *i_auth;
|
||||||
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
|
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len, status_len,
|
||||||
i_auth_len;
|
i_auth_len;
|
||||||
const u8 *addr[1];
|
const u8 *addr[2];
|
||||||
size_t len[1];
|
size_t len[2];
|
||||||
u8 *unwrapped = NULL;
|
u8 *unwrapped = NULL;
|
||||||
size_t unwrapped_len = 0;
|
size_t unwrapped_len = 0;
|
||||||
u8 i_auth2[DPP_MAX_HASH_LEN];
|
u8 i_auth2[DPP_MAX_HASH_LEN];
|
||||||
@ -2812,9 +2873,12 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr[0] = attr_start;
|
addr[0] = hdr;
|
||||||
len[0] = attr_len;
|
len[0] = DPP_HDR_LEN;
|
||||||
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD", addr[0], len[0]);
|
addr[1] = attr_start;
|
||||||
|
len[1] = attr_len;
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[0]", addr[0], len[0]);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "DDP: AES-SIV AD[1]", addr[1], len[1]);
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
wpa_hexdump(MSG_DEBUG, "DPP: AES-SIV ciphertext",
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
unwrapped_len = wrapped_data_len - AES_BLOCK_SIZE;
|
||||||
@ -2823,7 +2887,7 @@ int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
|||||||
return -1;
|
return -1;
|
||||||
if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
|
if (aes_siv_decrypt(auth->ke, auth->curve->hash_len,
|
||||||
wrapped_data, wrapped_data_len,
|
wrapped_data, wrapped_data_len,
|
||||||
1, addr, len, unwrapped) < 0) {
|
2, addr, len, unwrapped) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
wpa_printf(MSG_DEBUG, "DPP: AES-SIV decryption failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -2882,8 +2946,8 @@ void dpp_auth_deinit(struct dpp_authentication *auth)
|
|||||||
dpp_configuration_free(auth->conf_sta);
|
dpp_configuration_free(auth->conf_sta);
|
||||||
EVP_PKEY_free(auth->own_protocol_key);
|
EVP_PKEY_free(auth->own_protocol_key);
|
||||||
EVP_PKEY_free(auth->peer_protocol_key);
|
EVP_PKEY_free(auth->peer_protocol_key);
|
||||||
wpabuf_free(auth->req_attr);
|
wpabuf_free(auth->req_msg);
|
||||||
wpabuf_free(auth->resp_attr);
|
wpabuf_free(auth->resp_msg);
|
||||||
wpabuf_free(auth->conf_req);
|
wpabuf_free(auth->conf_req);
|
||||||
os_free(auth->connector);
|
os_free(auth->connector);
|
||||||
wpabuf_free(auth->net_access_key);
|
wpabuf_free(auth->net_access_key);
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "common/wpa_common.h"
|
#include "common/wpa_common.h"
|
||||||
#include "crypto/sha256.h"
|
#include "crypto/sha256.h"
|
||||||
|
|
||||||
|
#define DPP_HDR_LEN (4 + 2) /* OUI, OUI Type, Crypto Suite, DPP frame type */
|
||||||
|
|
||||||
enum dpp_public_action_frame_type {
|
enum dpp_public_action_frame_type {
|
||||||
DPP_PA_AUTHENTICATION_REQ = 0,
|
DPP_PA_AUTHENTICATION_REQ = 0,
|
||||||
DPP_PA_AUTHENTICATION_RESP = 1,
|
DPP_PA_AUTHENTICATION_RESP = 1,
|
||||||
@ -151,8 +153,8 @@ struct dpp_authentication {
|
|||||||
u8 r_capab;
|
u8 r_capab;
|
||||||
EVP_PKEY *own_protocol_key;
|
EVP_PKEY *own_protocol_key;
|
||||||
EVP_PKEY *peer_protocol_key;
|
EVP_PKEY *peer_protocol_key;
|
||||||
struct wpabuf *req_attr;
|
struct wpabuf *req_msg;
|
||||||
struct wpabuf *resp_attr;
|
struct wpabuf *resp_msg;
|
||||||
unsigned int curr_freq;
|
unsigned int curr_freq;
|
||||||
size_t secret_len;
|
size_t secret_len;
|
||||||
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
u8 Mx[DPP_MAX_SHARED_SECRET_LEN];
|
||||||
@ -219,15 +221,15 @@ struct dpp_authentication *
|
|||||||
dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
dpp_auth_req_rx(void *msg_ctx, u8 dpp_allowed_roles, int qr_mutual,
|
||||||
struct dpp_bootstrap_info *peer_bi,
|
struct dpp_bootstrap_info *peer_bi,
|
||||||
struct dpp_bootstrap_info *own_bi,
|
struct dpp_bootstrap_info *own_bi,
|
||||||
unsigned int freq, const u8 *attr_start,
|
unsigned int freq, const u8 *hdr, const u8 *attr_start,
|
||||||
const u8 *wrapped_data, u16 wrapped_data_len);
|
const u8 *wrapped_data, u16 wrapped_data_len);
|
||||||
struct wpabuf *
|
struct wpabuf *
|
||||||
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
dpp_auth_resp_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||||
size_t attr_len);
|
const u8 *attr_start, size_t attr_len);
|
||||||
struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
|
struct wpabuf * dpp_build_conf_req(struct dpp_authentication *auth,
|
||||||
const char *json);
|
const char *json);
|
||||||
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *attr_start,
|
int dpp_auth_conf_rx(struct dpp_authentication *auth, const u8 *hdr,
|
||||||
size_t attr_len);
|
const u8 *attr_start, size_t attr_len);
|
||||||
int dpp_notify_new_qr_code(struct dpp_authentication *auth,
|
int dpp_notify_new_qr_code(struct dpp_authentication *auth,
|
||||||
struct dpp_bootstrap_info *peer_bi);
|
struct dpp_bootstrap_info *peer_bi);
|
||||||
void dpp_configuration_free(struct dpp_configuration *conf);
|
void dpp_configuration_free(struct dpp_configuration *conf);
|
||||||
|
@ -91,25 +91,16 @@ int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||||||
|
|
||||||
if (auth && auth->response_pending &&
|
if (auth && auth->response_pending &&
|
||||||
dpp_notify_new_qr_code(auth, bi) == 1) {
|
dpp_notify_new_qr_code(auth, bi) == 1) {
|
||||||
struct wpabuf *msg;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: Sending out pending authentication response");
|
"DPP: Sending out pending authentication response");
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
|
|
||||||
wpabuf_len(auth->resp_attr));
|
|
||||||
if (!msg)
|
|
||||||
goto out;
|
|
||||||
wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
|
|
||||||
|
|
||||||
offchannel_send_action(wpa_s, auth->curr_freq,
|
offchannel_send_action(wpa_s, auth->curr_freq,
|
||||||
auth->peer_mac_addr, wpa_s->own_addr,
|
auth->peer_mac_addr, wpa_s->own_addr,
|
||||||
broadcast,
|
broadcast,
|
||||||
wpabuf_head(msg), wpabuf_len(msg),
|
wpabuf_head(auth->resp_msg),
|
||||||
|
wpabuf_len(auth->resp_msg),
|
||||||
500, wpas_dpp_tx_status, 0);
|
500, wpas_dpp_tx_status, 0);
|
||||||
wpabuf_free(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
return bi->id;
|
return bi->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,7 +499,6 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||||||
{
|
{
|
||||||
const char *pos;
|
const char *pos;
|
||||||
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
|
struct dpp_bootstrap_info *peer_bi, *own_bi = NULL;
|
||||||
struct wpabuf *msg;
|
|
||||||
const u8 *dst;
|
const u8 *dst;
|
||||||
int res;
|
int res;
|
||||||
int configurator = 1;
|
int configurator = 1;
|
||||||
@ -581,12 +571,6 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||||||
else
|
else
|
||||||
wpa_s->dpp_auth->curr_freq = 2412;
|
wpa_s->dpp_auth->curr_freq = 2412;
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_REQ,
|
|
||||||
wpabuf_len(wpa_s->dpp_auth->req_attr));
|
|
||||||
if (!msg)
|
|
||||||
return -1;
|
|
||||||
wpabuf_put_buf(msg, wpa_s->dpp_auth->req_attr);
|
|
||||||
|
|
||||||
if (is_zero_ether_addr(peer_bi->mac_addr)) {
|
if (is_zero_ether_addr(peer_bi->mac_addr)) {
|
||||||
dst = broadcast;
|
dst = broadcast;
|
||||||
} else {
|
} else {
|
||||||
@ -604,9 +588,9 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd)
|
|||||||
wpa_s, NULL);
|
wpa_s, NULL);
|
||||||
res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
|
res = offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
|
||||||
dst, wpa_s->own_addr, broadcast,
|
dst, wpa_s->own_addr, broadcast,
|
||||||
wpabuf_head(msg), wpabuf_len(msg),
|
wpabuf_head(wpa_s->dpp_auth->req_msg),
|
||||||
|
wpabuf_len(wpa_s->dpp_auth->req_msg),
|
||||||
wait_time, wpas_dpp_tx_status, 0);
|
wait_time, wpas_dpp_tx_status, 0);
|
||||||
wpabuf_free(msg);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
fail:
|
fail:
|
||||||
@ -790,12 +774,12 @@ void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
|
|||||||
|
|
||||||
|
|
||||||
static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
|
static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||||
const u8 *buf, size_t len, unsigned int freq)
|
const u8 *hdr, const u8 *buf, size_t len,
|
||||||
|
unsigned int freq)
|
||||||
{
|
{
|
||||||
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
|
const u8 *r_bootstrap, *i_bootstrap, *wrapped_data;
|
||||||
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
|
u16 r_bootstrap_len, i_bootstrap_len, wrapped_data_len;
|
||||||
struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
|
struct dpp_bootstrap_info *bi, *own_bi = NULL, *peer_bi = NULL;
|
||||||
struct wpabuf *msg;
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
|
wpa_printf(MSG_DEBUG, "DPP: Authentication Request from " MACSTR,
|
||||||
MAC2STR(src));
|
MAC2STR(src));
|
||||||
@ -872,7 +856,7 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
wpa_s->dpp_auth_ok_on_ack = 0;
|
wpa_s->dpp_auth_ok_on_ack = 0;
|
||||||
wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles,
|
wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s, wpa_s->dpp_allowed_roles,
|
||||||
wpa_s->dpp_qr_mutual,
|
wpa_s->dpp_qr_mutual,
|
||||||
peer_bi, own_bi, freq, buf,
|
peer_bi, own_bi, freq, hdr, buf,
|
||||||
wrapped_data, wrapped_data_len);
|
wrapped_data, wrapped_data_len);
|
||||||
if (!wpa_s->dpp_auth) {
|
if (!wpa_s->dpp_auth) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: No response generated");
|
wpa_printf(MSG_DEBUG, "DPP: No response generated");
|
||||||
@ -883,17 +867,11 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
wpa_s->dpp_configurator_params);
|
wpa_s->dpp_configurator_params);
|
||||||
os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
|
os_memcpy(wpa_s->dpp_auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_RESP,
|
|
||||||
wpabuf_len(wpa_s->dpp_auth->resp_attr));
|
|
||||||
if (!msg)
|
|
||||||
return;
|
|
||||||
wpabuf_put_buf(msg, wpa_s->dpp_auth->resp_attr);
|
|
||||||
|
|
||||||
offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
|
offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
|
||||||
src, wpa_s->own_addr, broadcast,
|
src, wpa_s->own_addr, broadcast,
|
||||||
wpabuf_head(msg), wpabuf_len(msg),
|
wpabuf_head(wpa_s->dpp_auth->resp_msg),
|
||||||
|
wpabuf_len(wpa_s->dpp_auth->resp_msg),
|
||||||
500, wpas_dpp_tx_status, 0);
|
500, wpas_dpp_tx_status, 0);
|
||||||
wpabuf_free(msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1183,10 +1161,10 @@ static void wpas_dpp_auth_success(struct wpa_supplicant *wpa_s, int initiator)
|
|||||||
|
|
||||||
|
|
||||||
static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
|
static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||||
const u8 *buf, size_t len)
|
const u8 *hdr, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
||||||
struct wpabuf *msg, *attr;
|
struct wpabuf *msg;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
|
wpa_printf(MSG_DEBUG, "DPP: Authentication Response from " MACSTR,
|
||||||
MAC2STR(src));
|
MAC2STR(src));
|
||||||
@ -1206,8 +1184,8 @@ static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
|
|
||||||
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
|
||||||
|
|
||||||
attr = dpp_auth_resp_rx(auth, buf, len);
|
msg = dpp_auth_resp_rx(auth, hdr, buf, len);
|
||||||
if (!attr) {
|
if (!msg) {
|
||||||
if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
|
if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"DPP: Start wait for full response");
|
"DPP: Start wait for full response");
|
||||||
@ -1220,14 +1198,6 @@ static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
}
|
}
|
||||||
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
|
||||||
|
|
||||||
msg = dpp_alloc_msg(DPP_PA_AUTHENTICATION_CONF, wpabuf_len(attr));
|
|
||||||
if (!msg) {
|
|
||||||
wpabuf_free(attr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wpabuf_put_buf(msg, attr);
|
|
||||||
wpabuf_free(attr);
|
|
||||||
|
|
||||||
offchannel_send_action(wpa_s, auth->curr_freq,
|
offchannel_send_action(wpa_s, auth->curr_freq,
|
||||||
src, wpa_s->own_addr, broadcast,
|
src, wpa_s->own_addr, broadcast,
|
||||||
wpabuf_head(msg), wpabuf_len(msg),
|
wpabuf_head(msg), wpabuf_len(msg),
|
||||||
@ -1238,7 +1208,7 @@ static void wpas_dpp_rx_auth_resp(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
|
|
||||||
|
|
||||||
static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
|
static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
|
||||||
const u8 *buf, size_t len)
|
const u8 *hdr, const u8 *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
struct dpp_authentication *auth = wpa_s->dpp_auth;
|
||||||
|
|
||||||
@ -1257,7 +1227,7 @@ static void wpas_dpp_rx_auth_conf(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpp_auth_conf_rx(auth, buf, len) < 0) {
|
if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
|
||||||
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1589,9 +1559,15 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
{
|
{
|
||||||
u8 crypto_suite;
|
u8 crypto_suite;
|
||||||
enum dpp_public_action_frame_type type;
|
enum dpp_public_action_frame_type type;
|
||||||
|
const u8 *hdr;
|
||||||
|
|
||||||
if (len < 2)
|
if (len < DPP_HDR_LEN)
|
||||||
return;
|
return;
|
||||||
|
if (WPA_GET_BE24(buf) != OUI_WFA || buf[3] != DPP_OUI_TYPE)
|
||||||
|
return;
|
||||||
|
hdr = buf;
|
||||||
|
buf += 4;
|
||||||
|
len -= 4;
|
||||||
crypto_suite = *buf++;
|
crypto_suite = *buf++;
|
||||||
type = *buf++;
|
type = *buf++;
|
||||||
len -= 2;
|
len -= 2;
|
||||||
@ -1611,13 +1587,13 @@ void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src,
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DPP_PA_AUTHENTICATION_REQ:
|
case DPP_PA_AUTHENTICATION_REQ:
|
||||||
wpas_dpp_rx_auth_req(wpa_s, src, buf, len, freq);
|
wpas_dpp_rx_auth_req(wpa_s, src, hdr, buf, len, freq);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_AUTHENTICATION_RESP:
|
case DPP_PA_AUTHENTICATION_RESP:
|
||||||
wpas_dpp_rx_auth_resp(wpa_s, src, buf, len);
|
wpas_dpp_rx_auth_resp(wpa_s, src, hdr, buf, len);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_AUTHENTICATION_CONF:
|
case DPP_PA_AUTHENTICATION_CONF:
|
||||||
wpas_dpp_rx_auth_conf(wpa_s, src, buf, len);
|
wpas_dpp_rx_auth_conf(wpa_s, src, hdr, buf, len);
|
||||||
break;
|
break;
|
||||||
case DPP_PA_PEER_DISCOVERY_RESP:
|
case DPP_PA_PEER_DISCOVERY_RESP:
|
||||||
wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
|
wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
|
||||||
|
@ -3696,8 +3696,8 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
|
|||||||
payload[0] == WLAN_PA_VENDOR_SPECIFIC &&
|
payload[0] == WLAN_PA_VENDOR_SPECIFIC &&
|
||||||
WPA_GET_BE24(&payload[1]) == OUI_WFA &&
|
WPA_GET_BE24(&payload[1]) == OUI_WFA &&
|
||||||
payload[4] == DPP_OUI_TYPE) {
|
payload[4] == DPP_OUI_TYPE) {
|
||||||
payload += 5;
|
payload++;
|
||||||
plen -= 5;
|
plen--;
|
||||||
wpas_dpp_rx_action(wpa_s, mgmt->sa, payload, plen, freq);
|
wpas_dpp_rx_action(wpa_s, mgmt->sa, payload, plen, freq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user