1 /*
2 * Wi-Fi Protected Setup - Enrollee
3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "eloop.h"
13 #include "crypto/crypto.h"
14 #include "crypto/sha256.h"
15 #include "crypto/random.h"
16 #include "wps_i.h"
17 #include "wps_dev_attr.h"
18
19 #include "esp_wps_i.h"
20
wps_build_wps_state(struct wps_data * wps,struct wpabuf * msg)21 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
22 {
23 u8 state;
24 if (wps->wps->ap)
25 state = wps->wps->wps_state;
26 else
27 state = WPS_STATE_NOT_CONFIGURED;
28 wpa_printf(MSG_DEBUG, "WPS: * Wi-Fi Protected Setup State (%d)",
29 state);
30 wpabuf_put_be16(msg, ATTR_WPS_STATE);
31 wpabuf_put_be16(msg, 1);
32 wpabuf_put_u8(msg, state);
33 return 0;
34 }
35
36
wps_build_e_hash(struct wps_data * wps,struct wpabuf * msg)37 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
38 {
39 u8 *hash;
40 const u8 *addr[4];
41 size_t len[4];
42
43 if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
44 return -1;
45 wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
46 wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
47 wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
48
49 if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
50 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
51 "E-Hash derivation");
52 return -1;
53 }
54
55 wpa_printf(MSG_DEBUG, "WPS: * E-Hash1");
56 wpabuf_put_be16(msg, ATTR_E_HASH1);
57 wpabuf_put_be16(msg, SHA256_MAC_LEN);
58 hash = wpabuf_put(msg, SHA256_MAC_LEN);
59 /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
60 addr[0] = wps->snonce;
61 len[0] = WPS_SECRET_NONCE_LEN;
62 addr[1] = wps->psk1;
63 len[1] = WPS_PSK_LEN;
64 addr[2] = wpabuf_head(wps->dh_pubkey_e);
65 len[2] = wpabuf_len(wps->dh_pubkey_e);
66 addr[3] = wpabuf_head(wps->dh_pubkey_r);
67 len[3] = wpabuf_len(wps->dh_pubkey_r);
68 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
69 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
70
71 wpa_printf(MSG_DEBUG, "WPS: * E-Hash2");
72 wpabuf_put_be16(msg, ATTR_E_HASH2);
73 wpabuf_put_be16(msg, SHA256_MAC_LEN);
74 hash = wpabuf_put(msg, SHA256_MAC_LEN);
75 /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
76 addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
77 addr[1] = wps->psk2;
78 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
79 wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
80
81 return 0;
82 }
83
84
wps_build_e_snonce1(struct wps_data * wps,struct wpabuf * msg)85 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
86 {
87 wpa_printf(MSG_DEBUG, "WPS: * E-SNonce1");
88 wpabuf_put_be16(msg, ATTR_E_SNONCE1);
89 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
90 wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
91 return 0;
92 }
93
94
wps_build_e_snonce2(struct wps_data * wps,struct wpabuf * msg)95 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
96 {
97 wpa_printf(MSG_DEBUG, "WPS: * E-SNonce2");
98 wpabuf_put_be16(msg, ATTR_E_SNONCE2);
99 wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
100 wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
101 WPS_SECRET_NONCE_LEN);
102 return 0;
103 }
104
105
wps_build_m1(struct wps_data * wps)106 static struct wpabuf * wps_build_m1(struct wps_data *wps)
107 {
108 struct wpabuf *msg;
109 u16 config_methods;
110 u8 multi_ap_backhaul_sta = 0;
111
112 if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
113 return NULL;
114 wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
115 wps->nonce_e, WPS_NONCE_LEN);
116
117 wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
118 msg = wpabuf_alloc(1000);
119 if (msg == NULL)
120 return NULL;
121
122 config_methods = wps->wps->config_methods;
123 if (wps->wps->ap && !wps->pbc_in_m1 &&
124 (wps->dev_password_len != 0 ||
125 (config_methods & WPS_CONFIG_DISPLAY))) {
126 /*
127 * These are the methods that the AP supports as an Enrollee
128 * for adding external Registrars, so remove PushButton.
129 *
130 * As a workaround for Windows 7 mechanism for probing WPS
131 * capabilities from M1, leave PushButton option if no PIN
132 * method is available or if WPS configuration enables PBC
133 * workaround.
134 */
135 config_methods &= ~WPS_CONFIG_PUSHBUTTON;
136 config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
137 WPS_CONFIG_PHY_PUSHBUTTON);
138 }
139
140 if (wps->multi_ap_backhaul_sta)
141 multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
142
143 if (wps_build_version(msg) ||
144 wps_build_msg_type(msg, WPS_M1) ||
145 wps_build_uuid_e(msg, wps->uuid_e) ||
146 wps_build_mac_addr(msg, wps->mac_addr_e) ||
147 wps_build_enrollee_nonce(wps, msg) ||
148 wps_build_public_key(wps, msg) ||
149 wps_build_auth_type_flags(wps, msg) ||
150 wps_build_encr_type_flags(wps, msg) ||
151 wps_build_conn_type_flags(wps, msg) ||
152 wps_build_config_methods(msg, config_methods) ||
153 wps_build_wps_state(wps, msg) ||
154 wps_build_device_attrs(&wps->wps->dev, msg) ||
155 wps_build_rf_bands(&wps->wps->dev, msg,
156 wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
157 wps_build_assoc_state(wps, msg) ||
158 wps_build_dev_password_id(msg, wps->dev_pw_id) ||
159 wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
160 wps_build_os_version(&wps->wps->dev, msg) ||
161 wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
162 wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
163 wpabuf_free(msg);
164 return NULL;
165 }
166
167 wps->state = RECV_M2;
168 return msg;
169 }
170
171
wps_build_m3(struct wps_data * wps)172 static struct wpabuf * wps_build_m3(struct wps_data *wps)
173 {
174 struct wpabuf *msg;
175
176 wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
177
178 if (wps->dev_password == NULL) {
179 wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
180 return NULL;
181 }
182 if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
183 return NULL;
184
185 if (wps->wps->ap && random_pool_ready() != 1) {
186 wpa_printf(MSG_INFO,
187 "WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
188 return NULL;
189 }
190
191 msg = wpabuf_alloc(1000);
192 if (msg == NULL)
193 return NULL;
194
195 if (wps_build_version(msg) ||
196 wps_build_msg_type(msg, WPS_M3) ||
197 wps_build_registrar_nonce(wps, msg) ||
198 wps_build_e_hash(wps, msg) ||
199 wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
200 wps_build_authenticator(wps, msg)) {
201 wpabuf_free(msg);
202 return NULL;
203 }
204
205 wps->state = RECV_M4;
206 return msg;
207 }
208
209
wps_build_m5(struct wps_data * wps)210 static struct wpabuf * wps_build_m5(struct wps_data *wps)
211 {
212 struct wpabuf *msg, *plain;
213
214 wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
215
216 plain = wpabuf_alloc(200);
217 if (plain == NULL)
218 return NULL;
219
220 msg = wpabuf_alloc(1000);
221 if (msg == NULL) {
222 wpabuf_free(plain);
223 return NULL;
224 }
225
226 if (wps_build_version(msg) ||
227 wps_build_msg_type(msg, WPS_M5) ||
228 wps_build_registrar_nonce(wps, msg) ||
229 wps_build_e_snonce1(wps, plain) ||
230 wps_build_key_wrap_auth(wps, plain) ||
231 wps_build_encr_settings(wps, msg, plain) ||
232 wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
233 wps_build_authenticator(wps, msg)) {
234 wpabuf_clear_free(plain);
235 wpabuf_free(msg);
236 return NULL;
237 }
238 wpabuf_clear_free(plain);
239
240 wps->state = RECV_M6;
241 return msg;
242 }
243
244
245 #ifndef ESP_SUPPLICANT
wps_build_cred_ssid(struct wps_data * wps,struct wpabuf * msg)246 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
247 {
248 wpa_printf(MSG_DEBUG, "WPS: * SSID");
249 wpabuf_put_be16(msg, ATTR_SSID);
250 wpabuf_put_be16(msg, wps->wps->ssid_len);
251 wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
252 return 0;
253 }
254
255
wps_build_cred_auth_type(struct wps_data * wps,struct wpabuf * msg)256 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
257 {
258 u16 auth_type = wps->wps->ap_auth_type;
259
260 /*
261 * Work around issues with Windows 7 WPS implementation not liking
262 * multiple Authentication Type bits in M7 AP Settings attribute by
263 * showing only the most secure option from current configuration.
264 */
265 if (auth_type & WPS_AUTH_WPA2PSK)
266 auth_type = WPS_AUTH_WPA2PSK;
267 else if (auth_type & WPS_AUTH_WPAPSK)
268 auth_type = WPS_AUTH_WPAPSK;
269 else if (auth_type & WPS_AUTH_OPEN)
270 auth_type = WPS_AUTH_OPEN;
271
272 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type (0x%x)", auth_type);
273 wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
274 wpabuf_put_be16(msg, 2);
275 wpabuf_put_be16(msg, auth_type);
276 return 0;
277 }
278
279
wps_build_cred_encr_type(struct wps_data * wps,struct wpabuf * msg)280 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
281 {
282 u16 encr_type = wps->wps->ap_encr_type;
283
284 /*
285 * Work around issues with Windows 7 WPS implementation not liking
286 * multiple Encryption Type bits in M7 AP Settings attribute by
287 * showing only the most secure option from current configuration.
288 */
289 if (wps->wps->ap_auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
290 if (encr_type & WPS_ENCR_AES)
291 encr_type = WPS_ENCR_AES;
292 else if (encr_type & WPS_ENCR_TKIP)
293 encr_type = WPS_ENCR_TKIP;
294 }
295
296 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type (0x%x)", encr_type);
297 wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
298 wpabuf_put_be16(msg, 2);
299 wpabuf_put_be16(msg, encr_type);
300 return 0;
301 }
302
303
wps_build_cred_network_key(struct wps_data * wps,struct wpabuf * msg)304 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
305 {
306 if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
307 wps->wps->network_key_len == 0) {
308 char hex[65];
309 u8 psk[32];
310 /* Generate a random per-device PSK */
311 if (random_pool_ready() != 1 ||
312 random_get_bytes(psk, sizeof(psk)) < 0) {
313 wpa_printf(MSG_INFO,
314 "WPS: Could not generate random PSK");
315 return -1;
316 }
317 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
318 psk, sizeof(psk));
319 wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
320 (unsigned int) wps->new_psk_len * 2);
321 wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
322 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
323 wpabuf_put_be16(msg, sizeof(psk) * 2);
324 wpabuf_put_data(msg, hex, sizeof(psk) * 2);
325 #ifdef CONFIG_WPS_REGISTRAR
326 if (wps->wps->registrar) {
327 wps_cb_new_psk(wps->wps->registrar,
328 wps->peer_dev.mac_addr,
329 wps->p2p_dev_addr, psk, sizeof(psk));
330 }
331 #endif
332 return 0;
333 }
334
335 wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%u)",
336 (unsigned int) wps->wps->network_key_len);
337 wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
338 wpabuf_put_be16(msg, wps->wps->network_key_len);
339 wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
340 return 0;
341 }
342
343
wps_build_cred_mac_addr(struct wps_data * wps,struct wpabuf * msg)344 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
345 {
346 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (AP BSSID)");
347 wpabuf_put_be16(msg, ATTR_MAC_ADDR);
348 wpabuf_put_be16(msg, ETH_ALEN);
349 wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
350 return 0;
351 }
352 #endif
353
wps_build_ap_settings(struct wps_data * wps,struct wpabuf * plain)354 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
355 {
356 #ifndef ESP_SUPPLICANT
357 const u8 *start, *end;
358 int ret;
359
360 if (wps->wps->ap_settings) {
361 wpa_printf(MSG_DEBUG, "WPS: * AP Settings (pre-configured)");
362 wpabuf_put_data(plain, wps->wps->ap_settings,
363 wps->wps->ap_settings_len);
364 return 0;
365 }
366
367 wpa_printf(MSG_DEBUG, "WPS: * AP Settings based on current configuration");
368 start = wpabuf_put(plain, 0);
369 ret = wps_build_cred_ssid(wps, plain) ||
370 wps_build_cred_mac_addr(wps, plain) ||
371 wps_build_cred_auth_type(wps, plain) ||
372 wps_build_cred_encr_type(wps, plain) ||
373 wps_build_cred_network_key(wps, plain);
374 end = wpabuf_put(plain, 0);
375
376 wpa_hexdump_key(MSG_DEBUG, "WPS: Plaintext AP Settings",
377 start, end - start);
378
379 return ret;
380 #else
381 return 0;
382 #endif
383 }
384
385
wps_build_m7(struct wps_data * wps)386 static struct wpabuf * wps_build_m7(struct wps_data *wps)
387 {
388 struct wpabuf *msg, *plain;
389
390 wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
391
392 plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
393 if (plain == NULL)
394 return NULL;
395
396 msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
397 if (msg == NULL) {
398 wpabuf_free(plain);
399 return NULL;
400 }
401
402 if (wps_build_version(msg) ||
403 wps_build_msg_type(msg, WPS_M7) ||
404 wps_build_registrar_nonce(wps, msg) ||
405 wps_build_e_snonce2(wps, plain) ||
406 (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
407 wps_build_key_wrap_auth(wps, plain) ||
408 wps_build_encr_settings(wps, msg, plain) ||
409 wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
410 wps_build_authenticator(wps, msg)) {
411 wpabuf_clear_free(plain);
412 wpabuf_free(msg);
413 return NULL;
414 }
415 wpabuf_clear_free(plain);
416
417 #ifdef CONFIG_WPS_REGISTRAR
418 if (wps->wps->ap && wps->wps->registrar) {
419 /*
420 * If the Registrar is only learning our current configuration,
421 * it may not continue protocol run to successful completion.
422 * Store information here to make sure it remains available.
423 */
424 wps_device_store(wps->wps->registrar, &wps->peer_dev,
425 wps->uuid_r);
426 }
427 #endif
428
429 wps->state = RECV_M8;
430 return msg;
431 }
432
433
wps_build_wsc_done(struct wps_data * wps)434 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
435 {
436 struct wpabuf *msg;
437
438 wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
439
440 msg = wpabuf_alloc(1000);
441 if (msg == NULL)
442 return NULL;
443
444 if (wps_build_version(msg) ||
445 wps_build_msg_type(msg, WPS_WSC_DONE) ||
446 wps_build_enrollee_nonce(wps, msg) ||
447 wps_build_registrar_nonce(wps, msg) ||
448 wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
449 wpabuf_free(msg);
450 return NULL;
451 }
452
453 if (wps->wps->ap)
454 wps->state = RECV_ACK;
455 else {
456 wps_success_event(wps->wps, wps->peer_dev.mac_addr);
457 wps->state = WPS_FINISHED;
458 }
459 return msg;
460 }
461
462
wps_enrollee_get_msg(struct wps_data * wps,enum wsc_op_code * op_code)463 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
464 enum wsc_op_code *op_code)
465 {
466 struct wpabuf *msg;
467
468 switch (wps->state) {
469 case SEND_M1:
470 msg = wps_build_m1(wps);
471 *op_code = WSC_MSG;
472 break;
473 case SEND_M3:
474 msg = wps_build_m3(wps);
475 *op_code = WSC_MSG;
476 break;
477 case SEND_M5:
478 msg = wps_build_m5(wps);
479 *op_code = WSC_MSG;
480 break;
481 case SEND_M7:
482 msg = wps_build_m7(wps);
483 *op_code = WSC_MSG;
484 break;
485 case RECEIVED_M2D:
486 if (wps->wps->ap) {
487 msg = wps_build_wsc_nack(wps);
488 *op_code = WSC_NACK;
489 break;
490 }
491 msg = wps_build_wsc_ack(wps);
492 *op_code = WSC_ACK;
493 if (msg) {
494 /* Another M2/M2D may be received */
495 wps->state = RECV_M2;
496 }
497 break;
498 case SEND_WSC_NACK:
499 msg = wps_build_wsc_nack(wps);
500 *op_code = WSC_NACK;
501 break;
502 case WPS_MSG_DONE:
503 msg = wps_build_wsc_done(wps);
504 *op_code = WSC_Done;
505 break;
506 default:
507 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
508 "a message", wps->state);
509 msg = NULL;
510 break;
511 }
512
513 if (*op_code == WSC_MSG && msg) {
514 /* Save a copy of the last message for Authenticator derivation
515 */
516 wpabuf_free(wps->last_msg);
517 wps->last_msg = wpabuf_dup(msg);
518 }
519
520 return msg;
521 }
522
523
wps_process_registrar_nonce(struct wps_data * wps,const u8 * r_nonce)524 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
525 {
526 if (r_nonce == NULL) {
527 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
528 return -1;
529 }
530
531 os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
532 wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
533 wps->nonce_r, WPS_NONCE_LEN);
534
535 return 0;
536 }
537
538
wps_process_enrollee_nonce(struct wps_data * wps,const u8 * e_nonce)539 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
540 {
541 if (e_nonce == NULL) {
542 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
543 return -1;
544 }
545
546 if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
547 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
548 return -1;
549 }
550
551 return 0;
552 }
553
554
wps_process_uuid_r(struct wps_data * wps,const u8 * uuid_r)555 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
556 {
557 if (uuid_r == NULL) {
558 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
559 return -1;
560 }
561
562 os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
563 wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
564
565 return 0;
566 }
567
568
wps_process_pubkey(struct wps_data * wps,const u8 * pk,size_t pk_len)569 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
570 size_t pk_len)
571 {
572 if (pk == NULL || pk_len == 0) {
573 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
574 return -1;
575 }
576
577 if (wps->peer_pubkey_hash_set) {
578 u8 hash[WPS_HASH_LEN];
579 sha256_vector(1, &pk, &pk_len, hash);
580 if (os_memcmp_const(hash, wps->peer_pubkey_hash,
581 WPS_OOB_PUBKEY_HASH_LEN) != 0) {
582 wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
583 wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
584 pk, pk_len);
585 wpa_hexdump(MSG_DEBUG, "WPS: Calculated public key "
586 "hash", hash, WPS_OOB_PUBKEY_HASH_LEN);
587 wpa_hexdump(MSG_DEBUG, "WPS: Expected public key hash",
588 wps->peer_pubkey_hash,
589 WPS_OOB_PUBKEY_HASH_LEN);
590 wps->config_error = WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
591 return -1;
592 }
593 }
594
595 wpabuf_free(wps->dh_pubkey_r);
596 wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
597 if (wps->dh_pubkey_r == NULL)
598 return -1;
599
600 if (wps_derive_keys(wps) < 0)
601 return -1;
602
603 return 0;
604 }
605
606
wps_process_r_hash1(struct wps_data * wps,const u8 * r_hash1)607 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
608 {
609 if (r_hash1 == NULL) {
610 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
611 return -1;
612 }
613
614 os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
615 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
616
617 return 0;
618 }
619
620
wps_process_r_hash2(struct wps_data * wps,const u8 * r_hash2)621 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
622 {
623 if (r_hash2 == NULL) {
624 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
625 return -1;
626 }
627
628 os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
629 wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
630
631 return 0;
632 }
633
634
wps_process_r_snonce1(struct wps_data * wps,const u8 * r_snonce1)635 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
636 {
637 u8 hash[SHA256_MAC_LEN];
638 const u8 *addr[4];
639 size_t len[4];
640
641 if (r_snonce1 == NULL) {
642 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
643 return -1;
644 }
645
646 wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
647 WPS_SECRET_NONCE_LEN);
648
649 /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
650 addr[0] = r_snonce1;
651 len[0] = WPS_SECRET_NONCE_LEN;
652 addr[1] = wps->psk1;
653 len[1] = WPS_PSK_LEN;
654 addr[2] = wpabuf_head(wps->dh_pubkey_e);
655 len[2] = wpabuf_len(wps->dh_pubkey_e);
656 addr[3] = wpabuf_head(wps->dh_pubkey_r);
657 len[3] = wpabuf_len(wps->dh_pubkey_r);
658 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
659
660 if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
661 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
662 "not match with the pre-committed value");
663 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
664 wps_pwd_auth_fail_event(wps->wps, 1, 1, wps->peer_dev.mac_addr);
665 return -1;
666 }
667
668 wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
669 "half of the device password");
670
671 return 0;
672 }
673
674
wps_process_r_snonce2(struct wps_data * wps,const u8 * r_snonce2)675 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
676 {
677 u8 hash[SHA256_MAC_LEN];
678 const u8 *addr[4];
679 size_t len[4];
680
681 if (r_snonce2 == NULL) {
682 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
683 return -1;
684 }
685
686 wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
687 WPS_SECRET_NONCE_LEN);
688
689 /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
690 addr[0] = r_snonce2;
691 len[0] = WPS_SECRET_NONCE_LEN;
692 addr[1] = wps->psk2;
693 len[1] = WPS_PSK_LEN;
694 addr[2] = wpabuf_head(wps->dh_pubkey_e);
695 len[2] = wpabuf_len(wps->dh_pubkey_e);
696 addr[3] = wpabuf_head(wps->dh_pubkey_r);
697 len[3] = wpabuf_len(wps->dh_pubkey_r);
698 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
699
700 if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
701 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
702 "not match with the pre-committed value");
703 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
704 wps_pwd_auth_fail_event(wps->wps, 1, 2, wps->peer_dev.mac_addr);
705 return -1;
706 }
707
708 wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
709 "half of the device password");
710
711 return 0;
712 }
713
714
wps_process_cred_e(struct wps_data * wps,const u8 * cred,size_t cred_len,int wps2)715 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
716 size_t cred_len, int wps2)
717 {
718 struct wps_parse_attr *attr;
719 struct wpabuf msg;
720 int ret = 0;
721
722 wpa_printf(MSG_DEBUG, "WPS: Received Credential");
723
724 attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
725 if (attr == NULL)
726 return -99;
727
728 os_memset(&wps->cred, 0, sizeof(wps->cred));
729 wpabuf_set(&msg, cred, cred_len);
730 if (wps_parse_msg(&msg, attr) < 0 ||
731 wps_process_cred(attr, &wps->cred)) {
732 ret = -1;
733 goto _out;
734 }
735
736 if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
737 0) {
738 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
739 MACSTR ") does not match with own address (" MACSTR
740 ")", MAC2STR(wps->cred.mac_addr),
741 MAC2STR(wps->wps->dev.mac_addr));
742 /*
743 * In theory, this could be consider fatal error, but there are
744 * number of deployed implementations using other address here
745 * due to unclarity in the specification. For interoperability
746 * reasons, allow this to be processed since we do not really
747 * use the MAC Address information for anything.
748 */
749 #ifdef CONFIG_WPS_STRICT
750 if (wps2) {
751 wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
752 "MAC Address in AP Settings");
753 ret = -1;
754 goto _out;
755 }
756 #endif /* CONFIG_WPS_STRICT */
757 }
758
759 if (!(wps->cred.encr_type &
760 (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES))) {
761 if (wps->cred.encr_type & WPS_ENCR_WEP) {
762 wpa_printf(MSG_INFO, "WPS: Reject Credential "
763 "due to WEP configuration");
764 wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
765 ret = -2;
766 goto _out;
767 }
768
769 wpa_printf(MSG_INFO, "WPS: Reject Credential due to "
770 "invalid encr_type 0x%x", wps->cred.encr_type);
771 ret = -1;
772 goto _out;
773 }
774
775 if (wps->wps->cred_cb) {
776 wps->cred.cred_attr = cred - 4;
777 wps->cred.cred_attr_len = cred_len + 4;
778 ret = wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
779 wps->cred.cred_attr = NULL;
780 wps->cred.cred_attr_len = 0;
781 }
782
783 _out:
784 if (attr)
785 os_free(attr);
786
787 return ret;
788 }
789
790
wps_process_creds(struct wps_data * wps,const u8 * cred[],u16 cred_len[],unsigned int num_cred,int wps2)791 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
792 u16 cred_len[], unsigned int num_cred, int wps2)
793 {
794 size_t i;
795 int ok = 0;
796
797 if (wps->wps->ap)
798 return 0;
799
800 if (num_cred == 0) {
801 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
802 "received");
803 return -1;
804 }
805
806 for (i = 0; i < num_cred; i++) {
807 int res;
808 res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
809 if (res == 0)
810 ok++;
811 else if (res == -2)
812 wpa_printf(MSG_DEBUG, "WPS: WEP credential skipped");
813 else
814 return -1;
815 }
816
817 if (ok == 0) {
818 wpa_printf(MSG_DEBUG, "WPS: No valid Credential attribute "
819 "received");
820 return -1;
821 }
822
823 return 0;
824 }
825
826
wps_process_ap_settings_e(struct wps_data * wps,struct wps_parse_attr * attr,struct wpabuf * attrs,int wps2)827 static int wps_process_ap_settings_e(struct wps_data *wps,
828 struct wps_parse_attr *attr,
829 struct wpabuf *attrs, int wps2)
830 {
831 struct wps_credential *cred;
832 int ret = 0;
833
834 cred = (struct wps_credential *)os_zalloc(sizeof(struct wps_credential));
835 if (cred == NULL) {
836 ret = -99;
837 goto _out;
838 }
839
840 if (!wps->wps->ap) {
841 ret = 0;
842 goto _out;
843 }
844
845 if (wps_process_ap_settings(attr, cred) < 0) {
846 ret = -1;
847 goto _out;
848 }
849
850 wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
851 "Registrar");
852
853 if (os_memcmp(cred->mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
854 0) {
855 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
856 MACSTR ") does not match with own address (" MACSTR
857 ")", MAC2STR(cred->mac_addr),
858 MAC2STR(wps->wps->dev.mac_addr));
859 /*
860 * In theory, this could be consider fatal error, but there are
861 * number of deployed implementations using other address here
862 * due to unclarity in the specification. For interoperability
863 * reasons, allow this to be processed since we do not really
864 * use the MAC Address information for anything.
865 */
866 #ifdef CONFIG_WPS_STRICT
867 if (wps2) {
868 wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
869 "MAC Address in AP Settings");
870 ret = -1;
871 goto _out;
872 }
873 #endif /* CONFIG_WPS_STRICT */
874 }
875
876 if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
877 {
878 if (cred->encr_type & WPS_ENCR_WEP) {
879 wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
880 "due to WEP configuration");
881 wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
882 ret = -1;
883 goto _out;
884 }
885
886 wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
887 "invalid encr_type 0x%x", cred->encr_type);
888 ret = -1;
889 goto _out;
890 }
891
892 #ifdef CONFIG_WPS_STRICT
893 if (wps2) {
894 if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
895 WPS_ENCR_TKIP ||
896 (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
897 WPS_AUTH_WPAPSK) {
898 wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
899 "AP Settings: WPA-Personal/TKIP only");
900 wps->error_indication =
901 WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
902 ret = -1;
903 goto _out;
904 }
905 }
906 #endif /* CONFIG_WPS_STRICT */
907
908 if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
909 {
910 wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
911 "TKIP+AES");
912 cred->encr_type |= WPS_ENCR_AES;
913 }
914
915 if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
916 WPS_AUTH_WPAPSK) {
917 wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
918 "WPAPSK+WPA2PSK");
919 cred->auth_type |= WPS_AUTH_WPA2PSK;
920 }
921
922 if (wps->wps->cred_cb) {
923 cred->cred_attr = wpabuf_head(attrs);
924 cred->cred_attr_len = wpabuf_len(attrs);
925 wps->wps->cred_cb(wps->wps->cb_ctx, cred);
926 }
927
928 _out:
929 if (cred)
930 os_free(cred);
931
932 return ret;
933 }
934
935
wps_process_dev_pw_id(struct wps_data * wps,const u8 * dev_pw_id)936 static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id)
937 {
938 u16 id;
939
940 if (dev_pw_id == NULL) {
941 wpa_printf(MSG_DEBUG, "WPS: Device Password ID");
942 return -1;
943 }
944
945 id = WPA_GET_BE16(dev_pw_id);
946 if (wps->dev_pw_id == id) {
947 wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id);
948 return 0;
949 }
950
951 #ifdef CONFIG_P2P
952 if ((id == DEV_PW_DEFAULT &&
953 wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) ||
954 (id == DEV_PW_REGISTRAR_SPECIFIED &&
955 wps->dev_pw_id == DEV_PW_DEFAULT)) {
956 /*
957 * Common P2P use cases indicate whether the PIN is from the
958 * client or GO using Device Password Id in M1/M2 in a way that
959 * does not look fully compliant with WSC specification. Anyway,
960 * this is deployed and needs to be allowed, so ignore changes
961 * between Registrar-Specified and Default PIN.
962 */
963 wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID "
964 "change");
965 return 0;
966 }
967 #endif /* CONFIG_P2P */
968
969 wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
970 "ID from %u to %u", wps->dev_pw_id, id);
971
972 if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) {
973 wpa_printf(MSG_DEBUG,
974 "WPS: Workaround - ignore PBC-to-PIN change");
975 return 0;
976 }
977
978 if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
979 wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
980 bin_clear_free(wps->dev_password, wps->dev_password_len);
981 wps->dev_pw_id = wps->alt_dev_pw_id;
982 wps->dev_password = wps->alt_dev_password;
983 wps->dev_password_len = wps->alt_dev_password_len;
984 wps->alt_dev_password = NULL;
985 wps->alt_dev_password_len = 0;
986 return 0;
987 }
988
989 return -1;
990 }
991
992
wps_process_m2(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)993 static enum wps_process_res wps_process_m2(struct wps_data *wps,
994 const struct wpabuf *msg,
995 struct wps_parse_attr *attr)
996 {
997 wpa_printf(MSG_DEBUG, "WPS: Received M2");
998
999 if (wps->state != RECV_M2) {
1000 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1001 "receiving M2", wps->state);
1002 wps->state = SEND_WSC_NACK;
1003 return WPS_CONTINUE;
1004 }
1005
1006 if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
1007 wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1008 wps_process_uuid_r(wps, attr->uuid_r) ||
1009 wps_process_dev_pw_id(wps, attr->dev_password_id)) {
1010 wps->state = SEND_WSC_NACK;
1011 return WPS_CONTINUE;
1012 }
1013
1014 /*
1015 * Stop here on an AP as an Enrollee if AP Setup is locked unless the
1016 * special locked mode is used to allow protocol run up to M7 in order
1017 * to support external Registrars that only learn the current AP
1018 * configuration without changing it.
1019 */
1020 if (wps->wps->ap &&
1021 ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) ||
1022 wps->dev_password == NULL)) {
1023 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1024 "registration of a new Registrar");
1025 wps->config_error = WPS_CFG_SETUP_LOCKED;
1026 wps->state = SEND_WSC_NACK;
1027 return WPS_CONTINUE;
1028 }
1029
1030 if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
1031 wps_process_authenticator(wps, attr->authenticator, msg) ||
1032 wps_process_device_attrs(&wps->peer_dev, attr)) {
1033 wps->state = SEND_WSC_NACK;
1034 return WPS_CONTINUE;
1035 }
1036
1037 #ifdef CONFIG_WPS_NFC
1038 if (wps->peer_pubkey_hash_set) {
1039 struct wpabuf *decrypted;
1040 struct wps_parse_attr eattr;
1041
1042 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1043 attr->encr_settings_len);
1044 if (decrypted == NULL) {
1045 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt "
1046 "Encrypted Settings attribute");
1047 wps->state = SEND_WSC_NACK;
1048 return WPS_CONTINUE;
1049 }
1050
1051 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted "
1052 "Settings attribute");
1053 if (wps_parse_msg(decrypted, &eattr) < 0 ||
1054 wps_process_key_wrap_auth(wps, decrypted,
1055 eattr.key_wrap_auth) ||
1056 wps_process_creds(wps, eattr.cred, eattr.cred_len,
1057 eattr.num_cred, attr->version2 != NULL)) {
1058 wpabuf_clear_free(decrypted);
1059 wps->state = SEND_WSC_NACK;
1060 return WPS_CONTINUE;
1061 }
1062 wpabuf_clear_free(decrypted);
1063
1064 wps->state = WPS_MSG_DONE;
1065 return WPS_CONTINUE;
1066 }
1067 #endif /* CONFIG_WPS_NFC */
1068
1069 wps->state = SEND_M3;
1070 return WPS_CONTINUE;
1071 }
1072
1073
wps_process_m2d(struct wps_data * wps,struct wps_parse_attr * attr)1074 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
1075 struct wps_parse_attr *attr)
1076 {
1077 wpa_printf(MSG_DEBUG, "WPS: Received M2D");
1078
1079 if (wps->state != RECV_M2) {
1080 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1081 "receiving M2D", wps->state);
1082 wps->state = SEND_WSC_NACK;
1083 return WPS_CONTINUE;
1084 }
1085
1086 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
1087 attr->manufacturer, attr->manufacturer_len);
1088 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
1089 attr->model_name, attr->model_name_len);
1090 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
1091 attr->model_number, attr->model_number_len);
1092 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
1093 attr->serial_number, attr->serial_number_len);
1094 wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
1095 attr->dev_name, attr->dev_name_len);
1096
1097 if (wps->wps->event_cb) {
1098 union wps_event_data data;
1099 struct wps_event_m2d *m2d = &data.m2d;
1100 os_memset(&data, 0, sizeof(data));
1101 if (attr->config_methods)
1102 m2d->config_methods =
1103 WPA_GET_BE16(attr->config_methods);
1104 m2d->manufacturer = attr->manufacturer;
1105 m2d->manufacturer_len = attr->manufacturer_len;
1106 m2d->model_name = attr->model_name;
1107 m2d->model_name_len = attr->model_name_len;
1108 m2d->model_number = attr->model_number;
1109 m2d->model_number_len = attr->model_number_len;
1110 m2d->serial_number = attr->serial_number;
1111 m2d->serial_number_len = attr->serial_number_len;
1112 m2d->dev_name = attr->dev_name;
1113 m2d->dev_name_len = attr->dev_name_len;
1114 m2d->primary_dev_type = attr->primary_dev_type;
1115 if (attr->config_error)
1116 m2d->config_error =
1117 WPA_GET_BE16(attr->config_error);
1118 if (attr->dev_password_id)
1119 m2d->dev_password_id =
1120 WPA_GET_BE16(attr->dev_password_id);
1121 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
1122 }
1123
1124 wps->state = RECEIVED_M2D;
1125 return WPS_CONTINUE;
1126 }
1127
1128
wps_process_m4(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1129 static enum wps_process_res wps_process_m4(struct wps_data *wps,
1130 const struct wpabuf *msg,
1131 struct wps_parse_attr *attr)
1132 {
1133 struct wpabuf *decrypted;
1134 struct wps_parse_attr *eattr;
1135 enum wps_process_res res;
1136
1137 wpa_printf(MSG_DEBUG, "WPS: Received M4");
1138
1139 eattr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1140 if (eattr == NULL) {
1141 wps->state = SEND_WSC_NACK;
1142 res = WPS_CONTINUE;
1143 goto _out;
1144 }
1145
1146 if (wps->state != RECV_M4) {
1147 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1148 "receiving M4", wps->state);
1149 wps->state = SEND_WSC_NACK;
1150 res = WPS_CONTINUE;
1151 goto _out;
1152 }
1153
1154 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1155 wps_process_authenticator(wps, attr->authenticator, msg) ||
1156 wps_process_r_hash1(wps, attr->r_hash1) ||
1157 wps_process_r_hash2(wps, attr->r_hash2)) {
1158 wps->state = SEND_WSC_NACK;
1159 res = WPS_CONTINUE;
1160 goto _out;
1161 }
1162
1163 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1164 attr->encr_settings_len);
1165 if (decrypted == NULL) {
1166 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1167 "Settings attribute");
1168 wps->state = SEND_WSC_NACK;
1169 res = WPS_CONTINUE;
1170 goto _out;
1171 }
1172
1173 if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
1174 wpabuf_clear_free(decrypted);
1175 wps->state = SEND_WSC_NACK;
1176 res = WPS_CONTINUE;
1177 goto _out;
1178 }
1179
1180 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1181 "attribute");
1182 if (wps_parse_msg(decrypted, eattr) < 0 ||
1183 wps_process_key_wrap_auth(wps, decrypted, eattr->key_wrap_auth) ||
1184 wps_process_r_snonce1(wps, eattr->r_snonce1)) {
1185 wpabuf_free(decrypted);
1186 wps->state = SEND_WSC_NACK;
1187 res = WPS_CONTINUE;
1188 goto _out;
1189 }
1190 wpabuf_clear_free(decrypted);
1191
1192 wps->state = SEND_M5;
1193 res = WPS_CONTINUE;
1194 _out:
1195 if (eattr)
1196 os_free(eattr);
1197 return res;
1198 }
1199
1200
wps_process_m6(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1201 static enum wps_process_res wps_process_m6(struct wps_data *wps,
1202 const struct wpabuf *msg,
1203 struct wps_parse_attr *attr)
1204 {
1205 struct wpabuf *decrypted;
1206 struct wps_parse_attr *eattr;
1207 enum wps_process_res res;
1208
1209 wpa_printf(MSG_DEBUG, "WPS: Received M6");
1210
1211 eattr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1212 if (eattr == NULL) {
1213 wps->state = SEND_WSC_NACK;
1214 res = WPS_CONTINUE;
1215 goto _out;
1216 }
1217
1218 if (wps->state != RECV_M6) {
1219 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1220 "receiving M6", wps->state);
1221 wps->state = SEND_WSC_NACK;
1222 res = WPS_CONTINUE;
1223 goto _out;
1224 }
1225
1226 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1227 wps_process_authenticator(wps, attr->authenticator, msg)) {
1228 wps->state = SEND_WSC_NACK;
1229 res = WPS_CONTINUE;
1230 goto _out;
1231 }
1232
1233 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1234 attr->encr_settings_len);
1235 if (decrypted == NULL) {
1236 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1237 "Settings attribute");
1238 wps->state = SEND_WSC_NACK;
1239 res = WPS_CONTINUE;
1240 goto _out;
1241 }
1242
1243 if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
1244 wpabuf_clear_free(decrypted);
1245 wps->state = SEND_WSC_NACK;
1246 res = WPS_CONTINUE;
1247 goto _out;
1248 }
1249
1250 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1251 "attribute");
1252 if (wps_parse_msg(decrypted, eattr) < 0 ||
1253 wps_process_key_wrap_auth(wps, decrypted, eattr->key_wrap_auth) ||
1254 wps_process_r_snonce2(wps, eattr->r_snonce2)) {
1255 wpabuf_free(decrypted);
1256 wps->state = SEND_WSC_NACK;
1257 res = WPS_CONTINUE;
1258 goto _out;
1259 }
1260 wpabuf_clear_free(decrypted);
1261
1262 if (wps->wps->ap)
1263 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
1264 NULL);
1265
1266 wps->state = SEND_M7;
1267 res = WPS_CONTINUE;
1268 _out:
1269 if (eattr)
1270 os_free(eattr);
1271 return res;
1272 }
1273
1274
wps_process_m8(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1275 static enum wps_process_res wps_process_m8(struct wps_data *wps,
1276 const struct wpabuf *msg,
1277 struct wps_parse_attr *attr)
1278 {
1279 struct wpabuf *decrypted;
1280 struct wps_parse_attr *eattr;
1281 enum wps_process_res res;
1282
1283 wpa_printf(MSG_DEBUG, "WPS: Received M8");
1284
1285 eattr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1286 if (eattr == NULL) {
1287 wps->state = SEND_WSC_NACK;
1288 res = WPS_CONTINUE;
1289 goto _out;
1290 }
1291
1292 if (wps->state != RECV_M8) {
1293 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1294 "receiving M8", wps->state);
1295 wps->state = SEND_WSC_NACK;
1296 res = WPS_CONTINUE;
1297 goto _out;
1298 }
1299
1300 if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1301 wps_process_authenticator(wps, attr->authenticator, msg)) {
1302 wps->state = SEND_WSC_NACK;
1303 res = WPS_CONTINUE;
1304 goto _out;
1305 }
1306
1307 if (wps->wps->ap && wps->wps->ap_setup_locked) {
1308 /*
1309 * Stop here if special ap_setup_locked == 2 mode allowed the
1310 * protocol to continue beyond M2. This allows ER to learn the
1311 * current AP settings without changing them.
1312 */
1313 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1314 "registration of a new Registrar");
1315 wps->config_error = WPS_CFG_SETUP_LOCKED;
1316 wps->state = SEND_WSC_NACK;
1317 res = WPS_CONTINUE;
1318 goto _out;
1319 }
1320
1321 decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1322 attr->encr_settings_len);
1323 if (decrypted == NULL) {
1324 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1325 "Settings attribute");
1326 wps->state = SEND_WSC_NACK;
1327 res = WPS_CONTINUE;
1328 goto _out;
1329 }
1330
1331 if (wps_validate_m8_encr(decrypted, wps->wps->ap,
1332 attr->version2 != NULL) < 0) {
1333 wpabuf_clear_free(decrypted);
1334 wps->state = SEND_WSC_NACK;
1335 res = WPS_CONTINUE;
1336 goto _out;
1337 }
1338
1339 wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1340 "attribute");
1341 if (wps_parse_msg(decrypted, eattr) < 0 ||
1342 wps_process_key_wrap_auth(wps, decrypted, eattr->key_wrap_auth) ||
1343 wps_process_creds(wps, eattr->cred, eattr->cred_len,
1344 eattr->num_cred, attr->version2 != NULL) ||
1345 wps_process_ap_settings_e(wps, eattr, decrypted,
1346 attr->version2 != NULL)) {
1347 wpabuf_free(decrypted);
1348 wps->state = SEND_WSC_NACK;
1349 res = WPS_CONTINUE;
1350 goto _out;
1351 }
1352 wpabuf_free(decrypted);
1353
1354 wps->state = WPS_MSG_DONE;
1355 res = WPS_CONTINUE;
1356
1357 _out:
1358 if (eattr)
1359 os_free(eattr);
1360 return res;
1361 }
1362
1363 extern struct wps_sm *gWpsSm;
1364
wps_process_wsc_start(struct wps_data * wps,const struct wpabuf * msg)1365 static enum wps_process_res wps_process_wsc_start(struct wps_data *wps,
1366 const struct wpabuf *msg)
1367 {
1368 enum wps_process_res ret = WPS_CONTINUE;
1369
1370 wpa_printf(MSG_DEBUG, "WPS: Received WSC_START");
1371 eloop_cancel_timeout(wifi_station_wps_eapol_start_handle, NULL, NULL);
1372 wps->state = SEND_M1;
1373 return ret;
1374 }
1375
1376
wps_process_wsc_msg(struct wps_data * wps,const struct wpabuf * msg)1377 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1378 const struct wpabuf *msg)
1379 {
1380 struct wps_parse_attr *attr;
1381 enum wps_process_res ret = WPS_CONTINUE;
1382
1383 wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1384
1385 attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1386 if (attr == NULL) {
1387 ret = WPS_FAILURE;
1388 goto _out;
1389 }
1390
1391 if (wps_parse_msg(msg, attr) < 0) {
1392 ret = WPS_FAILURE;
1393 goto _out;
1394 }
1395
1396 if (attr->enrollee_nonce == NULL ||
1397 os_memcmp(wps->nonce_e, attr->enrollee_nonce, WPS_NONCE_LEN) != 0) {
1398 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1399 ret = WPS_FAILURE;
1400 goto _out;
1401 }
1402
1403 if (attr->msg_type == NULL) {
1404 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1405 wps->state = SEND_WSC_NACK;
1406 ret = WPS_CONTINUE;
1407 goto _out;
1408 }
1409
1410 switch (*attr->msg_type) {
1411 case WPS_M2:
1412 if (wps_validate_m2(msg) < 0) {
1413 ret = WPS_FAILURE;
1414 goto _out;
1415 }
1416 ret = wps_process_m2(wps, msg, attr);
1417 break;
1418 case WPS_M2D:
1419 if (wps_validate_m2d(msg) < 0) {
1420 ret = WPS_FAILURE;
1421 goto _out;
1422 }
1423 ret = wps_process_m2d(wps, attr);
1424 break;
1425 case WPS_M4:
1426 if (wps_validate_m4(msg) < 0) {
1427 ret = WPS_FAILURE;
1428 goto _out;
1429 }
1430 ret = wps_process_m4(wps, msg, attr);
1431 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1432 wps_fail_event(wps->wps, WPS_M4, wps->config_error,
1433 wps->error_indication,
1434 wps->peer_dev.mac_addr);
1435 break;
1436 case WPS_M6:
1437 if (wps_validate_m6(msg) < 0) {
1438 ret = WPS_FAILURE;
1439 goto _out;
1440 }
1441 ret = wps_process_m6(wps, msg, attr);
1442 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1443 wps_fail_event(wps->wps, WPS_M6, wps->config_error,
1444 wps->error_indication,
1445 wps->peer_dev.mac_addr);
1446 break;
1447 case WPS_M8:
1448 if (wps_validate_m8(msg) < 0) {
1449 ret = WPS_FAILURE;
1450 goto _out;
1451 }
1452 ret = wps_process_m8(wps, msg, attr);
1453 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1454 wps_fail_event(wps->wps, WPS_M8, wps->config_error,
1455 wps->error_indication,
1456 wps->peer_dev.mac_addr);
1457 break;
1458 default:
1459 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1460 *attr->msg_type);
1461 ret = WPS_FAILURE;
1462 goto _out;
1463 }
1464
1465 /*
1466 * Save a copy of the last message for Authenticator derivation if we
1467 * are continuing. However, skip M2D since it is not authenticated and
1468 * neither is the ACK/NACK response frame. This allows the possibly
1469 * following M2 to be processed correctly by using the previously sent
1470 * M1 in Authenticator derivation.
1471 */
1472 if (ret == WPS_CONTINUE && *attr->msg_type != WPS_M2D) {
1473 /* Save a copy of the last message for Authenticator derivation
1474 */
1475 wpabuf_free(wps->last_msg);
1476 wps->last_msg = wpabuf_dup(msg);
1477 }
1478
1479 _out:
1480 if (attr)
1481 os_free(attr);
1482
1483 return ret;
1484 }
1485
1486
wps_process_wsc_ack(struct wps_data * wps,const struct wpabuf * msg)1487 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1488 const struct wpabuf *msg)
1489 {
1490 struct wps_parse_attr *attr;
1491 enum wps_process_res res;
1492
1493 wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1494
1495 attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1496 if (attr == NULL) {
1497 res = WPS_FAILURE;
1498 goto _out;
1499 }
1500
1501 if (wps_parse_msg(msg, attr) < 0) {
1502 res = WPS_FAILURE;
1503 goto _out;
1504 }
1505
1506 if (attr->msg_type == NULL) {
1507 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1508 res = WPS_FAILURE;
1509 goto _out;
1510 }
1511
1512 if (*attr->msg_type != WPS_WSC_ACK) {
1513 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1514 *attr->msg_type);
1515 res = WPS_FAILURE;
1516 goto _out;
1517 }
1518
1519 if (attr->registrar_nonce == NULL ||
1520 os_memcmp(wps->nonce_r, attr->registrar_nonce, WPS_NONCE_LEN) != 0)
1521 {
1522 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1523 res = WPS_FAILURE;
1524 goto _out;
1525 }
1526
1527 if (attr->enrollee_nonce == NULL ||
1528 os_memcmp(wps->nonce_e, attr->enrollee_nonce, WPS_NONCE_LEN) != 0) {
1529 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1530 res = WPS_FAILURE;
1531 goto _out;
1532 }
1533
1534 if (wps->state == RECV_ACK && wps->wps->ap) {
1535 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1536 "completed successfully");
1537 wps_success_event(wps->wps, wps->peer_dev.mac_addr);
1538 wps->state = WPS_FINISHED;
1539 res = WPS_DONE;
1540 goto _out;
1541 }
1542
1543 res = WPS_FAILURE;
1544 _out:
1545 if (attr)
1546 os_free(attr);
1547
1548 return res;
1549 }
1550
1551
wps_process_wsc_nack(struct wps_data * wps,const struct wpabuf * msg)1552 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1553 const struct wpabuf *msg)
1554 {
1555 struct wps_parse_attr *attr;
1556 enum wps_process_res res;
1557 u16 config_error;
1558
1559 wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1560
1561 attr = (struct wps_parse_attr *)os_zalloc(sizeof(struct wps_parse_attr));
1562 if (attr == NULL) {
1563 res = WPS_FAILURE;
1564 goto _out;
1565 }
1566
1567 if (wps_parse_msg(msg, attr) < 0) {
1568 res = WPS_FAILURE;
1569 goto _out;
1570 }
1571
1572 if (attr->msg_type == NULL) {
1573 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1574 res = WPS_FAILURE;
1575 goto _out;
1576 }
1577
1578 if (*attr->msg_type != WPS_WSC_NACK) {
1579 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1580 *attr->msg_type);
1581 res = WPS_FAILURE;
1582 goto _out;
1583 }
1584
1585 if (attr->registrar_nonce == NULL ||
1586 os_memcmp(wps->nonce_r, attr->registrar_nonce, WPS_NONCE_LEN) != 0)
1587 {
1588 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1589 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1590 attr->registrar_nonce, WPS_NONCE_LEN);
1591 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1592 wps->nonce_r, WPS_NONCE_LEN);
1593 res = WPS_FAILURE;
1594 goto _out;
1595 }
1596
1597 if (attr->enrollee_nonce == NULL ||
1598 os_memcmp(wps->nonce_e, attr->enrollee_nonce, WPS_NONCE_LEN) != 0) {
1599 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1600 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1601 attr->enrollee_nonce, WPS_NONCE_LEN);
1602 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1603 wps->nonce_e, WPS_NONCE_LEN);
1604 res = WPS_FAILURE;
1605 goto _out;
1606 }
1607
1608 if (attr->config_error == NULL) {
1609 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1610 "in WSC_NACK");
1611 res = WPS_FAILURE;
1612 goto _out;
1613 }
1614
1615 config_error = WPA_GET_BE16(attr->config_error);
1616 wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
1617 "Configuration Error %d", config_error);
1618
1619 switch (wps->state) {
1620 case RECV_M4:
1621 wps_fail_event(wps->wps, WPS_M3, config_error,
1622 wps->error_indication, wps->peer_dev.mac_addr);
1623 break;
1624 case RECV_M6:
1625 wps_fail_event(wps->wps, WPS_M5, config_error,
1626 wps->error_indication, wps->peer_dev.mac_addr);
1627 break;
1628 case RECV_M8:
1629 wps_fail_event(wps->wps, WPS_M7, config_error,
1630 wps->error_indication, wps->peer_dev.mac_addr);
1631 break;
1632 default:
1633 break;
1634 }
1635
1636 /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1637 * Enrollee is Authenticator */
1638 wps->state = SEND_WSC_NACK;
1639
1640 res = WPS_FAILURE;
1641 _out:
1642 if (attr)
1643 os_free(attr);
1644
1645 return res;
1646 }
1647
1648
wps_enrollee_process_msg(struct wps_data * wps,enum wsc_op_code op_code,const struct wpabuf * msg)1649 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
1650 enum wsc_op_code op_code,
1651 const struct wpabuf *msg)
1652 {
1653
1654 wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1655 "op_code=%d)",
1656 (unsigned long) wpabuf_len(msg), op_code);
1657
1658 if (op_code == WSC_UPnP) {
1659 /* Determine the OpCode based on message type attribute */
1660 struct wps_parse_attr attr;
1661 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
1662 if (*attr.msg_type == WPS_WSC_ACK)
1663 op_code = WSC_ACK;
1664 else if (*attr.msg_type == WPS_WSC_NACK)
1665 op_code = WSC_NACK;
1666 }
1667 }
1668
1669 switch (op_code) {
1670 case WSC_Start:
1671 return wps_process_wsc_start(wps, msg);
1672 case WSC_MSG:
1673 case WSC_UPnP:
1674 return wps_process_wsc_msg(wps, msg);
1675 case WSC_ACK:
1676 if (wps_validate_wsc_ack(msg) < 0)
1677 return WPS_FAILURE;
1678 return wps_process_wsc_ack(wps, msg);
1679 case WSC_NACK:
1680 if (wps_validate_wsc_nack(msg) < 0)
1681 return WPS_FAILURE;
1682 return wps_process_wsc_nack(wps, msg);
1683 default:
1684 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1685 return WPS_FAILURE;
1686 }
1687 }
1688