struct crypto_bignum *hash_bn = NULL;
struct crypto_ec *ec = NULL;
- /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
+ /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
- wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR, MAC2STR(mac_init));
- addr[num_elem] = mac_init;
- len[num_elem] = ETH_ALEN;
- num_elem++;
+ if (mac_init) {
+ wpa_printf(MSG_DEBUG, "DPP: MAC-Initiator: " MACSTR,
+ MAC2STR(mac_init));
+ addr[num_elem] = mac_init;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
if (identifier) {
wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
identifier);
if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
goto fail;
wpa_hexdump_key(MSG_DEBUG,
- "DPP: H(MAC-Initiator | [identifier |] code)",
+ "DPP: H([MAC-Initiator |] [identifier |] code)",
hash, curve->hash_len);
Pi_key = dpp_pkex_get_role_elem(curve, 1);
if (!Pi_key)
struct crypto_bignum *hash_bn = NULL;
struct crypto_ec *ec = NULL;
- /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
+ /* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
- wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR, MAC2STR(mac_resp));
- addr[num_elem] = mac_resp;
- len[num_elem] = ETH_ALEN;
- num_elem++;
+ if (mac_resp) {
+ wpa_printf(MSG_DEBUG, "DPP: MAC-Responder: " MACSTR,
+ MAC2STR(mac_resp));
+ addr[num_elem] = mac_resp;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
if (identifier) {
wpa_printf(MSG_DEBUG, "DPP: code identifier: %s",
identifier);
if (dpp_hash_vector(curve, num_elem, addr, len, hash) < 0)
goto fail;
wpa_hexdump_key(MSG_DEBUG,
- "DPP: H(MAC-Responder | [identifier |] code)",
+ "DPP: H([MAC-Responder |] [identifier |] code)",
hash, curve->hash_len);
Pr_key = dpp_pkex_get_role_elem(curve, 0);
if (!Pr_key)
int dpp_pkex_derive_z(const u8 *mac_init, const u8 *mac_resp,
+ u8 ver_init, u8 ver_resp,
const u8 *Mx, size_t Mx_len,
const u8 *Nx, size_t Nx_len,
const char *code,
u8 *info, *pos;
size_t info_len;
- /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
+ /*
+ * v1: info = MAC-Initiator | MAC-Responder
+ * v2: info = Protocol Version-Initiator | Protocol Version-Responder
+ * z = HKDF(<>, info | M.x | N.x | code, K.x)
*/
/* HKDF-Extract(<>, IKM=K.x) */
return -1;
wpa_hexdump_key(MSG_DEBUG, "DPP: PRK = HKDF-Extract(<>, IKM)",
prk, hash_len);
- info_len = 2 * ETH_ALEN + Mx_len + Nx_len + os_strlen(code);
+ if (mac_init && mac_resp)
+ info_len = 2 * ETH_ALEN;
+ else
+ info_len = 2;
+ info_len += Mx_len + Nx_len + os_strlen(code);
info = os_malloc(info_len);
if (!info)
return -1;
pos = info;
- os_memcpy(pos, mac_init, ETH_ALEN);
- pos += ETH_ALEN;
- os_memcpy(pos, mac_resp, ETH_ALEN);
- pos += ETH_ALEN;
+ if (mac_init && mac_resp) {
+ os_memcpy(pos, mac_init, ETH_ALEN);
+ pos += ETH_ALEN;
+ os_memcpy(pos, mac_resp, ETH_ALEN);
+ pos += ETH_ALEN;
+ } else {
+ *pos++ = ver_init;
+ *pos++ = ver_resp;
+ }
os_memcpy(pos, Mx, Mx_len);
pos += Mx_len;
os_memcpy(pos, Nx, Nx_len);
#endif /* CONFIG_TESTING_OPTIONS */
-static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex)
+static struct wpabuf * dpp_pkex_build_exchange_req(struct dpp_pkex *pkex,
+ bool v2)
{
struct crypto_ec *ec = NULL;
const struct crypto_ec_point *X;
size_t attr_len;
const struct dpp_curve_params *curve = pkex->own_bi->curve;
- wpa_printf(MSG_DEBUG, "DPP: Build PKEX Exchange Request");
+ wpa_printf(MSG_DEBUG, "DPP: Build PKEX %sExchange Request",
+ v2 ? "" : "Version 1 ");
- /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
- Qi = dpp_pkex_derive_Qi(curve, pkex->own_mac, pkex->code,
+ /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
+ Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : pkex->own_mac, pkex->code,
pkex->identifier, &ec);
if (!Qi)
goto fail;
/* Initiator -> Responder: group, [identifier,] M */
attr_len = 4 + 2;
+#ifdef CONFIG_DPP2
+ if (v2)
+ attr_len += 4 + 1;
+#endif /* CONFIG_DPP2 */
if (pkex->identifier)
attr_len += 4 + os_strlen(pkex->identifier);
attr_len += 4 + 2 * curve->prime_len;
- msg = dpp_alloc_msg(DPP_PA_PKEX_EXCHANGE_REQ, attr_len);
+ msg = dpp_alloc_msg(v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+ DPP_PA_PKEX_V1_EXCHANGE_REQ, attr_len);
if (!msg)
goto fail;
+#ifdef CONFIG_DPP2
+ if (v2) {
+ /* Protocol Version */
+ wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
+ wpabuf_put_le16(msg, 1);
+ wpabuf_put_u8(msg, DPP_VERSION);
+ }
+#endif /* CONFIG_DPP2 */
+
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_NO_FINITE_CYCLIC_GROUP_PKEX_EXCHANGE_REQ) {
wpa_printf(MSG_INFO, "DPP: TESTING - no Finite Cyclic Group");
struct dpp_pkex * dpp_pkex_init(void *msg_ctx, struct dpp_bootstrap_info *bi,
const u8 *own_mac,
- const char *identifier,
- const char *code)
+ const char *identifier, const char *code,
+ bool v2)
{
struct dpp_pkex *pkex;
return NULL;
pkex->msg_ctx = msg_ctx;
pkex->initiator = 1;
+ pkex->v2 = v2;
pkex->own_bi = bi;
os_memcpy(pkex->own_mac, own_mac, ETH_ALEN);
if (identifier) {
pkex->code = os_strdup(code);
if (!pkex->code)
goto fail;
- pkex->exchange_req = dpp_pkex_build_exchange_req(pkex);
+ pkex->exchange_req = dpp_pkex_build_exchange_req(pkex, v2);
if (!pkex->exchange_req)
goto fail;
return pkex;
size_t attr_len;
const struct dpp_curve_params *curve = pkex->own_bi->curve;
- /* Initiator -> Responder: DPP Status, [identifier,] N */
+ /* Initiator -> Responder: DPP Status, [Protocol Version,] [identifier,]
+ * N */
attr_len = 4 + 1;
+#ifdef CONFIG_DPP2
+ if (pkex->v2)
+ attr_len += 4 + 1;
+#endif /* CONFIG_DPP2 */
if (pkex->identifier)
attr_len += 4 + os_strlen(pkex->identifier);
attr_len += 4 + 2 * curve->prime_len;
skip_status:
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_DPP2
+ if (pkex->v2) {
+ /* Protocol Version */
+ wpabuf_put_le16(msg, DPP_ATTR_PROTOCOL_VERSION);
+ wpabuf_put_le16(msg, 1);
+ wpabuf_put_u8(msg, DPP_VERSION);
+ }
+#endif /* CONFIG_DPP2 */
+
/* Code Identifier attribute */
if (pkex->identifier) {
wpabuf_put_le16(msg, DPP_ATTR_CODE_IDENTIFIER);
const u8 *peer_mac,
const char *identifier,
const char *code,
- const u8 *buf, size_t len)
+ const u8 *buf, size_t len, bool v2)
{
const u8 *attr_group, *attr_id, *attr_key;
u16 attr_group_len, attr_id_len, attr_key_len;
u8 Kx[DPP_MAX_SHARED_SECRET_LEN];
size_t Kx_len;
int res;
+ u8 peer_version = 0;
if (bi->pkex_t >= PKEX_COUNTER_T_LIMIT) {
wpa_msg(msg_ctx, MSG_INFO, DPP_EVENT_FAIL
return NULL;
}
+#ifdef CONFIG_DPP2
+ if (v2) {
+ const u8 *version;
+ u16 version_len;
+
+ version = dpp_get_attr(buf, len, DPP_ATTR_PROTOCOL_VERSION,
+ &version_len);
+ if (!version || version_len < 1 || version[0] == 0) {
+ wpa_msg(msg_ctx, MSG_INFO,
+ "Missing or invalid Protocol Version attribute");
+ return NULL;
+ }
+ peer_version = version[0];
+ wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
+ peer_version);
+ }
+#endif /* CONFIG_DPP2 */
+
#ifdef CONFIG_TESTING_OPTIONS
if (!is_zero_ether_addr(dpp_pkex_peer_mac_override)) {
wpa_printf(MSG_INFO, "DPP: TESTING - peer_mac override " MACSTR,
pkex = os_zalloc(sizeof(*pkex));
if (!pkex)
goto fail;
+ pkex->v2 = v2;
+ pkex->peer_version = peer_version;
pkex->own_bi = bi;
pkex->failed = 1;
pkex->exchange_resp = dpp_pkex_build_exchange_resp(
return NULL;
}
- /* Qi = H(MAC-Initiator | [identifier |] code) * Pi */
- Qi = dpp_pkex_derive_Qi(curve, peer_mac, code, identifier, &ec);
+ /* Qi = H([MAC-Initiator |] [identifier |] code) * Pi */
+ Qi = dpp_pkex_derive_Qi(curve, v2 ? NULL : peer_mac, code, identifier,
+ &ec);
if (!Qi)
goto fail;
pkex = os_zalloc(sizeof(*pkex));
if (!pkex)
goto fail;
+ pkex->v2 = v2;
+ pkex->peer_version = peer_version;
pkex->t = bi->pkex_t;
pkex->msg_ctx = msg_ctx;
pkex->own_bi = bi;
if (!pkex->x)
goto fail;
- /* Qr = H(MAC-Responder | | [identifier | ] code) * Pr */
- Qr = dpp_pkex_derive_Qr(curve, own_mac, code, identifier, NULL);
+ /* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
+ Qr = dpp_pkex_derive_Qr(curve, v2 ? NULL : own_mac, code, identifier,
+ NULL);
if (!Qr)
goto fail;
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
Kx, Kx_len);
- /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
- */
- res = dpp_pkex_derive_z(pkex->peer_mac, pkex->own_mac,
+ /* z = HKDF(<>, info | M.x | N.x | code, K.x) */
+ res = dpp_pkex_derive_z(pkex->v2 ? NULL : pkex->peer_mac,
+ pkex->v2 ? NULL : pkex->own_mac,
+ pkex->peer_version, DPP_VERSION,
pkex->Mx, curve->prime_len,
pkex->Nx, curve->prime_len, pkex->code,
Kx, Kx_len, pkex->z, curve->hash_len);
u8 Jx[DPP_MAX_SHARED_SECRET_LEN], Kx[DPP_MAX_SHARED_SECRET_LEN];
const u8 *addr[4];
size_t len[4];
+ size_t num_elem;
u8 u[DPP_MAX_HASH_LEN];
int res;
}
#endif /* CONFIG_TESTING_OPTIONS */
+#ifdef CONFIG_DPP2
+ if (pkex->v2) {
+ const u8 *version;
+ u16 version_len;
+
+ version = dpp_get_attr(buf, buflen, DPP_ATTR_PROTOCOL_VERSION,
+ &version_len);
+ if (!version || version_len < 1 || version[0] == 0) {
+ dpp_pkex_fail(pkex,
+ "Missing or invalid Protocol Version attribute");
+ return NULL;
+ }
+ pkex->peer_version = version[0];
+ wpa_printf(MSG_DEBUG, "DPP: Peer protocol version %u",
+ pkex->peer_version);
+ }
+#endif /* CONFIG_DPP2 */
+
os_memcpy(pkex->peer_mac, peer_mac, ETH_ALEN);
attr_status = dpp_get_attr(buf, buflen, DPP_ATTR_STATUS,
return NULL;
}
- /* Qr = H(MAC-Responder | [identifier |] code) * Pr */
- Qr = dpp_pkex_derive_Qr(curve, pkex->peer_mac, pkex->code,
- pkex->identifier, &ec);
+ /* Qr = H([MAC-Responder |] [identifier |] code) * Pr */
+ Qr = dpp_pkex_derive_Qr(curve, pkex->v2 ? NULL : pkex->peer_mac,
+ pkex->code, pkex->identifier, &ec);
if (!Qr)
goto fail;
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
Jx, Jx_len);
- /* u = HMAC(J.x, MAC-Initiator | A.x | Y'.x | X.x) */
+ /* u = HMAC(J.x, [MAC-Initiator |] A.x | Y'.x | X.x) */
A_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
if (!A_pub || !Y_pub || !X_pub)
goto fail;
- addr[0] = pkex->own_mac;
- len[0] = ETH_ALEN;
- addr[1] = wpabuf_head(A_pub);
- len[1] = wpabuf_len(A_pub) / 2;
- addr[2] = wpabuf_head(Y_pub);
- len[2] = wpabuf_len(Y_pub) / 2;
- addr[3] = wpabuf_head(X_pub);
- len[3] = wpabuf_len(X_pub) / 2;
- if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
+ num_elem = 0;
+ if (!pkex->v2) {
+ addr[num_elem] = pkex->own_mac;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
+ addr[num_elem] = wpabuf_head(A_pub);
+ len[num_elem] = wpabuf_len(A_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(Y_pub);
+ len[num_elem] = wpabuf_len(Y_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(X_pub);
+ len[num_elem] = wpabuf_len(X_pub) / 2;
+ num_elem++;
+ if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, num_elem, addr, len, u)
+ < 0)
goto fail;
wpa_hexdump(MSG_DEBUG, "DPP: u", u, curve->hash_len);
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (K.x)",
Kx, Kx_len);
- /* z = HKDF(<>, MAC-Initiator | MAC-Responder | M.x | N.x | code, K.x)
- */
- res = dpp_pkex_derive_z(pkex->own_mac, pkex->peer_mac,
+ /* z = HKDF(<>, info | M.x | N.x | code, K.x) */
+ res = dpp_pkex_derive_z(pkex->v2 ? NULL : pkex->own_mac,
+ pkex->v2 ? NULL : pkex->peer_mac,
+ DPP_VERSION, pkex->peer_version,
pkex->Mx, curve->prime_len,
attr_key /* N.x */, attr_key_len / 2,
pkex->code, Kx, Kx_len,
u16 wrapped_data_len, b_key_len, peer_u_len = 0;
const u8 *addr[4];
size_t len[4];
+ size_t num_elem;
u8 octet;
u8 *unwrapped = NULL;
size_t unwrapped_len = 0;
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (J.x)",
Jx, Jx_len);
- /* u' = HMAC(J'.x, MAC-Initiator | A'.x | Y.x | X'.x) */
+ /* u' = HMAC(J'.x, [MAC-Initiator |] A'.x | Y.x | X'.x) */
A_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
if (!A_pub || !Y_pub || !X_pub)
goto fail;
- addr[0] = pkex->peer_mac;
- len[0] = ETH_ALEN;
- addr[1] = wpabuf_head(A_pub);
- len[1] = wpabuf_len(A_pub) / 2;
- addr[2] = wpabuf_head(Y_pub);
- len[2] = wpabuf_len(Y_pub) / 2;
- addr[3] = wpabuf_head(X_pub);
- len[3] = wpabuf_len(X_pub) / 2;
- if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, 4, addr, len, u) < 0)
+ num_elem = 0;
+ if (!pkex->v2) {
+ addr[num_elem] = pkex->peer_mac;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
+ addr[num_elem] = wpabuf_head(A_pub);
+ len[num_elem] = wpabuf_len(A_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(Y_pub);
+ len[num_elem] = wpabuf_len(Y_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(X_pub);
+ len[num_elem] = wpabuf_len(X_pub) / 2;
+ num_elem++;
+ if (dpp_hmac_vector(curve->hash_len, Jx, Jx_len, num_elem, addr, len, u)
+ < 0)
goto fail;
peer_u = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_I_AUTH_TAG,
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
Lx, Lx_len);
- /* v = HMAC(L.x, MAC-Responder | B.x | X'.x | Y.x) */
+ /* v = HMAC(L.x, [MAC-Responder |] B.x | X'.x | Y.x) */
B_pub = crypto_ec_key_get_pubkey_point(pkex->own_bi->pubkey, 0);
if (!B_pub)
goto fail;
- addr[0] = pkex->own_mac;
- len[0] = ETH_ALEN;
- addr[1] = wpabuf_head(B_pub);
- len[1] = wpabuf_len(B_pub) / 2;
- addr[2] = wpabuf_head(X_pub);
- len[2] = wpabuf_len(X_pub) / 2;
- addr[3] = wpabuf_head(Y_pub);
- len[3] = wpabuf_len(Y_pub) / 2;
- if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
+ num_elem = 0;
+ if (!pkex->v2) {
+ addr[num_elem] = pkex->own_mac;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
+ addr[num_elem] = wpabuf_head(B_pub);
+ len[num_elem] = wpabuf_len(B_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(X_pub);
+ len[num_elem] = wpabuf_len(X_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(Y_pub);
+ len[num_elem] = wpabuf_len(Y_pub) / 2;
+ num_elem++;
+ if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, num_elem, addr, len, v)
+ < 0)
goto fail;
wpa_hexdump(MSG_DEBUG, "DPP: v", v, curve->hash_len);
u16 wrapped_data_len, b_key_len, peer_v_len = 0;
const u8 *addr[4];
size_t len[4];
+ size_t num_elem;
u8 octet;
u8 *unwrapped = NULL;
size_t unwrapped_len = 0;
wpa_hexdump_key(MSG_DEBUG, "DPP: ECDH shared secret (L.x)",
Lx, Lx_len);
- /* v' = HMAC(L.x, MAC-Responder | B'.x | X.x | Y'.x) */
+ /* v' = HMAC(L.x, [MAC-Responder |] B'.x | X.x | Y'.x) */
B_pub = crypto_ec_key_get_pubkey_point(pkex->peer_bootstrap_key, 0);
X_pub = crypto_ec_key_get_pubkey_point(pkex->x, 0);
Y_pub = crypto_ec_key_get_pubkey_point(pkex->y, 0);
if (!B_pub || !X_pub || !Y_pub)
goto fail;
- addr[0] = pkex->peer_mac;
- len[0] = ETH_ALEN;
- addr[1] = wpabuf_head(B_pub);
- len[1] = wpabuf_len(B_pub) / 2;
- addr[2] = wpabuf_head(X_pub);
- len[2] = wpabuf_len(X_pub) / 2;
- addr[3] = wpabuf_head(Y_pub);
- len[3] = wpabuf_len(Y_pub) / 2;
- if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, 4, addr, len, v) < 0)
+ num_elem = 0;
+ if (!pkex->v2) {
+ addr[num_elem] = pkex->peer_mac;
+ len[num_elem] = ETH_ALEN;
+ num_elem++;
+ }
+ addr[num_elem] = wpabuf_head(B_pub);
+ len[num_elem] = wpabuf_len(B_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(X_pub);
+ len[num_elem] = wpabuf_len(X_pub) / 2;
+ num_elem++;
+ addr[num_elem] = wpabuf_head(Y_pub);
+ len[num_elem] = wpabuf_len(Y_pub) / 2;
+ num_elem++;
+ if (dpp_hmac_vector(curve->hash_len, Lx, Lx_len, num_elem, addr, len, v)
+ < 0)
goto fail;
peer_v = dpp_get_attr(unwrapped, unwrapped_len, DPP_ATTR_R_AUTH_TAG,
wpa_printf(MSG_DEBUG, "DPP: Retransmit PKEX Exchange Request (try %u)",
pkex->exch_req_tries);
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
- MAC2STR(broadcast), pkex->freq, DPP_PA_PKEX_EXCHANGE_REQ);
+ MAC2STR(broadcast), pkex->freq,
+ pkex->v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+ DPP_PA_PKEX_V1_EXCHANGE_REQ);
offchannel_send_action(wpa_s, pkex->freq, broadcast,
wpa_s->own_addr, broadcast,
wpabuf_head(pkex->exchange_req),
static void
wpas_dpp_rx_pkex_exchange_req(struct wpa_supplicant *wpa_s, const u8 *src,
- const u8 *buf, size_t len, unsigned int freq)
+ const u8 *buf, size_t len, unsigned int freq,
+ bool v2)
{
struct wpabuf *msg;
unsigned int wait_time;
wpa_s->own_addr, src,
wpa_s->dpp_pkex_identifier,
wpa_s->dpp_pkex_code,
- buf, len);
+ buf, len, v2);
if (!wpa_s->dpp_pkex) {
wpa_printf(MSG_DEBUG,
"DPP: Failed to process the request - ignore it");
case DPP_PA_PEER_DISCOVERY_RESP:
wpas_dpp_rx_peer_disc_resp(wpa_s, src, buf, len);
break;
+#ifdef CONFIG_DPP3
case DPP_PA_PKEX_EXCHANGE_REQ:
- wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq);
+ /* This is for PKEXv2, but for now, process only with
+ * CONFIG_DPP3 to avoid issues with a capability that has not
+ * been tested with other implementations. */
+ wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq, true);
+ break;
+#endif /* CONFIG_DPP3 */
+ case DPP_PA_PKEX_V1_EXCHANGE_REQ:
+ wpas_dpp_rx_pkex_exchange_req(wpa_s, src, buf, len, freq,
+ false);
break;
case DPP_PA_PKEX_EXCHANGE_RESP:
wpas_dpp_rx_pkex_exchange_resp(wpa_s, src, buf, len, freq);
if (!wpa_s->dpp_pkex_code)
return -1;
- if (os_strstr(cmd, " init=1")) {
+ if (os_strstr(cmd, " init=1") || os_strstr(cmd, " init=2")) {
struct dpp_pkex *pkex;
struct wpabuf *msg;
+ bool v2 = os_strstr(cmd, " init=2") != NULL;
wpa_printf(MSG_DEBUG, "DPP: Initiating PKEX");
dpp_pkex_free(wpa_s->dpp_pkex);
wpa_s->dpp_pkex = dpp_pkex_init(wpa_s, own_bi, wpa_s->own_addr,
wpa_s->dpp_pkex_identifier,
- wpa_s->dpp_pkex_code);
+ wpa_s->dpp_pkex_code, v2);
pkex = wpa_s->dpp_pkex;
if (!pkex)
return -1;
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
" freq=%u type=%d",
MAC2STR(broadcast), pkex->freq,
- DPP_PA_PKEX_EXCHANGE_REQ);
+ v2 ? DPP_PA_PKEX_EXCHANGE_REQ :
+ DPP_PA_PKEX_V1_EXCHANGE_REQ);
offchannel_send_action(wpa_s, pkex->freq, broadcast,
wpa_s->own_addr, broadcast,
wpabuf_head(msg), wpabuf_len(msg),