2 * Wi-Fi Protected Setup - Enrollee
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 #include "wps_dev_attr.h"
24 static int wps_build_mac_addr(struct wps_data
*wps
, struct wpabuf
*msg
)
26 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address");
27 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
28 wpabuf_put_be16(msg
, ETH_ALEN
);
29 wpabuf_put_data(msg
, wps
->mac_addr_e
, ETH_ALEN
);
34 static int wps_build_wps_state(struct wps_data
*wps
, struct wpabuf
*msg
)
38 state
= wps
->wps
->wps_state
;
40 state
= WPS_STATE_NOT_CONFIGURED
;
41 wpa_printf(MSG_DEBUG
, "WPS: * Wi-Fi Protected Setup State (%d)",
43 wpabuf_put_be16(msg
, ATTR_WPS_STATE
);
44 wpabuf_put_be16(msg
, 1);
45 wpabuf_put_u8(msg
, WPS_STATE_NOT_CONFIGURED
);
50 static int wps_build_e_hash(struct wps_data
*wps
, struct wpabuf
*msg
)
56 if (os_get_random(wps
->snonce
, 2 * WPS_SECRET_NONCE_LEN
) < 0)
58 wpa_hexdump(MSG_DEBUG
, "WPS: E-S1", wps
->snonce
, WPS_SECRET_NONCE_LEN
);
59 wpa_hexdump(MSG_DEBUG
, "WPS: E-S2",
60 wps
->snonce
+ WPS_SECRET_NONCE_LEN
, WPS_SECRET_NONCE_LEN
);
62 if (wps
->dh_pubkey_e
== NULL
|| wps
->dh_pubkey_r
== NULL
) {
63 wpa_printf(MSG_DEBUG
, "WPS: DH public keys not available for "
68 wpa_printf(MSG_DEBUG
, "WPS: * E-Hash1");
69 wpabuf_put_be16(msg
, ATTR_E_HASH1
);
70 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
71 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
72 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
73 addr
[0] = wps
->snonce
;
74 len
[0] = WPS_SECRET_NONCE_LEN
;
77 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
78 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
79 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
80 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
81 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
82 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash1", hash
, SHA256_MAC_LEN
);
84 wpa_printf(MSG_DEBUG
, "WPS: * E-Hash2");
85 wpabuf_put_be16(msg
, ATTR_E_HASH2
);
86 wpabuf_put_be16(msg
, SHA256_MAC_LEN
);
87 hash
= wpabuf_put(msg
, SHA256_MAC_LEN
);
88 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
89 addr
[0] = wps
->snonce
+ WPS_SECRET_NONCE_LEN
;
91 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
92 wpa_hexdump(MSG_DEBUG
, "WPS: E-Hash2", hash
, SHA256_MAC_LEN
);
98 static int wps_build_e_snonce1(struct wps_data
*wps
, struct wpabuf
*msg
)
100 wpa_printf(MSG_DEBUG
, "WPS: * E-SNonce1");
101 wpabuf_put_be16(msg
, ATTR_E_SNONCE1
);
102 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
103 wpabuf_put_data(msg
, wps
->snonce
, WPS_SECRET_NONCE_LEN
);
108 static int wps_build_e_snonce2(struct wps_data
*wps
, struct wpabuf
*msg
)
110 wpa_printf(MSG_DEBUG
, "WPS: * E-SNonce2");
111 wpabuf_put_be16(msg
, ATTR_E_SNONCE2
);
112 wpabuf_put_be16(msg
, WPS_SECRET_NONCE_LEN
);
113 wpabuf_put_data(msg
, wps
->snonce
+ WPS_SECRET_NONCE_LEN
,
114 WPS_SECRET_NONCE_LEN
);
119 static struct wpabuf
* wps_build_m1(struct wps_data
*wps
)
124 if (os_get_random(wps
->nonce_e
, WPS_NONCE_LEN
) < 0)
126 wpa_hexdump(MSG_DEBUG
, "WPS: Enrollee Nonce",
127 wps
->nonce_e
, WPS_NONCE_LEN
);
129 wpa_printf(MSG_DEBUG
, "WPS: Building Message M1");
130 msg
= wpabuf_alloc(1000);
134 methods
= WPS_CONFIG_LABEL
| WPS_CONFIG_DISPLAY
| WPS_CONFIG_KEYPAD
|
137 methods
|= WPS_CONFIG_PUSHBUTTON
;
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(wps
, msg
) ||
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
, 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_build_assoc_state(wps
, msg
) ||
153 wps_build_dev_password_id(msg
, wps
->dev_pw_id
) ||
154 wps_build_config_error(msg
, WPS_CFG_NO_ERROR
) ||
155 wps_build_os_version(&wps
->wps
->dev
, msg
)) {
160 wps
->state
= RECV_M2
;
165 static struct wpabuf
* wps_build_m3(struct wps_data
*wps
)
169 wpa_printf(MSG_DEBUG
, "WPS: Building Message M3");
171 if (wps
->dev_password
== NULL
) {
172 wpa_printf(MSG_DEBUG
, "WPS: No Device Password available");
175 wps_derive_psk(wps
, wps
->dev_password
, wps
->dev_password_len
);
177 msg
= wpabuf_alloc(1000);
181 if (wps_build_version(msg
) ||
182 wps_build_msg_type(msg
, WPS_M3
) ||
183 wps_build_registrar_nonce(wps
, msg
) ||
184 wps_build_e_hash(wps
, msg
) ||
185 wps_build_authenticator(wps
, msg
)) {
190 wps
->state
= RECV_M4
;
195 static struct wpabuf
* wps_build_m5(struct wps_data
*wps
)
197 struct wpabuf
*msg
, *plain
;
199 wpa_printf(MSG_DEBUG
, "WPS: Building Message M5");
201 plain
= wpabuf_alloc(200);
205 msg
= wpabuf_alloc(1000);
211 if (wps_build_version(msg
) ||
212 wps_build_msg_type(msg
, WPS_M5
) ||
213 wps_build_registrar_nonce(wps
, msg
) ||
214 wps_build_e_snonce1(wps
, plain
) ||
215 wps_build_key_wrap_auth(wps
, plain
) ||
216 wps_build_encr_settings(wps
, msg
, plain
) ||
217 wps_build_authenticator(wps
, msg
)) {
224 wps
->state
= RECV_M6
;
229 static int wps_build_cred_ssid(struct wps_data
*wps
, struct wpabuf
*msg
)
231 wpa_printf(MSG_DEBUG
, "WPS: * SSID");
232 wpabuf_put_be16(msg
, ATTR_SSID
);
233 wpabuf_put_be16(msg
, wps
->wps
->ssid_len
);
234 wpabuf_put_data(msg
, wps
->wps
->ssid
, wps
->wps
->ssid_len
);
239 static int wps_build_cred_auth_type(struct wps_data
*wps
, struct wpabuf
*msg
)
241 wpa_printf(MSG_DEBUG
, "WPS: * Authentication Type");
242 wpabuf_put_be16(msg
, ATTR_AUTH_TYPE
);
243 wpabuf_put_be16(msg
, 2);
244 wpabuf_put_be16(msg
, wps
->wps
->auth_types
);
249 static int wps_build_cred_encr_type(struct wps_data
*wps
, struct wpabuf
*msg
)
251 wpa_printf(MSG_DEBUG
, "WPS: * Encryption Type");
252 wpabuf_put_be16(msg
, ATTR_ENCR_TYPE
);
253 wpabuf_put_be16(msg
, 2);
254 wpabuf_put_be16(msg
, wps
->wps
->encr_types
);
259 static int wps_build_cred_network_key(struct wps_data
*wps
, struct wpabuf
*msg
)
261 wpa_printf(MSG_DEBUG
, "WPS: * Network Key");
262 wpabuf_put_be16(msg
, ATTR_NETWORK_KEY
);
263 wpabuf_put_be16(msg
, wps
->wps
->network_key_len
);
264 wpabuf_put_data(msg
, wps
->wps
->network_key
, wps
->wps
->network_key_len
);
269 static int wps_build_cred_mac_addr(struct wps_data
*wps
, struct wpabuf
*msg
)
271 wpa_printf(MSG_DEBUG
, "WPS: * MAC Address (AP BSSID)");
272 wpabuf_put_be16(msg
, ATTR_MAC_ADDR
);
273 wpabuf_put_be16(msg
, ETH_ALEN
);
274 wpabuf_put_data(msg
, wps
->wps
->dev
.mac_addr
, ETH_ALEN
);
279 static int wps_build_ap_settings(struct wps_data
*wps
, struct wpabuf
*plain
)
281 if (wps
->wps
->ap_settings
) {
282 wpa_printf(MSG_DEBUG
, "WPS: * AP Settings (pre-configured)");
283 wpabuf_put_data(plain
, wps
->wps
->ap_settings
,
284 wps
->wps
->ap_settings_len
);
288 return wps_build_cred_ssid(wps
, plain
) ||
289 wps_build_cred_mac_addr(wps
, plain
) ||
290 wps_build_cred_auth_type(wps
, plain
) ||
291 wps_build_cred_encr_type(wps
, plain
) ||
292 wps_build_cred_network_key(wps
, plain
);
296 static struct wpabuf
* wps_build_m7(struct wps_data
*wps
)
298 struct wpabuf
*msg
, *plain
;
300 wpa_printf(MSG_DEBUG
, "WPS: Building Message M7");
302 plain
= wpabuf_alloc(500 + wps
->wps
->ap_settings_len
);
306 msg
= wpabuf_alloc(1000 + wps
->wps
->ap_settings_len
);
312 if (wps_build_version(msg
) ||
313 wps_build_msg_type(msg
, WPS_M7
) ||
314 wps_build_registrar_nonce(wps
, msg
) ||
315 wps_build_e_snonce2(wps
, plain
) ||
316 (wps
->wps
->ap
&& wps_build_ap_settings(wps
, plain
)) ||
317 wps_build_key_wrap_auth(wps
, plain
) ||
318 wps_build_encr_settings(wps
, msg
, plain
) ||
319 wps_build_authenticator(wps
, msg
)) {
326 wps
->state
= RECV_M8
;
331 static struct wpabuf
* wps_build_wsc_done(struct wps_data
*wps
)
335 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_Done");
337 msg
= wpabuf_alloc(1000);
341 if (wps_build_version(msg
) ||
342 wps_build_msg_type(msg
, WPS_WSC_DONE
) ||
343 wps_build_enrollee_nonce(wps
, msg
) ||
344 wps_build_registrar_nonce(wps
, msg
)) {
350 wps
->state
= RECV_ACK
;
352 wps_success_event(wps
->wps
);
353 wps
->state
= WPS_FINISHED
;
359 static struct wpabuf
* wps_build_wsc_ack(struct wps_data
*wps
)
363 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_ACK");
365 msg
= wpabuf_alloc(1000);
369 if (wps_build_version(msg
) ||
370 wps_build_msg_type(msg
, WPS_WSC_ACK
) ||
371 wps_build_enrollee_nonce(wps
, msg
) ||
372 wps_build_registrar_nonce(wps
, msg
)) {
381 static struct wpabuf
* wps_build_wsc_nack(struct wps_data
*wps
)
385 wpa_printf(MSG_DEBUG
, "WPS: Building Message WSC_NACK");
387 msg
= wpabuf_alloc(1000);
391 if (wps_build_version(msg
) ||
392 wps_build_msg_type(msg
, WPS_WSC_NACK
) ||
393 wps_build_enrollee_nonce(wps
, msg
) ||
394 wps_build_registrar_nonce(wps
, msg
) ||
395 wps_build_config_error(msg
, wps
->config_error
)) {
404 struct wpabuf
* wps_enrollee_get_msg(struct wps_data
*wps
,
405 enum wsc_op_code
*op_code
)
409 switch (wps
->state
) {
411 msg
= wps_build_m1(wps
);
415 msg
= wps_build_m3(wps
);
419 msg
= wps_build_m5(wps
);
423 msg
= wps_build_m7(wps
);
428 msg
= wps_build_wsc_nack(wps
);
432 msg
= wps_build_wsc_ack(wps
);
435 /* Another M2/M2D may be received */
436 wps
->state
= RECV_M2
;
440 msg
= wps_build_wsc_nack(wps
);
444 msg
= wps_build_wsc_done(wps
);
448 wpa_printf(MSG_DEBUG
, "WPS: Unsupported state %d for building "
449 "a message", wps
->state
);
454 if (*op_code
== WSC_MSG
&& msg
) {
455 /* Save a copy of the last message for Authenticator derivation
457 wpabuf_free(wps
->last_msg
);
458 wps
->last_msg
= wpabuf_dup(msg
);
465 static int wps_process_registrar_nonce(struct wps_data
*wps
, const u8
*r_nonce
)
467 if (r_nonce
== NULL
) {
468 wpa_printf(MSG_DEBUG
, "WPS: No Registrar Nonce received");
472 os_memcpy(wps
->nonce_r
, r_nonce
, WPS_NONCE_LEN
);
473 wpa_hexdump(MSG_DEBUG
, "WPS: Registrar Nonce",
474 wps
->nonce_r
, WPS_NONCE_LEN
);
480 static int wps_process_enrollee_nonce(struct wps_data
*wps
, const u8
*e_nonce
)
482 if (e_nonce
== NULL
) {
483 wpa_printf(MSG_DEBUG
, "WPS: No Enrollee Nonce received");
487 if (os_memcmp(wps
->nonce_e
, e_nonce
, WPS_NONCE_LEN
) != 0) {
488 wpa_printf(MSG_DEBUG
, "WPS: Invalid Enrollee Nonce received");
496 static int wps_process_uuid_r(struct wps_data
*wps
, const u8
*uuid_r
)
498 if (uuid_r
== NULL
) {
499 wpa_printf(MSG_DEBUG
, "WPS: No UUID-R received");
503 os_memcpy(wps
->uuid_r
, uuid_r
, WPS_UUID_LEN
);
504 wpa_hexdump(MSG_DEBUG
, "WPS: UUID-R", wps
->uuid_r
, WPS_UUID_LEN
);
510 static int wps_process_pubkey(struct wps_data
*wps
, const u8
*pk
,
513 if (pk
== NULL
|| pk_len
== 0) {
514 wpa_printf(MSG_DEBUG
, "WPS: No Public Key received");
518 if (wps
->wps
->oob_conf
.pubkey_hash
!= NULL
) {
520 u8 hash
[WPS_HASH_LEN
];
523 sha256_vector(1, addr
, &pk_len
, hash
);
525 wpabuf_head(wps
->wps
->oob_conf
.pubkey_hash
),
526 WPS_OOB_PUBKEY_HASH_LEN
) != 0) {
527 wpa_printf(MSG_ERROR
, "WPS: Public Key hash error");
532 wpabuf_free(wps
->dh_pubkey_r
);
533 wps
->dh_pubkey_r
= wpabuf_alloc_copy(pk
, pk_len
);
534 if (wps
->dh_pubkey_r
== NULL
)
537 if (wps_derive_keys(wps
) < 0)
540 if (wps
->request_type
== WPS_REQ_WLAN_MANAGER_REGISTRAR
&&
541 wps_derive_mgmt_keys(wps
) < 0)
548 static int wps_process_r_hash1(struct wps_data
*wps
, const u8
*r_hash1
)
550 if (r_hash1
== NULL
) {
551 wpa_printf(MSG_DEBUG
, "WPS: No R-Hash1 received");
555 os_memcpy(wps
->peer_hash1
, r_hash1
, WPS_HASH_LEN
);
556 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash1", wps
->peer_hash1
, WPS_HASH_LEN
);
562 static int wps_process_r_hash2(struct wps_data
*wps
, const u8
*r_hash2
)
564 if (r_hash2
== NULL
) {
565 wpa_printf(MSG_DEBUG
, "WPS: No R-Hash2 received");
569 os_memcpy(wps
->peer_hash2
, r_hash2
, WPS_HASH_LEN
);
570 wpa_hexdump(MSG_DEBUG
, "WPS: R-Hash2", wps
->peer_hash2
, WPS_HASH_LEN
);
576 static int wps_process_r_snonce1(struct wps_data
*wps
, const u8
*r_snonce1
)
578 u8 hash
[SHA256_MAC_LEN
];
582 if (r_snonce1
== NULL
) {
583 wpa_printf(MSG_DEBUG
, "WPS: No R-SNonce1 received");
587 wpa_hexdump_key(MSG_DEBUG
, "WPS: R-SNonce1", r_snonce1
,
588 WPS_SECRET_NONCE_LEN
);
590 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
592 len
[0] = WPS_SECRET_NONCE_LEN
;
594 len
[1] = WPS_PSK_LEN
;
595 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
596 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
597 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
598 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
599 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
601 if (os_memcmp(wps
->peer_hash1
, hash
, WPS_HASH_LEN
) != 0) {
602 wpa_printf(MSG_DEBUG
, "WPS: R-Hash1 derived from R-S1 does "
603 "not match with the pre-committed value");
604 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
605 wps_pwd_auth_fail_event(wps
->wps
, 1, 1);
609 wpa_printf(MSG_DEBUG
, "WPS: Registrar proved knowledge of the first "
610 "half of the device password");
616 static int wps_process_r_snonce2(struct wps_data
*wps
, const u8
*r_snonce2
)
618 u8 hash
[SHA256_MAC_LEN
];
622 if (r_snonce2
== NULL
) {
623 wpa_printf(MSG_DEBUG
, "WPS: No R-SNonce2 received");
627 wpa_hexdump_key(MSG_DEBUG
, "WPS: R-SNonce2", r_snonce2
,
628 WPS_SECRET_NONCE_LEN
);
630 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
632 len
[0] = WPS_SECRET_NONCE_LEN
;
634 len
[1] = WPS_PSK_LEN
;
635 addr
[2] = wpabuf_head(wps
->dh_pubkey_e
);
636 len
[2] = wpabuf_len(wps
->dh_pubkey_e
);
637 addr
[3] = wpabuf_head(wps
->dh_pubkey_r
);
638 len
[3] = wpabuf_len(wps
->dh_pubkey_r
);
639 hmac_sha256_vector(wps
->authkey
, WPS_AUTHKEY_LEN
, 4, addr
, len
, hash
);
641 if (os_memcmp(wps
->peer_hash2
, hash
, WPS_HASH_LEN
) != 0) {
642 wpa_printf(MSG_DEBUG
, "WPS: R-Hash2 derived from R-S2 does "
643 "not match with the pre-committed value");
644 wps
->config_error
= WPS_CFG_DEV_PASSWORD_AUTH_FAILURE
;
645 wps_pwd_auth_fail_event(wps
->wps
, 1, 2);
649 wpa_printf(MSG_DEBUG
, "WPS: Registrar proved knowledge of the second "
650 "half of the device password");
656 static int wps_process_cred_e(struct wps_data
*wps
, const u8
*cred
,
659 struct wps_parse_attr attr
;
662 wpa_printf(MSG_DEBUG
, "WPS: Received Credential");
663 os_memset(&wps
->cred
, 0, sizeof(wps
->cred
));
664 wpabuf_set(&msg
, cred
, cred_len
);
665 if (wps_parse_msg(&msg
, &attr
) < 0 ||
666 wps_process_cred(&attr
, &wps
->cred
))
669 if (wps
->wps
->cred_cb
) {
670 wps
->cred
.cred_attr
= cred
- 4;
671 wps
->cred
.cred_attr_len
= cred_len
+ 4;
672 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &wps
->cred
);
673 wps
->cred
.cred_attr
= NULL
;
674 wps
->cred
.cred_attr_len
= 0;
681 static int wps_process_creds(struct wps_data
*wps
, const u8
*cred
[],
682 size_t cred_len
[], size_t num_cred
)
690 wpa_printf(MSG_DEBUG
, "WPS: No Credential attributes "
695 for (i
= 0; i
< num_cred
; i
++) {
696 if (wps_process_cred_e(wps
, cred
[i
], cred_len
[i
]))
704 static int wps_process_ap_settings_e(struct wps_data
*wps
,
705 struct wps_parse_attr
*attr
,
706 struct wpabuf
*attrs
)
708 struct wps_credential cred
;
713 if (wps_process_ap_settings(attr
, &cred
) < 0)
716 wpa_printf(MSG_INFO
, "WPS: Received new AP configuration from "
719 if (wps
->wps
->cred_cb
) {
720 cred
.cred_attr
= wpabuf_head(attrs
);
721 cred
.cred_attr_len
= wpabuf_len(attrs
);
722 wps
->wps
->cred_cb(wps
->wps
->cb_ctx
, &cred
);
729 static enum wps_process_res
wps_process_m2(struct wps_data
*wps
,
730 const struct wpabuf
*msg
,
731 struct wps_parse_attr
*attr
)
733 wpa_printf(MSG_DEBUG
, "WPS: Received M2");
735 if (wps
->state
!= RECV_M2
) {
736 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
737 "receiving M2", wps
->state
);
738 wps
->state
= SEND_WSC_NACK
;
742 if (wps_process_registrar_nonce(wps
, attr
->registrar_nonce
) ||
743 wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
744 wps_process_uuid_r(wps
, attr
->uuid_r
) ||
745 wps_process_pubkey(wps
, attr
->public_key
, attr
->public_key_len
) ||
746 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
747 wps
->state
= SEND_WSC_NACK
;
751 if (wps
->wps
->ap
&& wps
->wps
->ap_setup_locked
) {
752 wpa_printf(MSG_DEBUG
, "WPS: AP Setup is locked - refuse "
753 "registration of a new Registrar");
754 wps
->config_error
= WPS_CFG_SETUP_LOCKED
;
755 wps
->state
= SEND_WSC_NACK
;
759 wps
->state
= SEND_M3
;
764 static enum wps_process_res
wps_process_m2d(struct wps_data
*wps
,
765 struct wps_parse_attr
*attr
)
767 wpa_printf(MSG_DEBUG
, "WPS: Received M2D");
769 if (wps
->state
!= RECV_M2
) {
770 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
771 "receiving M2D", wps
->state
);
772 wps
->state
= SEND_WSC_NACK
;
776 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Manufacturer",
777 attr
->manufacturer
, attr
->manufacturer_len
);
778 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Name",
779 attr
->model_name
, attr
->model_name_len
);
780 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Model Number",
781 attr
->model_number
, attr
->model_number_len
);
782 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Serial Number",
783 attr
->serial_number
, attr
->serial_number_len
);
784 wpa_hexdump_ascii(MSG_DEBUG
, "WPS: Device Name",
785 attr
->dev_name
, attr
->dev_name_len
);
787 if (wps
->wps
->event_cb
) {
788 union wps_event_data data
;
789 struct wps_event_m2d
*m2d
= &data
.m2d
;
790 os_memset(&data
, 0, sizeof(data
));
791 if (attr
->config_methods
)
792 m2d
->config_methods
=
793 WPA_GET_BE16(attr
->config_methods
);
794 m2d
->manufacturer
= attr
->manufacturer
;
795 m2d
->manufacturer_len
= attr
->manufacturer_len
;
796 m2d
->model_name
= attr
->model_name
;
797 m2d
->model_name_len
= attr
->model_name_len
;
798 m2d
->model_number
= attr
->model_number
;
799 m2d
->model_number_len
= attr
->model_number_len
;
800 m2d
->serial_number
= attr
->serial_number
;
801 m2d
->serial_number_len
= attr
->serial_number_len
;
802 m2d
->dev_name
= attr
->dev_name
;
803 m2d
->dev_name_len
= attr
->dev_name_len
;
804 m2d
->primary_dev_type
= attr
->primary_dev_type
;
805 if (attr
->config_error
)
807 WPA_GET_BE16(attr
->config_error
);
808 if (attr
->dev_password_id
)
809 m2d
->dev_password_id
=
810 WPA_GET_BE16(attr
->dev_password_id
);
811 wps
->wps
->event_cb(wps
->wps
->cb_ctx
, WPS_EV_M2D
, &data
);
814 wps
->state
= RECEIVED_M2D
;
819 static enum wps_process_res
wps_process_m4(struct wps_data
*wps
,
820 const struct wpabuf
*msg
,
821 struct wps_parse_attr
*attr
)
823 struct wpabuf
*decrypted
;
824 struct wps_parse_attr eattr
;
826 wpa_printf(MSG_DEBUG
, "WPS: Received M4");
828 if (wps
->state
!= RECV_M4
) {
829 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
830 "receiving M4", wps
->state
);
831 wps
->state
= SEND_WSC_NACK
;
835 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
836 wps_process_authenticator(wps
, attr
->authenticator
, msg
) ||
837 wps_process_r_hash1(wps
, attr
->r_hash1
) ||
838 wps_process_r_hash2(wps
, attr
->r_hash2
)) {
839 wps
->state
= SEND_WSC_NACK
;
843 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
844 attr
->encr_settings_len
);
845 if (decrypted
== NULL
) {
846 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
847 "Settings attribute");
848 wps
->state
= SEND_WSC_NACK
;
852 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
854 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
855 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
856 wps_process_r_snonce1(wps
, eattr
.r_snonce1
)) {
857 wpabuf_free(decrypted
);
858 wps
->state
= SEND_WSC_NACK
;
861 wpabuf_free(decrypted
);
863 wps
->state
= SEND_M5
;
868 static enum wps_process_res
wps_process_m6(struct wps_data
*wps
,
869 const struct wpabuf
*msg
,
870 struct wps_parse_attr
*attr
)
872 struct wpabuf
*decrypted
;
873 struct wps_parse_attr eattr
;
875 wpa_printf(MSG_DEBUG
, "WPS: Received M6");
877 if (wps
->state
!= RECV_M6
) {
878 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
879 "receiving M6", wps
->state
);
880 wps
->state
= SEND_WSC_NACK
;
884 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
885 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
886 wps
->state
= SEND_WSC_NACK
;
890 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
891 attr
->encr_settings_len
);
892 if (decrypted
== NULL
) {
893 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
894 "Settings attribute");
895 wps
->state
= SEND_WSC_NACK
;
899 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
901 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
902 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
903 wps_process_r_snonce2(wps
, eattr
.r_snonce2
)) {
904 wpabuf_free(decrypted
);
905 wps
->state
= SEND_WSC_NACK
;
908 wpabuf_free(decrypted
);
910 wps
->state
= SEND_M7
;
915 static enum wps_process_res
wps_process_m8(struct wps_data
*wps
,
916 const struct wpabuf
*msg
,
917 struct wps_parse_attr
*attr
)
919 struct wpabuf
*decrypted
;
920 struct wps_parse_attr eattr
;
922 wpa_printf(MSG_DEBUG
, "WPS: Received M8");
924 if (wps
->state
!= RECV_M8
) {
925 wpa_printf(MSG_DEBUG
, "WPS: Unexpected state (%d) for "
926 "receiving M8", wps
->state
);
927 wps
->state
= SEND_WSC_NACK
;
931 if (wps_process_enrollee_nonce(wps
, attr
->enrollee_nonce
) ||
932 wps_process_authenticator(wps
, attr
->authenticator
, msg
)) {
933 wps
->state
= SEND_WSC_NACK
;
937 decrypted
= wps_decrypt_encr_settings(wps
, attr
->encr_settings
,
938 attr
->encr_settings_len
);
939 if (decrypted
== NULL
) {
940 wpa_printf(MSG_DEBUG
, "WPS: Failed to decrypted Encrypted "
941 "Settings attribute");
942 wps
->state
= SEND_WSC_NACK
;
946 wpa_printf(MSG_DEBUG
, "WPS: Processing decrypted Encrypted Settings "
948 if (wps_parse_msg(decrypted
, &eattr
) < 0 ||
949 wps_process_key_wrap_auth(wps
, decrypted
, eattr
.key_wrap_auth
) ||
950 wps_process_creds(wps
, eattr
.cred
, eattr
.cred_len
,
952 wps_process_ap_settings_e(wps
, &eattr
, decrypted
)) {
953 wpabuf_free(decrypted
);
954 wps
->state
= SEND_WSC_NACK
;
957 wpabuf_free(decrypted
);
959 wps
->state
= WPS_MSG_DONE
;
964 static enum wps_process_res
wps_process_wsc_msg(struct wps_data
*wps
,
965 const struct wpabuf
*msg
)
967 struct wps_parse_attr attr
;
968 enum wps_process_res ret
= WPS_CONTINUE
;
970 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_MSG");
972 if (wps_parse_msg(msg
, &attr
) < 0)
975 if (!wps_version_supported(attr
.version
)) {
976 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
977 attr
.version
? *attr
.version
: 0);
981 if (attr
.enrollee_nonce
== NULL
||
982 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
983 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
987 if (attr
.msg_type
== NULL
) {
988 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
992 switch (*attr
.msg_type
) {
994 ret
= wps_process_m2(wps
, msg
, &attr
);
997 ret
= wps_process_m2d(wps
, &attr
);
1000 ret
= wps_process_m4(wps
, msg
, &attr
);
1001 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1002 wps_fail_event(wps
->wps
, WPS_M4
);
1005 ret
= wps_process_m6(wps
, msg
, &attr
);
1006 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1007 wps_fail_event(wps
->wps
, WPS_M6
);
1010 ret
= wps_process_m8(wps
, msg
, &attr
);
1011 if (ret
== WPS_FAILURE
|| wps
->state
== SEND_WSC_NACK
)
1012 wps_fail_event(wps
->wps
, WPS_M8
);
1015 wpa_printf(MSG_DEBUG
, "WPS: Unsupported Message Type %d",
1021 * Save a copy of the last message for Authenticator derivation if we
1022 * are continuing. However, skip M2D since it is not authenticated and
1023 * neither is the ACK/NACK response frame. This allows the possibly
1024 * following M2 to be processed correctly by using the previously sent
1025 * M1 in Authenticator derivation.
1027 if (ret
== WPS_CONTINUE
&& *attr
.msg_type
!= WPS_M2D
) {
1028 /* Save a copy of the last message for Authenticator derivation
1030 wpabuf_free(wps
->last_msg
);
1031 wps
->last_msg
= wpabuf_dup(msg
);
1038 static enum wps_process_res
wps_process_wsc_ack(struct wps_data
*wps
,
1039 const struct wpabuf
*msg
)
1041 struct wps_parse_attr attr
;
1043 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_ACK");
1045 if (wps_parse_msg(msg
, &attr
) < 0)
1048 if (!wps_version_supported(attr
.version
)) {
1049 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
1050 attr
.version
? *attr
.version
: 0);
1054 if (attr
.msg_type
== NULL
) {
1055 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
1059 if (*attr
.msg_type
!= WPS_WSC_ACK
) {
1060 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
1065 if (attr
.registrar_nonce
== NULL
||
1066 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
1068 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
1072 if (attr
.enrollee_nonce
== NULL
||
1073 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
1074 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
1078 if (wps
->state
== RECV_ACK
&& wps
->wps
->ap
) {
1079 wpa_printf(MSG_DEBUG
, "WPS: External Registrar registration "
1080 "completed successfully");
1081 wps_success_event(wps
->wps
);
1082 wps
->state
= WPS_FINISHED
;
1090 static enum wps_process_res
wps_process_wsc_nack(struct wps_data
*wps
,
1091 const struct wpabuf
*msg
)
1093 struct wps_parse_attr attr
;
1095 wpa_printf(MSG_DEBUG
, "WPS: Received WSC_NACK");
1097 if (wps_parse_msg(msg
, &attr
) < 0)
1100 if (!wps_version_supported(attr
.version
)) {
1101 wpa_printf(MSG_DEBUG
, "WPS: Unsupported message version 0x%x",
1102 attr
.version
? *attr
.version
: 0);
1106 if (attr
.msg_type
== NULL
) {
1107 wpa_printf(MSG_DEBUG
, "WPS: No Message Type attribute");
1111 if (*attr
.msg_type
!= WPS_WSC_NACK
) {
1112 wpa_printf(MSG_DEBUG
, "WPS: Invalid Message Type %d",
1117 if (attr
.registrar_nonce
== NULL
||
1118 os_memcmp(wps
->nonce_r
, attr
.registrar_nonce
, WPS_NONCE_LEN
!= 0))
1120 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in registrar nonce");
1121 wpa_hexdump(MSG_DEBUG
, "WPS: Received Registrar Nonce",
1122 attr
.registrar_nonce
, WPS_NONCE_LEN
);
1123 wpa_hexdump(MSG_DEBUG
, "WPS: Expected Registrar Nonce",
1124 wps
->nonce_r
, WPS_NONCE_LEN
);
1128 if (attr
.enrollee_nonce
== NULL
||
1129 os_memcmp(wps
->nonce_e
, attr
.enrollee_nonce
, WPS_NONCE_LEN
!= 0)) {
1130 wpa_printf(MSG_DEBUG
, "WPS: Mismatch in enrollee nonce");
1131 wpa_hexdump(MSG_DEBUG
, "WPS: Received Enrollee Nonce",
1132 attr
.enrollee_nonce
, WPS_NONCE_LEN
);
1133 wpa_hexdump(MSG_DEBUG
, "WPS: Expected Enrollee Nonce",
1134 wps
->nonce_e
, WPS_NONCE_LEN
);
1138 if (attr
.config_error
== NULL
) {
1139 wpa_printf(MSG_DEBUG
, "WPS: No Configuration Error attribute "
1144 wpa_printf(MSG_DEBUG
, "WPS: Registrar terminated negotiation with "
1145 "Configuration Error %d", WPA_GET_BE16(attr
.config_error
));
1147 switch (wps
->state
) {
1149 wps_fail_event(wps
->wps
, WPS_M3
);
1152 wps_fail_event(wps
->wps
, WPS_M5
);
1155 wps_fail_event(wps
->wps
, WPS_M7
);
1161 /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1162 * Enrollee is Authenticator */
1163 wps
->state
= SEND_WSC_NACK
;
1169 enum wps_process_res
wps_enrollee_process_msg(struct wps_data
*wps
,
1170 enum wsc_op_code op_code
,
1171 const struct wpabuf
*msg
)
1174 wpa_printf(MSG_DEBUG
, "WPS: Processing received message (len=%lu "
1176 (unsigned long) wpabuf_len(msg
), op_code
);
1181 return wps_process_wsc_msg(wps
, msg
);
1183 return wps_process_wsc_ack(wps
, msg
);
1185 return wps_process_wsc_nack(wps
, msg
);
1187 wpa_printf(MSG_DEBUG
, "WPS: Unsupported op_code %d", op_code
);