2 * Wi-Fi Protected Setup - Enrollee
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "crypto/crypto.h"
13 #include "crypto/sha256.h"
14 #include "crypto/random.h"
16 #include "wps_dev_attr.h"
19 static int wps_build_wps_state(struct wps_data
*wps
, struct wpabuf
*msg
)
23 state
= wps
->wps
->wps_state
;
25 state
= WPS_STATE_NOT_CONFIGURED
;
26 wpa_printf(MSG_DEBUG
, "WPS: * Wi-Fi Protected Setup State (%d)",
28 wpabuf_put_be16(msg
, ATTR_WPS_STATE
);
29 wpabuf_put_be16(msg
, 1);
30 wpabuf_put_u8(msg
, state
);
35 static int wps_build_e_hash(struct wps_data
*wps
, struct wpabuf
*msg
)
41 if (random_get_bytes(wps
->snonce
, 2 * WPS_SECRET_NONCE_LEN
) < 0)
43 wpa_hexdump(MSG_DEBUG
, "WPS: E-S1", wps
->snonce
, WPS_SECRET_NONCE_LEN
);
44 wpa_hexdump(MSG_DEBUG
, "WPS: E-S2",
45 wps
->snonce
+ WPS_SECRET_NONCE_LEN
, WPS_SECRET_NONCE_LEN
);
47 if (wps
->dh_pubkey_e
== NULL
|| wps
->dh_pubkey_r
== NULL
) {
48 wpa_printf(MSG_DEBUG
, "WPS: DH public keys not available for "
53 wpa_printf(MSG_DEBUG
, "WPS: * E-Hash1");
54 wpabuf_put_be16(msg
, ATTR_E_HASH1
);
55 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
56 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
57 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
58 addr
[0] = wps
->snonce
;
59 len
[0] = WPS_SECRET_NONCE_LEN
;
62 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
63 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
64 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
65 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
66 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
67 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash1", hash
, SHA256_MAC_LEN
);
69 wpa_printf(MSG_DEBUG
, "WPS: * E-Hash2");
70 wpabuf_put_be16(msg
, ATTR_E_HASH2
);
71 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
72 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
73 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
74 addr
[0] = wps
->snonce
+ WPS_SECRET_NONCE_LEN
;
76 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
77 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash2", hash
, SHA256_MAC_LEN
);
83 static int wps_build_e_snonce1(struct wps_data
*wps
, struct wpabuf
*msg
)
85 wpa_printf(MSG_DEBUG
, "WPS: * E-SNonce1");
86 wpabuf_put_be16(msg
, ATTR_E_SNONCE1
);
87 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
88 wpabuf_put_data(msg
, wps
->snonce
, WPS_SECRET_NONCE_LEN
);
93 static int wps_build_e_snonce2(struct wps_data
*wps
, struct wpabuf
*msg
)
95 wpa_printf(MSG_DEBUG
, "WPS: * E-SNonce2");
96 wpabuf_put_be16(msg
, ATTR_E_SNONCE2
);
97 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
98 wpabuf_put_data(msg
, wps
->snonce
+ WPS_SECRET_NONCE_LEN
,
99 WPS_SECRET_NONCE_LEN
);
104 static struct wpabuf
* wps_build_m1(struct wps_data
*wps
)
109 if (random_get_bytes(wps
->nonce_e
, WPS_NONCE_LEN
) < 0)
111 wpa_hexdump(MSG_DEBUG
, "WPS: Enrollee Nonce",
112 wps
->nonce_e
, WPS_NONCE_LEN
);
114 wpa_printf(MSG_DEBUG
, "WPS: Building Message M1");
115 msg
= wpabuf_alloc(1000);
119 config_methods
= wps
->wps
->config_methods
;
120 if (wps
->wps
->ap
&& !wps
->pbc_in_m1
&&
121 (wps
->dev_password_len
!= 0 ||
122 (config_methods
& WPS_CONFIG_DISPLAY
))) {
124 * These are the methods that the AP supports as an Enrollee
125 * for adding external Registrars, so remove PushButton.
127 * As a workaround for Windows 7 mechanism for probing WPS
128 * capabilities from M1, leave PushButton option if no PIN
129 * method is available or if WPS configuration enables PBC
132 config_methods
&= ~WPS_CONFIG_PUSHBUTTON
;
134 config_methods
&= ~(WPS_CONFIG_VIRT_PUSHBUTTON
|
135 WPS_CONFIG_PHY_PUSHBUTTON
);
136 #endif /* CONFIG_WPS2 */
139 if (wps_build_version(msg
) ||
140 wps_build_msg_type(msg
, WPS_M1
) ||
141 wps_build_uuid_e(msg
, wps
->uuid_e
) ||
142 wps_build_mac_addr(msg
, wps
->mac_addr_e
) ||
143 wps_build_enrollee_nonce(wps
, msg
) ||
144 wps_build_public_key(wps
, msg
) ||
145 wps_build_auth_type_flags(wps
, msg
) ||
146 wps_build_encr_type_flags(wps
, msg
) ||
147 wps_build_conn_type_flags(wps
, msg
) ||
148 wps_build_config_methods(msg
, config_methods
) ||
149 wps_build_wps_state(wps
, msg
) ||
150 wps_build_device_attrs(&wps
->wps
->dev
, msg
) ||
151 wps_build_rf_bands(&wps
->wps
->dev
, msg
,
152 wps
->wps
->rf_band_cb(wps
->wps
->cb_ctx
)) ||
153 wps_build_assoc_state(wps
, msg
) ||
154 wps_build_dev_password_id(msg
, wps
->dev_pw_id
) ||
155 wps_build_config_error(msg
, WPS_CFG_NO_ERROR
) ||
156 wps_build_os_version(&wps
->wps
->dev
, msg
) ||
157 wps_build_wfa_ext(msg
, 0, NULL
, 0) ||
158 wps_build_vendor_ext_m1(&wps
->wps
->dev
, msg
)) {
163 wps
->state
= RECV_M2
;
168 static struct wpabuf
* wps_build_m3(struct wps_data
*wps
)
172 wpa_printf(MSG_DEBUG
, "WPS: Building Message M3");
174 if (wps
->dev_password
== NULL
) {
175 wpa_printf(MSG_DEBUG
, "WPS: No Device Password available");
178 wps_derive_psk(wps
, wps
->dev_password
, wps
->dev_password_len
);
180 msg
= wpabuf_alloc(1000);
184 if (wps_build_version(msg
) ||
185 wps_build_msg_type(msg
, WPS_M3
) ||
186 wps_build_registrar_nonce(wps
, msg
) ||
187 wps_build_e_hash(wps
, msg
) ||
188 wps_build_wfa_ext(msg
, 0, NULL
, 0) ||
189 wps_build_authenticator(wps
, msg
)) {
194 wps
->state
= RECV_M4
;
199 static struct wpabuf
* wps_build_m5(struct wps_data
*wps
)
201 struct wpabuf
*msg
, *plain
;
203 wpa_printf(MSG_DEBUG
, "WPS: Building Message M5");
205 plain
= wpabuf_alloc(200);
209 msg
= wpabuf_alloc(1000);
215 if (wps_build_version(msg
) ||
216 wps_build_msg_type(msg
, WPS_M5
) ||
217 wps_build_registrar_nonce(wps
, msg
) ||
218 wps_build_e_snonce1(wps
, plain
) ||
219 wps_build_key_wrap_auth(wps
, plain
) ||
220 wps_build_encr_settings(wps
, msg
, plain
) ||
221 wps_build_wfa_ext(msg
, 0, NULL
, 0) ||
222 wps_build_authenticator(wps
, msg
)) {
229 wps
->state
= RECV_M6
;
234 static int wps_build_cred_ssid(struct wps_data
*wps
, struct wpabuf
*msg
)
236 wpa_printf(MSG_DEBUG
, "WPS: * SSID");
237 wpabuf_put_be16(msg
, ATTR_SSID
);
238 wpabuf_put_be16(msg
, wps
->wps
->ssid_len
);
239 wpabuf_put_data(msg
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
244 static int wps_build_cred_auth_type(struct wps_data
*wps
, struct wpabuf
*msg
)
246 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type (0x%x)",
247 wps
->wps
->ap_auth_type
);
248 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE
);
249 wpabuf_put_be16(msg
, 2);
250 wpabuf_put_be16(msg
, wps
->wps
->ap_auth_type
);
255 static int wps_build_cred_encr_type(struct wps_data
*wps
, struct wpabuf
*msg
)
257 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type (0x%x)",
258 wps
->wps
->ap_encr_type
);
259 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE
);
260 wpabuf_put_be16(msg
, 2);
261 wpabuf_put_be16(msg
, wps
->wps
->ap_encr_type
);
266 static int wps_build_cred_network_key(struct wps_data
*wps
, struct wpabuf
*msg
)
268 if ((wps
->wps
->ap_auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) &&
269 wps
->wps
->network_key_len
== 0) {
272 /* Generate a random per-device PSK */
273 if (random_get_bytes(psk
, sizeof(psk
)) < 0)
275 wpa_hexdump_key(MSG_DEBUG
, "WPS: Generated per-device PSK",
277 wpa_printf(MSG_DEBUG
, "WPS: * Network Key (len=%u)",
278 (unsigned int) wps
->new_psk_len
* 2);
279 wpa_snprintf_hex(hex
, sizeof(hex
), psk
, sizeof(psk
));
280 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
281 wpabuf_put_be16(msg
, sizeof(psk
) * 2);
282 wpabuf_put_data(msg
, hex
, sizeof(psk
) * 2);
283 if (wps
->wps
->registrar
) {
284 wps_cb_new_psk(wps
->wps
->registrar
,
285 wps
->peer_dev
.mac_addr
,
286 wps
->p2p_dev_addr
, psk
, sizeof(psk
));
291 wpa_printf(MSG_DEBUG
, "WPS: * Network Key (len=%u)",
292 (unsigned int) wps
->wps
->network_key_len
);
293 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
294 wpabuf_put_be16(msg
, wps
->wps
->network_key_len
);
295 wpabuf_put_data(msg
, wps
->wps
->network_key
, wps
->wps
->network_key_len
);
300 static int wps_build_cred_mac_addr(struct wps_data
*wps
, struct wpabuf
*msg
)
302 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address (AP BSSID)");
303 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
304 wpabuf_put_be16(msg
, ETH_ALEN
);
305 wpabuf_put_data(msg
, wps
->wps
->dev
.mac_addr
, ETH_ALEN
);
310 static int wps_build_ap_settings(struct wps_data
*wps
, struct wpabuf
*plain
)
312 const u8
*start
, *end
;
315 if (wps
->wps
->ap_settings
) {
316 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings (pre-configured)");
317 wpabuf_put_data(plain
, wps
->wps
->ap_settings
,
318 wps
->wps
->ap_settings_len
);
322 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings based on current configuration");
323 start
= wpabuf_put(plain
, 0);
324 ret
= wps_build_cred_ssid(wps
, plain
) ||
325 wps_build_cred_mac_addr(wps
, plain
) ||
326 wps_build_cred_auth_type(wps
, plain
) ||
327 wps_build_cred_encr_type(wps
, plain
) ||
328 wps_build_cred_network_key(wps
, plain
);
329 end
= wpabuf_put(plain
, 0);
331 wpa_hexdump_key(MSG_DEBUG
, "WPS: Plaintext AP Settings",
338 static struct wpabuf
* wps_build_m7(struct wps_data
*wps
)
340 struct wpabuf
*msg
, *plain
;
342 wpa_printf(MSG_DEBUG
, "WPS: Building Message M7");
344 plain
= wpabuf_alloc(500 + wps
->wps
->ap_settings_len
);
348 msg
= wpabuf_alloc(1000 + wps
->wps
->ap_settings_len
);
354 if (wps_build_version(msg
) ||
355 wps_build_msg_type(msg
, WPS_M7
) ||
356 wps_build_registrar_nonce(wps
, msg
) ||
357 wps_build_e_snonce2(wps
, plain
) ||
358 (wps
->wps
->ap
&& wps_build_ap_settings(wps
, plain
)) ||
359 wps_build_key_wrap_auth(wps
, plain
) ||
360 wps_build_encr_settings(wps
, msg
, plain
) ||
361 wps_build_wfa_ext(msg
, 0, NULL
, 0) ||
362 wps_build_authenticator(wps
, msg
)) {
369 if (wps
->wps
->ap
&& wps
->wps
->registrar
) {
371 * If the Registrar is only learning our current configuration,
372 * it may not continue protocol run to successful completion.
373 * Store information here to make sure it remains available.
375 wps_device_store(wps
->wps
->registrar
, &wps
->peer_dev
,
379 wps
->state
= RECV_M8
;
384 static struct wpabuf
* wps_build_wsc_done(struct wps_data
*wps
)
388 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_Done");
390 msg
= wpabuf_alloc(1000);
394 if (wps_build_version(msg
) ||
395 wps_build_msg_type(msg
, WPS_WSC_DONE
) ||
396 wps_build_enrollee_nonce(wps
, msg
) ||
397 wps_build_registrar_nonce(wps
, msg
) ||
398 wps_build_wfa_ext(msg
, 0, NULL
, 0)) {
404 wps
->state
= RECV_ACK
;
406 wps_success_event(wps
->wps
, wps
->peer_dev
.mac_addr
);
407 wps
->state
= WPS_FINISHED
;
413 struct wpabuf
* wps_enrollee_get_msg(struct wps_data
*wps
,
414 enum wsc_op_code
*op_code
)
418 switch (wps
->state
) {
420 msg
= wps_build_m1(wps
);
424 msg
= wps_build_m3(wps
);
428 msg
= wps_build_m5(wps
);
432 msg
= wps_build_m7(wps
);
437 msg
= wps_build_wsc_nack(wps
);
441 msg
= wps_build_wsc_ack(wps
);
444 /* Another M2/M2D may be received */
445 wps
->state
= RECV_M2
;
449 msg
= wps_build_wsc_nack(wps
);
453 msg
= wps_build_wsc_done(wps
);
457 wpa_printf(MSG_DEBUG
, "WPS: Unsupported state %d for building "
458 "a message", wps
->state
);
463 if (*op_code
== WSC_MSG
&& msg
) {
464 /* Save a copy of the last message for Authenticator derivation
466 wpabuf_free(wps
->last_msg
);
467 wps
->last_msg
= wpabuf_dup(msg
);
474 static int wps_process_registrar_nonce(struct wps_data
*wps
, const u8
*r_nonce
)
476 if (r_nonce
== NULL
) {
477 wpa_printf(MSG_DEBUG
, "WPS: No Registrar Nonce received");
481 os_memcpy(wps
->nonce_r
, r_nonce
, WPS_NONCE_LEN
);
482 wpa_hexdump(MSG_DEBUG
, "WPS: Registrar Nonce",
483 wps
->nonce_r
, WPS_NONCE_LEN
);
489 static int wps_process_enrollee_nonce(struct wps_data
*wps
, const u8
*e_nonce
)
491 if (e_nonce
== NULL
) {
492 wpa_printf(MSG_DEBUG
, "WPS: No Enrollee Nonce received");
496 if (os_memcmp(wps
->nonce_e
, e_nonce
, WPS_NONCE_LEN
) != 0) {
497 wpa_printf(MSG_DEBUG
, "WPS: Invalid Enrollee Nonce received");
505 static int wps_process_uuid_r(struct wps_data
*wps
, const u8
*uuid_r
)
507 if (uuid_r
== NULL
) {
508 wpa_printf(MSG_DEBUG
, "WPS: No UUID-R received");
512 os_memcpy(wps
->uuid_r
, uuid_r
, WPS_UUID_LEN
);
513 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-R", wps
->uuid_r
, WPS_UUID_LEN
);
519 static int wps_process_pubkey(struct wps_data
*wps
, const u8
*pk
,
522 if (pk
== NULL
|| pk_len
== 0) {
523 wpa_printf(MSG_DEBUG
, "WPS: No Public Key received");
527 if (wps
->peer_pubkey_hash_set
) {
528 u8 hash
[WPS_HASH_LEN
];
529 sha256_vector(1, &pk
, &pk_len
, hash
);
530 if (os_memcmp(hash
, wps
->peer_pubkey_hash
,
531 WPS_OOB_PUBKEY_HASH_LEN
) != 0) {
532 wpa_printf(MSG_ERROR
, "WPS: Public Key hash mismatch");
533 wpa_hexdump(MSG_DEBUG
, "WPS: Received public key",
535 wpa_hexdump(MSG_DEBUG
, "WPS: Calculated public key "
536 "hash", hash
, WPS_OOB_PUBKEY_HASH_LEN
);
537 wpa_hexdump(MSG_DEBUG
, "WPS: Expected public key hash",
538 wps
->peer_pubkey_hash
,
539 WPS_OOB_PUBKEY_HASH_LEN
);
540 wps
->config_error
= WPS_CFG_PUBLIC_KEY_HASH_MISMATCH
;
545 wpabuf_free(wps
->dh_pubkey_r
);
546 wps
->dh_pubkey_r
= wpabuf_alloc_copy(pk
, pk_len
);
547 if (wps
->dh_pubkey_r
== NULL
)
550 if (wps_derive_keys(wps
) < 0)
557 static int wps_process_r_hash1(struct wps_data
*wps
, const u8
*r_hash1
)
559 if (r_hash1
== NULL
) {
560 wpa_printf(MSG_DEBUG
, "WPS: No R-Hash1 received");
564 os_memcpy(wps
->peer_hash1
, r_hash1
, WPS_HASH_LEN
);
565 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash1", wps
->peer_hash1
, WPS_HASH_LEN
);
571 static int wps_process_r_hash2(struct wps_data
*wps
, const u8
*r_hash2
)
573 if (r_hash2
== NULL
) {
574 wpa_printf(MSG_DEBUG
, "WPS: No R-Hash2 received");
578 os_memcpy(wps
->peer_hash2
, r_hash2
, WPS_HASH_LEN
);
579 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash2", wps
->peer_hash2
, WPS_HASH_LEN
);
585 static int wps_process_r_snonce1(struct wps_data
*wps
, const u8
*r_snonce1
)
587 u8 hash
[SHA256_MAC_LEN
];
591 if (r_snonce1
== NULL
) {
592 wpa_printf(MSG_DEBUG
, "WPS: No R-SNonce1 received");
596 wpa_hexdump_key(MSG_DEBUG
, "WPS: R-SNonce1", r_snonce1
,
597 WPS_SECRET_NONCE_LEN
);
599 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
601 len
[0] = WPS_SECRET_NONCE_LEN
;
603 len
[1] = WPS_PSK_LEN
;
604 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
605 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
606 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
607 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
608 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
610 if (os_memcmp(wps
->peer_hash1
, hash
, WPS_HASH_LEN
) != 0) {
611 wpa_printf(MSG_DEBUG
, "WPS: R-Hash1 derived from R-S1 does "
612 "not match with the pre-committed value");
613 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
614 wps_pwd_auth_fail_event(wps
->wps
, 1, 1, wps
->peer_dev
.mac_addr
);
618 wpa_printf(MSG_DEBUG
, "WPS: Registrar proved knowledge of the first "
619 "half of the device password");
625 static int wps_process_r_snonce2(struct wps_data
*wps
, const u8
*r_snonce2
)
627 u8 hash
[SHA256_MAC_LEN
];
631 if (r_snonce2
== NULL
) {
632 wpa_printf(MSG_DEBUG
, "WPS: No R-SNonce2 received");
636 wpa_hexdump_key(MSG_DEBUG
, "WPS: R-SNonce2", r_snonce2
,
637 WPS_SECRET_NONCE_LEN
);
639 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
641 len
[0] = WPS_SECRET_NONCE_LEN
;
643 len
[1] = WPS_PSK_LEN
;
644 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
645 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
646 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
647 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
648 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
650 if (os_memcmp(wps
->peer_hash2
, hash
, WPS_HASH_LEN
) != 0) {
651 wpa_printf(MSG_DEBUG
, "WPS: R-Hash2 derived from R-S2 does "
652 "not match with the pre-committed value");
653 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
654 wps_pwd_auth_fail_event(wps
->wps
, 1, 2, wps
->peer_dev
.mac_addr
);
658 wpa_printf(MSG_DEBUG
, "WPS: Registrar proved knowledge of the second "
659 "half of the device password");
665 static int wps_process_cred_e(struct wps_data
*wps
, const u8
*cred
,
666 size_t cred_len
, int wps2
)
668 struct wps_parse_attr attr
;
672 wpa_printf(MSG_DEBUG
, "WPS: Received Credential");
673 os_memset(&wps
->cred
, 0, sizeof(wps
->cred
));
674 wpabuf_set(&msg
, cred
, cred_len
);
675 if (wps_parse_msg(&msg
, &attr
) < 0 ||
676 wps_process_cred(&attr
, &wps
->cred
))
679 if (os_memcmp(wps
->cred
.mac_addr
, wps
->wps
->dev
.mac_addr
, ETH_ALEN
) !=
681 wpa_printf(MSG_DEBUG
, "WPS: MAC Address in the Credential ("
682 MACSTR
") does not match with own address (" MACSTR
683 ")", MAC2STR(wps
->cred
.mac_addr
),
684 MAC2STR(wps
->wps
->dev
.mac_addr
));
686 * In theory, this could be consider fatal error, but there are
687 * number of deployed implementations using other address here
688 * due to unclarity in the specification. For interoperability
689 * reasons, allow this to be processed since we do not really
690 * use the MAC Address information for anything.
692 #ifdef CONFIG_WPS_STRICT
694 wpa_printf(MSG_INFO
, "WPS: Do not accept incorrect "
695 "MAC Address in AP Settings");
698 #endif /* CONFIG_WPS_STRICT */
702 if (!(wps
->cred
.encr_type
&
703 (WPS_ENCR_NONE
| WPS_ENCR_TKIP
| WPS_ENCR_AES
))) {
704 if (wps
->cred
.encr_type
& WPS_ENCR_WEP
) {
705 wpa_printf(MSG_INFO
, "WPS: Reject Credential "
706 "due to WEP configuration");
707 wps
->error_indication
= WPS_EI_SECURITY_WEP_PROHIBITED
;
711 wpa_printf(MSG_INFO
, "WPS: Reject Credential due to "
712 "invalid encr_type 0x%x", wps
->cred
.encr_type
);
715 #endif /* CONFIG_WPS2 */
717 if (wps
->wps
->cred_cb
) {
718 wps
->cred
.cred_attr
= cred
- 4;
719 wps
->cred
.cred_attr_len
= cred_len
+ 4;
720 ret
= wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &wps
->cred
);
721 wps
->cred
.cred_attr
= NULL
;
722 wps
->cred
.cred_attr_len
= 0;
729 static int wps_process_creds(struct wps_data
*wps
, const u8
*cred
[],
730 size_t cred_len
[], size_t num_cred
, int wps2
)
739 wpa_printf(MSG_DEBUG
, "WPS: No Credential attributes "
744 for (i
= 0; i
< num_cred
; i
++) {
746 res
= wps_process_cred_e(wps
, cred
[i
], cred_len
[i
], wps2
);
750 wpa_printf(MSG_DEBUG
, "WPS: WEP credential skipped");
756 wpa_printf(MSG_DEBUG
, "WPS: No valid Credential attribute "
765 static int wps_process_ap_settings_e(struct wps_data
*wps
,
766 struct wps_parse_attr
*attr
,
767 struct wpabuf
*attrs
, int wps2
)
769 struct wps_credential cred
;
774 if (wps_process_ap_settings(attr
, &cred
) < 0)
777 wpa_printf(MSG_INFO
, "WPS: Received new AP configuration from "
780 if (os_memcmp(cred
.mac_addr
, wps
->wps
->dev
.mac_addr
, ETH_ALEN
) !=
782 wpa_printf(MSG_DEBUG
, "WPS: MAC Address in the AP Settings ("
783 MACSTR
") does not match with own address (" MACSTR
784 ")", MAC2STR(cred
.mac_addr
),
785 MAC2STR(wps
->wps
->dev
.mac_addr
));
787 * In theory, this could be consider fatal error, but there are
788 * number of deployed implementations using other address here
789 * due to unclarity in the specification. For interoperability
790 * reasons, allow this to be processed since we do not really
791 * use the MAC Address information for anything.
793 #ifdef CONFIG_WPS_STRICT
795 wpa_printf(MSG_INFO
, "WPS: Do not accept incorrect "
796 "MAC Address in AP Settings");
799 #endif /* CONFIG_WPS_STRICT */
803 if (!(cred
.encr_type
& (WPS_ENCR_NONE
| WPS_ENCR_TKIP
| WPS_ENCR_AES
)))
805 if (cred
.encr_type
& WPS_ENCR_WEP
) {
806 wpa_printf(MSG_INFO
, "WPS: Reject new AP settings "
807 "due to WEP configuration");
808 wps
->error_indication
= WPS_EI_SECURITY_WEP_PROHIBITED
;
812 wpa_printf(MSG_INFO
, "WPS: Reject new AP settings due to "
813 "invalid encr_type 0x%x", cred
.encr_type
);
816 #endif /* CONFIG_WPS2 */
818 #ifdef CONFIG_WPS_STRICT
820 if ((cred
.encr_type
& (WPS_ENCR_TKIP
| WPS_ENCR_AES
)) ==
822 (cred
.auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) ==
824 wpa_printf(MSG_INFO
, "WPS-STRICT: Invalid WSC 2.0 "
825 "AP Settings: WPA-Personal/TKIP only");
826 wps
->error_indication
=
827 WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED
;
831 #endif /* CONFIG_WPS_STRICT */
834 if ((cred
.encr_type
& (WPS_ENCR_TKIP
| WPS_ENCR_AES
)) == WPS_ENCR_TKIP
)
836 wpa_printf(MSG_DEBUG
, "WPS: Upgrade encr_type TKIP -> "
838 cred
.encr_type
|= WPS_ENCR_AES
;
841 if ((cred
.auth_type
& (WPS_AUTH_WPAPSK
| WPS_AUTH_WPA2PSK
)) ==
843 wpa_printf(MSG_DEBUG
, "WPS: Upgrade auth_type WPAPSK -> "
845 cred
.auth_type
|= WPS_AUTH_WPA2PSK
;
847 #endif /* CONFIG_WPS2 */
849 if (wps
->wps
->cred_cb
) {
850 cred
.cred_attr
= wpabuf_head(attrs
);
851 cred
.cred_attr_len
= wpabuf_len(attrs
);
852 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &cred
);
859 static int wps_process_dev_pw_id(struct wps_data
*wps
, const u8
*dev_pw_id
)
863 if (dev_pw_id
== NULL
) {
864 wpa_printf(MSG_DEBUG
, "WPS: Device Password ID");
868 id
= WPA_GET_BE16(dev_pw_id
);
869 if (wps
->dev_pw_id
== id
) {
870 wpa_printf(MSG_DEBUG
, "WPS: Device Password ID %u", id
);
875 if ((id
== DEV_PW_DEFAULT
&&
876 wps
->dev_pw_id
== DEV_PW_REGISTRAR_SPECIFIED
) ||
877 (id
== DEV_PW_REGISTRAR_SPECIFIED
&&
878 wps
->dev_pw_id
== DEV_PW_DEFAULT
)) {
880 * Common P2P use cases indicate whether the PIN is from the
881 * client or GO using Device Password Id in M1/M2 in a way that
882 * does not look fully compliant with WSC specification. Anyway,
883 * this is deployed and needs to be allowed, so ignore changes
884 * between Registrar-Specified and Default PIN.
886 wpa_printf(MSG_DEBUG
, "WPS: Allow PIN Device Password ID "
890 #endif /* CONFIG_P2P */
892 wpa_printf(MSG_DEBUG
, "WPS: Registrar trying to change Device Password "
893 "ID from %u to %u", wps
->dev_pw_id
, id
);
895 if (wps
->dev_pw_id
== DEV_PW_PUSHBUTTON
&& id
== DEV_PW_DEFAULT
) {
896 wpa_printf(MSG_DEBUG
,
897 "WPS: Workaround - ignore PBC-to-PIN change");
901 if (wps
->alt_dev_password
&& wps
->alt_dev_pw_id
== id
) {
902 wpa_printf(MSG_DEBUG
, "WPS: Found a matching Device Password");
903 os_free(wps
->dev_password
);
904 wps
->dev_pw_id
= wps
->alt_dev_pw_id
;
905 wps
->dev_password
= wps
->alt_dev_password
;
906 wps
->dev_password_len
= wps
->alt_dev_password_len
;
907 wps
->alt_dev_password
= NULL
;
908 wps
->alt_dev_password_len
= 0;
916 static enum wps_process_res
wps_process_m2(struct wps_data
*wps
,
917 const struct wpabuf
*msg
,
918 struct wps_parse_attr
*attr
)
920 wpa_printf(MSG_DEBUG
, "WPS: Received M2");
922 if (wps
->state
!= RECV_M2
) {
923 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
924 "receiving M2", wps
->state
);
925 wps
->state
= SEND_WSC_NACK
;
929 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
930 wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
931 wps_process_uuid_r(wps
, attr
->uuid_r
) ||
932 wps_process_dev_pw_id(wps
, attr
->dev_password_id
)) {
933 wps
->state
= SEND_WSC_NACK
;
938 * Stop here on an AP as an Enrollee if AP Setup is locked unless the
939 * special locked mode is used to allow protocol run up to M7 in order
940 * to support external Registrars that only learn the current AP
941 * configuration without changing it.
944 ((wps
->wps
->ap_setup_locked
&& wps
->wps
->ap_setup_locked
!= 2) ||
945 wps
->dev_password
== NULL
)) {
946 wpa_printf(MSG_DEBUG
, "WPS: AP Setup is locked - refuse "
947 "registration of a new Registrar");
948 wps
->config_error
= WPS_CFG_SETUP_LOCKED
;
949 wps
->state
= SEND_WSC_NACK
;
953 if (wps_process_pubkey(wps
, attr
->public_key
, attr
->public_key_len
) ||
954 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
955 wps_process_device_attrs(&wps
->peer_dev
, attr
)) {
956 wps
->state
= SEND_WSC_NACK
;
960 #ifdef CONFIG_WPS_NFC
961 if (wps
->peer_pubkey_hash_set
) {
962 struct wpabuf
*decrypted
;
963 struct wps_parse_attr eattr
;
965 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
966 attr
->encr_settings_len
);
967 if (decrypted
== NULL
) {
968 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypt "
969 "Encrypted Settings attribute");
970 wps
->state
= SEND_WSC_NACK
;
974 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted "
975 "Settings attribute");
976 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
977 wps_process_key_wrap_auth(wps
, decrypted
,
978 eattr
.key_wrap_auth
) ||
979 wps_process_creds(wps
, eattr
.cred
, eattr
.cred_len
,
980 eattr
.num_cred
, attr
->version2
!= NULL
)) {
981 wpabuf_free(decrypted
);
982 wps
->state
= SEND_WSC_NACK
;
985 wpabuf_free(decrypted
);
987 wps
->state
= WPS_MSG_DONE
;
990 #endif /* CONFIG_WPS_NFC */
992 wps
->state
= SEND_M3
;
997 static enum wps_process_res
wps_process_m2d(struct wps_data
*wps
,
998 struct wps_parse_attr
*attr
)
1000 wpa_printf(MSG_DEBUG
, "WPS: Received M2D");
1002 if (wps
->state
!= RECV_M2
) {
1003 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
1004 "receiving M2D", wps
->state
);
1005 wps
->state
= SEND_WSC_NACK
;
1006 return WPS_CONTINUE
;
1009 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Manufacturer",
1010 attr
->manufacturer
, attr
->manufacturer_len
);
1011 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Name",
1012 attr
->model_name
, attr
->model_name_len
);
1013 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Number",
1014 attr
->model_number
, attr
->model_number_len
);
1015 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Serial Number",
1016 attr
->serial_number
, attr
->serial_number_len
);
1017 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Device Name",
1018 attr
->dev_name
, attr
->dev_name_len
);
1020 if (wps
->wps
->event_cb
) {
1021 union wps_event_data data
;
1022 struct wps_event_m2d
*m2d
= &data
.m2d
;
1023 os_memset(&data
, 0, sizeof(data
));
1024 if (attr
->config_methods
)
1025 m2d
->config_methods
=
1026 WPA_GET_BE16(attr
->config_methods
);
1027 m2d
->manufacturer
= attr
->manufacturer
;
1028 m2d
->manufacturer_len
= attr
->manufacturer_len
;
1029 m2d
->model_name
= attr
->model_name
;
1030 m2d
->model_name_len
= attr
->model_name_len
;
1031 m2d
->model_number
= attr
->model_number
;
1032 m2d
->model_number_len
= attr
->model_number_len
;
1033 m2d
->serial_number
= attr
->serial_number
;
1034 m2d
->serial_number_len
= attr
->serial_number_len
;
1035 m2d
->dev_name
= attr
->dev_name
;
1036 m2d
->dev_name_len
= attr
->dev_name_len
;
1037 m2d
->primary_dev_type
= attr
->primary_dev_type
;
1038 if (attr
->config_error
)
1040 WPA_GET_BE16(attr
->config_error
);
1041 if (attr
->dev_password_id
)
1042 m2d
->dev_password_id
=
1043 WPA_GET_BE16(attr
->dev_password_id
);
1044 wps
->wps
->event_cb(wps
->wps
->cb_ctx
, WPS_EV_M2D
, &data
);
1047 wps
->state
= RECEIVED_M2D
;
1048 return WPS_CONTINUE
;
1052 static enum wps_process_res
wps_process_m4(struct wps_data
*wps
,
1053 const struct wpabuf
*msg
,
1054 struct wps_parse_attr
*attr
)
1056 struct wpabuf
*decrypted
;
1057 struct wps_parse_attr eattr
;
1059 wpa_printf(MSG_DEBUG
, "WPS: Received M4");
1061 if (wps
->state
!= RECV_M4
) {
1062 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
1063 "receiving M4", wps
->state
);
1064 wps
->state
= SEND_WSC_NACK
;
1065 return WPS_CONTINUE
;
1068 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
1069 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
1070 wps_process_r_hash1(wps
, attr
->r_hash1
) ||
1071 wps_process_r_hash2(wps
, attr
->r_hash2
)) {
1072 wps
->state
= SEND_WSC_NACK
;
1073 return WPS_CONTINUE
;
1076 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
1077 attr
->encr_settings_len
);
1078 if (decrypted
== NULL
) {
1079 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
1080 "Settings attribute");
1081 wps
->state
= SEND_WSC_NACK
;
1082 return WPS_CONTINUE
;
1085 if (wps_validate_m4_encr(decrypted
, attr
->version2
!= NULL
) < 0) {
1086 wpabuf_free(decrypted
);
1087 wps
->state
= SEND_WSC_NACK
;
1088 return WPS_CONTINUE
;
1091 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
1093 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
1094 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
1095 wps_process_r_snonce1(wps
, eattr
.r_snonce1
)) {
1096 wpabuf_free(decrypted
);
1097 wps
->state
= SEND_WSC_NACK
;
1098 return WPS_CONTINUE
;
1100 wpabuf_free(decrypted
);
1102 wps
->state
= SEND_M5
;
1103 return WPS_CONTINUE
;
1107 static enum wps_process_res
wps_process_m6(struct wps_data
*wps
,
1108 const struct wpabuf
*msg
,
1109 struct wps_parse_attr
*attr
)
1111 struct wpabuf
*decrypted
;
1112 struct wps_parse_attr eattr
;
1114 wpa_printf(MSG_DEBUG
, "WPS: Received M6");
1116 if (wps
->state
!= RECV_M6
) {
1117 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
1118 "receiving M6", wps
->state
);
1119 wps
->state
= SEND_WSC_NACK
;
1120 return WPS_CONTINUE
;
1123 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
1124 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
1125 wps
->state
= SEND_WSC_NACK
;
1126 return WPS_CONTINUE
;
1129 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
1130 attr
->encr_settings_len
);
1131 if (decrypted
== NULL
) {
1132 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
1133 "Settings attribute");
1134 wps
->state
= SEND_WSC_NACK
;
1135 return WPS_CONTINUE
;
1138 if (wps_validate_m6_encr(decrypted
, attr
->version2
!= NULL
) < 0) {
1139 wpabuf_free(decrypted
);
1140 wps
->state
= SEND_WSC_NACK
;
1141 return WPS_CONTINUE
;
1144 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
1146 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
1147 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
1148 wps_process_r_snonce2(wps
, eattr
.r_snonce2
)) {
1149 wpabuf_free(decrypted
);
1150 wps
->state
= SEND_WSC_NACK
;
1151 return WPS_CONTINUE
;
1153 wpabuf_free(decrypted
);
1156 wps
->wps
->event_cb(wps
->wps
->cb_ctx
, WPS_EV_AP_PIN_SUCCESS
,
1159 wps
->state
= SEND_M7
;
1160 return WPS_CONTINUE
;
1164 static enum wps_process_res
wps_process_m8(struct wps_data
*wps
,
1165 const struct wpabuf
*msg
,
1166 struct wps_parse_attr
*attr
)
1168 struct wpabuf
*decrypted
;
1169 struct wps_parse_attr eattr
;
1171 wpa_printf(MSG_DEBUG
, "WPS: Received M8");
1173 if (wps
->state
!= RECV_M8
) {
1174 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
1175 "receiving M8", wps
->state
);
1176 wps
->state
= SEND_WSC_NACK
;
1177 return WPS_CONTINUE
;
1180 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
1181 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
1182 wps
->state
= SEND_WSC_NACK
;
1183 return WPS_CONTINUE
;
1186 if (wps
->wps
->ap
&& wps
->wps
->ap_setup_locked
) {
1188 * Stop here if special ap_setup_locked == 2 mode allowed the
1189 * protocol to continue beyond M2. This allows ER to learn the
1190 * current AP settings without changing them.
1192 wpa_printf(MSG_DEBUG
, "WPS: AP Setup is locked - refuse "
1193 "registration of a new Registrar");
1194 wps
->config_error
= WPS_CFG_SETUP_LOCKED
;
1195 wps
->state
= SEND_WSC_NACK
;
1196 return WPS_CONTINUE
;
1199 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
1200 attr
->encr_settings_len
);
1201 if (decrypted
== NULL
) {
1202 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
1203 "Settings attribute");
1204 wps
->state
= SEND_WSC_NACK
;
1205 return WPS_CONTINUE
;
1208 if (wps_validate_m8_encr(decrypted
, wps
->wps
->ap
,
1209 attr
->version2
!= NULL
) < 0) {
1210 wpabuf_free(decrypted
);
1211 wps
->state
= SEND_WSC_NACK
;
1212 return WPS_CONTINUE
;
1215 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
1217 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
1218 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
1219 wps_process_creds(wps
, eattr
.cred
, eattr
.cred_len
,
1220 eattr
.num_cred
, attr
->version2
!= NULL
) ||
1221 wps_process_ap_settings_e(wps
, &eattr
, decrypted
,
1222 attr
->version2
!= NULL
)) {
1223 wpabuf_free(decrypted
);
1224 wps
->state
= SEND_WSC_NACK
;
1225 return WPS_CONTINUE
;
1227 wpabuf_free(decrypted
);
1229 wps
->state
= WPS_MSG_DONE
;
1230 return WPS_CONTINUE
;
1234 static enum wps_process_res
wps_process_wsc_msg(struct wps_data
*wps
,
1235 const struct wpabuf
*msg
)
1237 struct wps_parse_attr attr
;
1238 enum wps_process_res ret
= WPS_CONTINUE
;
1240 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_MSG");
1242 if (wps_parse_msg(msg
, &attr
) < 0)
1245 if (attr
.enrollee_nonce
== NULL
||
1246 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
) != 0) {
1247 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
1251 if (attr
.msg_type
== NULL
) {
1252 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
1253 wps
->state
= SEND_WSC_NACK
;
1254 return WPS_CONTINUE
;
1257 switch (*attr
.msg_type
) {
1259 if (wps_validate_m2(msg
) < 0)
1261 ret
= wps_process_m2(wps
, msg
, &attr
);
1264 if (wps_validate_m2d(msg
) < 0)
1266 ret
= wps_process_m2d(wps
, &attr
);
1269 if (wps_validate_m4(msg
) < 0)
1271 ret
= wps_process_m4(wps
, msg
, &attr
);
1272 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1273 wps_fail_event(wps
->wps
, WPS_M4
, wps
->config_error
,
1274 wps
->error_indication
,
1275 wps
->peer_dev
.mac_addr
);
1278 if (wps_validate_m6(msg
) < 0)
1280 ret
= wps_process_m6(wps
, msg
, &attr
);
1281 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1282 wps_fail_event(wps
->wps
, WPS_M6
, wps
->config_error
,
1283 wps
->error_indication
,
1284 wps
->peer_dev
.mac_addr
);
1287 if (wps_validate_m8(msg
) < 0)
1289 ret
= wps_process_m8(wps
, msg
, &attr
);
1290 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1291 wps_fail_event(wps
->wps
, WPS_M8
, wps
->config_error
,
1292 wps
->error_indication
,
1293 wps
->peer_dev
.mac_addr
);
1296 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Message Type %d",
1302 * Save a copy of the last message for Authenticator derivation if we
1303 * are continuing. However, skip M2D since it is not authenticated and
1304 * neither is the ACK/NACK response frame. This allows the possibly
1305 * following M2 to be processed correctly by using the previously sent
1306 * M1 in Authenticator derivation.
1308 if (ret
== WPS_CONTINUE
&& *attr
.msg_type
!= WPS_M2D
) {
1309 /* Save a copy of the last message for Authenticator derivation
1311 wpabuf_free(wps
->last_msg
);
1312 wps
->last_msg
= wpabuf_dup(msg
);
1319 static enum wps_process_res
wps_process_wsc_ack(struct wps_data
*wps
,
1320 const struct wpabuf
*msg
)
1322 struct wps_parse_attr attr
;
1324 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_ACK");
1326 if (wps_parse_msg(msg
, &attr
) < 0)
1329 if (attr
.msg_type
== NULL
) {
1330 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
1334 if (*attr
.msg_type
!= WPS_WSC_ACK
) {
1335 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
1340 if (attr
.registrar_nonce
== NULL
||
1341 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
) != 0)
1343 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
1347 if (attr
.enrollee_nonce
== NULL
||
1348 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
) != 0) {
1349 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
1353 if (wps
->state
== RECV_ACK
&& wps
->wps
->ap
) {
1354 wpa_printf(MSG_DEBUG
, "WPS: External Registrar registration "
1355 "completed successfully");
1356 wps_success_event(wps
->wps
, wps
->peer_dev
.mac_addr
);
1357 wps
->state
= WPS_FINISHED
;
1365 static enum wps_process_res
wps_process_wsc_nack(struct wps_data
*wps
,
1366 const struct wpabuf
*msg
)
1368 struct wps_parse_attr attr
;
1371 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_NACK");
1373 if (wps_parse_msg(msg
, &attr
) < 0)
1376 if (attr
.msg_type
== NULL
) {
1377 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
1381 if (*attr
.msg_type
!= WPS_WSC_NACK
) {
1382 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
1387 if (attr
.registrar_nonce
== NULL
||
1388 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
) != 0)
1390 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
1391 wpa_hexdump(MSG_DEBUG
, "WPS: Received Registrar Nonce",
1392 attr
.registrar_nonce
, WPS_NONCE_LEN
);
1393 wpa_hexdump(MSG_DEBUG
, "WPS: Expected Registrar Nonce",
1394 wps
->nonce_r
, WPS_NONCE_LEN
);
1398 if (attr
.enrollee_nonce
== NULL
||
1399 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
) != 0) {
1400 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
1401 wpa_hexdump(MSG_DEBUG
, "WPS: Received Enrollee Nonce",
1402 attr
.enrollee_nonce
, WPS_NONCE_LEN
);
1403 wpa_hexdump(MSG_DEBUG
, "WPS: Expected Enrollee Nonce",
1404 wps
->nonce_e
, WPS_NONCE_LEN
);
1408 if (attr
.config_error
== NULL
) {
1409 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error attribute "
1414 config_error
= WPA_GET_BE16(attr
.config_error
);
1415 wpa_printf(MSG_DEBUG
, "WPS: Registrar terminated negotiation with "
1416 "Configuration Error %d", config_error
);
1418 switch (wps
->state
) {
1420 wps_fail_event(wps
->wps
, WPS_M3
, config_error
,
1421 wps
->error_indication
, wps
->peer_dev
.mac_addr
);
1424 wps_fail_event(wps
->wps
, WPS_M5
, config_error
,
1425 wps
->error_indication
, wps
->peer_dev
.mac_addr
);
1428 wps_fail_event(wps
->wps
, WPS_M7
, config_error
,
1429 wps
->error_indication
, wps
->peer_dev
.mac_addr
);
1435 /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1436 * Enrollee is Authenticator */
1437 wps
->state
= SEND_WSC_NACK
;
1443 enum wps_process_res
wps_enrollee_process_msg(struct wps_data
*wps
,
1444 enum wsc_op_code op_code
,
1445 const struct wpabuf
*msg
)
1448 wpa_printf(MSG_DEBUG
, "WPS: Processing received message (len=%lu "
1450 (unsigned long) wpabuf_len(msg
), op_code
);
1452 if (op_code
== WSC_UPnP
) {
1453 /* Determine the OpCode based on message type attribute */
1454 struct wps_parse_attr attr
;
1455 if (wps_parse_msg(msg
, &attr
) == 0 && attr
.msg_type
) {
1456 if (*attr
.msg_type
== WPS_WSC_ACK
)
1458 else if (*attr
.msg_type
== WPS_WSC_NACK
)
1466 return wps_process_wsc_msg(wps
, msg
);
1468 if (wps_validate_wsc_ack(msg
) < 0)
1470 return wps_process_wsc_ack(wps
, msg
);
1472 if (wps_validate_wsc_nack(msg
) < 0)
1474 return wps_process_wsc_nack(wps
, msg
);
1476 wpa_printf(MSG_DEBUG
, "WPS: Unsupported op_code %d", op_code
);