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