1 /*
2  * Wi-Fi Protected Setup - Strict protocol validation routines
3  * Copyright (c) 2010, Atheros Communications, Inc.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #include "utils/common.h"
12 #include "wps_i.h"
13 #include "wps.h"
14 
15 
16 #ifndef WPS_STRICT_ALL
17 #define WPS_STRICT_WPS2
18 #endif /* WPS_STRICT_ALL */
19 
20 
21 static int wps_validate_version(const u8 *version, int mandatory)
22 {
23 	if (version == NULL) {
24 		if (mandatory) {
25 			wpa_printf(MSG_INFO, "WPS-STRICT: Version attribute "
26 				   "missing");
27 			return -1;
28 		}
29 		return 0;
30 	}
31 	if (*version != 0x10) {
32 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version attribute "
33 			   "value 0x%x", *version);
34 		return -1;
35 	}
36 	return 0;
37 }
38 
39 
40 static int wps_validate_version2(const u8 *version2, int mandatory)
41 {
42 	if (version2 == NULL) {
43 		if (mandatory) {
44 			wpa_printf(MSG_INFO, "WPS-STRICT: Version2 attribute "
45 				   "missing");
46 			return -1;
47 		}
48 		return 0;
49 	}
50 	if (*version2 < 0x20) {
51 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version2 attribute "
52 			   "value 0x%x", *version2);
53 		return -1;
54 	}
55 	return 0;
56 }
57 
58 
59 static int wps_validate_request_type(const u8 *request_type, int mandatory)
60 {
61 	if (request_type == NULL) {
62 		if (mandatory) {
63 			wpa_printf(MSG_INFO, "WPS-STRICT: Request Type "
64 				   "attribute missing");
65 			return -1;
66 		}
67 		return 0;
68 	}
69 	if (*request_type > 0x03) {
70 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request Type "
71 			   "attribute value 0x%x", *request_type);
72 		return -1;
73 	}
74 	return 0;
75 }
76 
77 
78 static int wps_validate_response_type(const u8 *response_type, int mandatory)
79 {
80 	if (response_type == NULL) {
81 		if (mandatory) {
82 			wpa_printf(MSG_INFO, "WPS-STRICT: Response Type "
83 				   "attribute missing");
84 			return -1;
85 		}
86 		return 0;
87 	}
88 	if (*response_type > 0x03) {
89 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Response Type "
90 			   "attribute value 0x%x", *response_type);
91 		return -1;
92 	}
93 	return 0;
94 }
95 
96 
97 static int valid_config_methods(u16 val, int wps2)
98 {
99 	if (wps2) {
100 		if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
101 			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
102 				   "Display flag without old Display flag "
103 				   "set");
104 			return 0;
105 		}
106 		if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
107 			wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
108 				   "without Physical/Virtual Display flag");
109 			return 0;
110 		}
111 		if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
112 			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
113 				   "PushButton flag without old PushButton "
114 				   "flag set");
115 			return 0;
116 		}
117 		if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
118 			wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
119 				   "without Physical/Virtual PushButton flag");
120 			return 0;
121 		}
122 	}
123 
124 	return 1;
125 }
126 
127 
128 static int wps_validate_config_methods(const u8 *config_methods, int wps2,
129 				       int mandatory)
130 {
131 	u16 val;
132 
133 	if (config_methods == NULL) {
134 		if (mandatory) {
135 			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration "
136 				   "Methods attribute missing");
137 			return -1;
138 		}
139 		return 0;
140 	}
141 
142 	val = WPA_GET_BE16(config_methods);
143 	if (!valid_config_methods(val, wps2)) {
144 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
145 			   "Methods attribute value 0x%04x", val);
146 		return -1;
147 	}
148 	return 0;
149 }
150 
151 
152 static int wps_validate_ap_config_methods(const u8 *config_methods, int wps2,
153 					  int mandatory)
154 {
155 	u16 val;
156 
157 	if (wps_validate_config_methods(config_methods, wps2, mandatory) < 0)
158 		return -1;
159 	if (config_methods == NULL)
160 		return 0;
161 	val = WPA_GET_BE16(config_methods);
162 	if (val & WPS_CONFIG_PUSHBUTTON) {
163 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
164 			   "Methods attribute value 0x%04x in AP info "
165 			   "(PushButton not allowed for registering new ER)",
166 			   val);
167 		return -1;
168 	}
169 	return 0;
170 }
171 
172 
173 static int wps_validate_uuid_e(const u8 *uuid_e, int mandatory)
174 {
175 	if (uuid_e == NULL) {
176 		if (mandatory) {
177 			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-E "
178 				   "attribute missing");
179 			return -1;
180 		}
181 		return 0;
182 	}
183 	return 0;
184 }
185 
186 
187 static int wps_validate_uuid_r(const u8 *uuid_r, int mandatory)
188 {
189 	if (uuid_r == NULL) {
190 		if (mandatory) {
191 			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-R "
192 				   "attribute missing");
193 			return -1;
194 		}
195 		return 0;
196 	}
197 	return 0;
198 }
199 
200 
201 static int wps_validate_primary_dev_type(const u8 *primary_dev_type,
202 					 int mandatory)
203 {
204 	if (primary_dev_type == NULL) {
205 		if (mandatory) {
206 			wpa_printf(MSG_INFO, "WPS-STRICT: Primary Device Type "
207 				   "attribute missing");
208 			return -1;
209 		}
210 		return 0;
211 	}
212 	return 0;
213 }
214 
215 
216 static int wps_validate_rf_bands(const u8 *rf_bands, int mandatory)
217 {
218 	if (rf_bands == NULL) {
219 		if (mandatory) {
220 			wpa_printf(MSG_INFO, "WPS-STRICT: RF Bands "
221 				   "attribute missing");
222 			return -1;
223 		}
224 		return 0;
225 	}
226 	if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
227 	    *rf_bands != WPS_RF_60GHZ &&
228 	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ | WPS_RF_60GHZ) &&
229 	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
230 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
231 			   "attribute value 0x%x", *rf_bands);
232 		return -1;
233 	}
234 	return 0;
235 }
236 
237 
238 static int wps_validate_assoc_state(const u8 *assoc_state, int mandatory)
239 {
240 	u16 val;
241 	if (assoc_state == NULL) {
242 		if (mandatory) {
243 			wpa_printf(MSG_INFO, "WPS-STRICT: Association State "
244 				   "attribute missing");
245 			return -1;
246 		}
247 		return 0;
248 	}
249 	val = WPA_GET_BE16(assoc_state);
250 	if (val > 4) {
251 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Association State "
252 			   "attribute value 0x%04x", val);
253 		return -1;
254 	}
255 	return 0;
256 }
257 
258 
259 static int wps_validate_config_error(const u8 *config_error, int mandatory)
260 {
261 	u16 val;
262 
263 	if (config_error == NULL) {
264 		if (mandatory) {
265 			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration Error "
266 				   "attribute missing");
267 			return -1;
268 		}
269 		return 0;
270 	}
271 	val = WPA_GET_BE16(config_error);
272 	if (val > 20) {
273 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
274 			   "attribute value 0x%04x", val);
275 		return -1;
276 	}
277 	return 0;
278 }
279 
280 
281 static int wps_validate_dev_password_id(const u8 *dev_password_id,
282 					int mandatory)
283 {
284 	u16 val;
285 
286 	if (dev_password_id == NULL) {
287 		if (mandatory) {
288 			wpa_printf(MSG_INFO, "WPS-STRICT: Device Password ID "
289 				   "attribute missing");
290 			return -1;
291 		}
292 		return 0;
293 	}
294 	val = WPA_GET_BE16(dev_password_id);
295 	if (val >= 0x0008 && val <= 0x000f) {
296 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
297 			   "attribute value 0x%04x", val);
298 		return -1;
299 	}
300 	return 0;
301 }
302 
303 
304 static int wps_validate_manufacturer(const u8 *manufacturer, size_t len,
305 				     int mandatory)
306 {
307 	if (manufacturer == NULL) {
308 		if (mandatory) {
309 			wpa_printf(MSG_INFO, "WPS-STRICT: Manufacturer "
310 				   "attribute missing");
311 			return -1;
312 		}
313 		return 0;
314 	}
315 	if (len > 0 && manufacturer[len - 1] == 0) {
316 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Manufacturer "
317 			   "attribute value", manufacturer, len);
318 		return -1;
319 	}
320 	return 0;
321 }
322 
323 
324 static int wps_validate_model_name(const u8 *model_name, size_t len,
325 				   int mandatory)
326 {
327 	if (model_name == NULL) {
328 		if (mandatory) {
329 			wpa_printf(MSG_INFO, "WPS-STRICT: Model Name "
330 				   "attribute missing");
331 			return -1;
332 		}
333 		return 0;
334 	}
335 	if (len > 0 && model_name[len - 1] == 0) {
336 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Name "
337 			   "attribute value", model_name, len);
338 		return -1;
339 	}
340 	return 0;
341 }
342 
343 
344 static int wps_validate_model_number(const u8 *model_number, size_t len,
345 				     int mandatory)
346 {
347 	if (model_number == NULL) {
348 		if (mandatory) {
349 			wpa_printf(MSG_INFO, "WPS-STRICT: Model Number "
350 				   "attribute missing");
351 			return -1;
352 		}
353 		return 0;
354 	}
355 	if (len > 0 && model_number[len - 1] == 0) {
356 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Number "
357 			   "attribute value", model_number, len);
358 		return -1;
359 	}
360 	return 0;
361 }
362 
363 
364 static int wps_validate_serial_number(const u8 *serial_number, size_t len,
365 				      int mandatory)
366 {
367 	if (serial_number == NULL) {
368 		if (mandatory) {
369 			wpa_printf(MSG_INFO, "WPS-STRICT: Serial Number "
370 				   "attribute missing");
371 			return -1;
372 		}
373 		return 0;
374 	}
375 	if (len > 0 && serial_number[len - 1] == 0) {
376 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Serial "
377 				  "Number attribute value",
378 				  serial_number, len);
379 		return -1;
380 	}
381 	return 0;
382 }
383 
384 
385 static int wps_validate_dev_name(const u8 *dev_name, size_t len,
386 				 int mandatory)
387 {
388 	if (dev_name == NULL) {
389 		if (mandatory) {
390 			wpa_printf(MSG_INFO, "WPS-STRICT: Device Name "
391 				   "attribute missing");
392 			return -1;
393 		}
394 		return 0;
395 	}
396 	if (len > 0 && dev_name[len - 1] == 0) {
397 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Device Name "
398 			   "attribute value", dev_name, len);
399 		return -1;
400 	}
401 	return 0;
402 }
403 
404 
405 static int wps_validate_request_to_enroll(const u8 *request_to_enroll,
406 					  int mandatory)
407 {
408 	if (request_to_enroll == NULL) {
409 		if (mandatory) {
410 			wpa_printf(MSG_INFO, "WPS-STRICT: Request to Enroll "
411 				   "attribute missing");
412 			return -1;
413 		}
414 		return 0;
415 	}
416 	if (*request_to_enroll > 0x01) {
417 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request to Enroll "
418 			   "attribute value 0x%x", *request_to_enroll);
419 		return -1;
420 	}
421 	return 0;
422 }
423 
424 
425 static int wps_validate_req_dev_type(const u8 *req_dev_type[], size_t num,
426 				     int mandatory)
427 {
428 	if (num == 0) {
429 		if (mandatory) {
430 			wpa_printf(MSG_INFO, "WPS-STRICT: Requested Device "
431 				   "Type attribute missing");
432 			return -1;
433 		}
434 		return 0;
435 	}
436 	return 0;
437 }
438 
439 
440 static int wps_validate_wps_state(const u8 *wps_state, int mandatory)
441 {
442 	if (wps_state == NULL) {
443 		if (mandatory) {
444 			wpa_printf(MSG_INFO, "WPS-STRICT: Wi-Fi Protected "
445 				   "Setup State attribute missing");
446 			return -1;
447 		}
448 		return 0;
449 	}
450 	if (*wps_state != WPS_STATE_NOT_CONFIGURED &&
451 	    *wps_state != WPS_STATE_CONFIGURED) {
452 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Wi-Fi Protected "
453 			   "Setup State attribute value 0x%x", *wps_state);
454 		return -1;
455 	}
456 	return 0;
457 }
458 
459 
460 static int wps_validate_ap_setup_locked(const u8 *ap_setup_locked,
461 					int mandatory)
462 {
463 	if (ap_setup_locked == NULL) {
464 		if (mandatory) {
465 			wpa_printf(MSG_INFO, "WPS-STRICT: AP Setup Locked "
466 				   "attribute missing");
467 			return -1;
468 		}
469 		return 0;
470 	}
471 	if (*ap_setup_locked > 1) {
472 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid AP Setup Locked "
473 			   "attribute value 0x%x", *ap_setup_locked);
474 		return -1;
475 	}
476 	return 0;
477 }
478 
479 
480 static int wps_validate_selected_registrar(const u8 *selected_registrar,
481 					   int mandatory)
482 {
483 	if (selected_registrar == NULL) {
484 		if (mandatory) {
485 			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
486 				   "attribute missing");
487 			return -1;
488 		}
489 		return 0;
490 	}
491 	if (*selected_registrar > 1) {
492 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
493 			   "attribute value 0x%x", *selected_registrar);
494 		return -1;
495 	}
496 	return 0;
497 }
498 
499 
500 static int wps_validate_sel_reg_config_methods(const u8 *config_methods,
501 					       int wps2, int mandatory)
502 {
503 	u16 val;
504 
505 	if (config_methods == NULL) {
506 		if (mandatory) {
507 			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
508 				   "Configuration Methods attribute missing");
509 			return -1;
510 		}
511 		return 0;
512 	}
513 
514 	val = WPA_GET_BE16(config_methods);
515 	if (!valid_config_methods(val, wps2)) {
516 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
517 			   "Configuration Methods attribute value 0x%04x",
518 			   val);
519 		return -1;
520 	}
521 	return 0;
522 }
523 
524 
525 static int wps_validate_authorized_macs(const u8 *authorized_macs, size_t len,
526 					int mandatory)
527 {
528 	if (authorized_macs == NULL) {
529 		if (mandatory) {
530 			wpa_printf(MSG_INFO, "WPS-STRICT: Authorized MACs "
531 				   "attribute missing");
532 			return -1;
533 		}
534 		return 0;
535 	}
536 	if (len > 30 && (len % ETH_ALEN) != 0) {
537 		wpa_hexdump(MSG_INFO, "WPS-STRICT: Invalid Authorized "
538 			    "MACs attribute value", authorized_macs, len);
539 		return -1;
540 	}
541 	return 0;
542 }
543 
544 
545 static int wps_validate_msg_type(const u8 *msg_type, int mandatory)
546 {
547 	if (msg_type == NULL) {
548 		if (mandatory) {
549 			wpa_printf(MSG_INFO, "WPS-STRICT: Message Type "
550 				   "attribute missing");
551 			return -1;
552 		}
553 		return 0;
554 	}
555 	if (*msg_type < WPS_Beacon || *msg_type > WPS_WSC_DONE) {
556 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Message Type "
557 			   "attribute value 0x%x", *msg_type);
558 		return -1;
559 	}
560 	return 0;
561 }
562 
563 
564 static int wps_validate_mac_addr(const u8 *mac_addr, int mandatory)
565 {
566 	if (mac_addr == NULL) {
567 		if (mandatory) {
568 			wpa_printf(MSG_INFO, "WPS-STRICT: MAC Address "
569 				   "attribute missing");
570 			return -1;
571 		}
572 		return 0;
573 	}
574 	if (mac_addr[0] & 0x01) {
575 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid MAC Address "
576 			   "attribute value " MACSTR, MAC2STR(mac_addr));
577 		return -1;
578 	}
579 	return 0;
580 }
581 
582 
583 static int wps_validate_enrollee_nonce(const u8 *enrollee_nonce, int mandatory)
584 {
585 	if (enrollee_nonce == NULL) {
586 		if (mandatory) {
587 			wpa_printf(MSG_INFO, "WPS-STRICT: Enrollee Nonce "
588 				   "attribute missing");
589 			return -1;
590 		}
591 		return 0;
592 	}
593 	return 0;
594 }
595 
596 
597 static int wps_validate_registrar_nonce(const u8 *registrar_nonce,
598 					int mandatory)
599 {
600 	if (registrar_nonce == NULL) {
601 		if (mandatory) {
602 			wpa_printf(MSG_INFO, "WPS-STRICT: Registrar Nonce "
603 				   "attribute missing");
604 			return -1;
605 		}
606 		return 0;
607 	}
608 	return 0;
609 }
610 
611 
612 static int wps_validate_public_key(const u8 *public_key, size_t len,
613 				   int mandatory)
614 {
615 	if (public_key == NULL) {
616 		if (mandatory) {
617 			wpa_printf(MSG_INFO, "WPS-STRICT: Public Key "
618 				   "attribute missing");
619 			return -1;
620 		}
621 		return 0;
622 	}
623 	if (len != 192) {
624 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Public Key "
625 			   "attribute length %d", (int) len);
626 		return -1;
627 	}
628 	return 0;
629 }
630 
631 
632 static int num_bits_set(u16 val)
633 {
634 	int c;
635 	for (c = 0; val; c++)
636 		val &= val - 1;
637 	return c;
638 }
639 
640 
641 static int wps_validate_auth_type_flags(const u8 *flags, int mandatory)
642 {
643 	u16 val;
644 
645 	if (flags == NULL) {
646 		if (mandatory) {
647 			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
648 				   "Flags attribute missing");
649 			return -1;
650 		}
651 		return 0;
652 	}
653 	val = WPA_GET_BE16(flags);
654 	if ((val & ~WPS_AUTH_TYPES) || !(val & WPS_AUTH_WPA2PSK)) {
655 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
656 			   "Flags attribute value 0x%04x", val);
657 		return -1;
658 	}
659 	return 0;
660 }
661 
662 
663 static int wps_validate_auth_type(const u8 *type, int mandatory)
664 {
665 	u16 val;
666 
667 	if (type == NULL) {
668 		if (mandatory) {
669 			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
670 				   "attribute missing");
671 			return -1;
672 		}
673 		return 0;
674 	}
675 	val = WPA_GET_BE16(type);
676 	if ((val & ~WPS_AUTH_TYPES) || val == 0 ||
677 	    (num_bits_set(val) > 1 &&
678 	     val != (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK))) {
679 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
680 			   "attribute value 0x%04x", val);
681 		return -1;
682 	}
683 	return 0;
684 }
685 
686 
687 static int wps_validate_encr_type_flags(const u8 *flags, int mandatory)
688 {
689 	u16 val;
690 
691 	if (flags == NULL) {
692 		if (mandatory) {
693 			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
694 				   "Flags attribute missing");
695 			return -1;
696 		}
697 		return 0;
698 	}
699 	val = WPA_GET_BE16(flags);
700 	if ((val & ~WPS_ENCR_TYPES) || !(val & WPS_ENCR_AES)) {
701 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
702 			   "Flags attribute value 0x%04x", val);
703 		return -1;
704 	}
705 	return 0;
706 }
707 
708 
709 static int wps_validate_encr_type(const u8 *type, int mandatory)
710 {
711 	u16 val;
712 
713 	if (type == NULL) {
714 		if (mandatory) {
715 			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
716 				   "attribute missing");
717 			return -1;
718 		}
719 		return 0;
720 	}
721 	val = WPA_GET_BE16(type);
722 	if ((val & ~WPS_ENCR_TYPES) || val == 0 ||
723 	    (num_bits_set(val) > 1 && val != (WPS_ENCR_TKIP | WPS_ENCR_AES))) {
724 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
725 			   "attribute value 0x%04x", val);
726 		return -1;
727 	}
728 	return 0;
729 }
730 
731 
732 static int wps_validate_conn_type_flags(const u8 *flags, int mandatory)
733 {
734 	if (flags == NULL) {
735 		if (mandatory) {
736 			wpa_printf(MSG_INFO, "WPS-STRICT: Connection Type "
737 				   "Flags attribute missing");
738 			return -1;
739 		}
740 		return 0;
741 	}
742 	if ((*flags & ~(WPS_CONN_ESS | WPS_CONN_IBSS)) ||
743 	    !(*flags & WPS_CONN_ESS)) {
744 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Connection Type "
745 			   "Flags attribute value 0x%02x", *flags);
746 		return -1;
747 	}
748 	return 0;
749 }
750 
751 
752 static int wps_validate_os_version(const u8 *os_version, int mandatory)
753 {
754 	if (os_version == NULL) {
755 		if (mandatory) {
756 			wpa_printf(MSG_INFO, "WPS-STRICT: OS Version "
757 				   "attribute missing");
758 			return -1;
759 		}
760 		return 0;
761 	}
762 	return 0;
763 }
764 
765 
766 static int wps_validate_authenticator(const u8 *authenticator, int mandatory)
767 {
768 	if (authenticator == NULL) {
769 		if (mandatory) {
770 			wpa_printf(MSG_INFO, "WPS-STRICT: Authenticator "
771 				   "attribute missing");
772 			return -1;
773 		}
774 		return 0;
775 	}
776 	return 0;
777 }
778 
779 
780 static int wps_validate_e_hash1(const u8 *hash, int mandatory)
781 {
782 	if (hash == NULL) {
783 		if (mandatory) {
784 			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash1 "
785 				   "attribute missing");
786 			return -1;
787 		}
788 		return 0;
789 	}
790 	return 0;
791 }
792 
793 
794 static int wps_validate_e_hash2(const u8 *hash, int mandatory)
795 {
796 	if (hash == NULL) {
797 		if (mandatory) {
798 			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash2 "
799 				   "attribute missing");
800 			return -1;
801 		}
802 		return 0;
803 	}
804 	return 0;
805 }
806 
807 
808 static int wps_validate_r_hash1(const u8 *hash, int mandatory)
809 {
810 	if (hash == NULL) {
811 		if (mandatory) {
812 			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash1 "
813 				   "attribute missing");
814 			return -1;
815 		}
816 		return 0;
817 	}
818 	return 0;
819 }
820 
821 
822 static int wps_validate_r_hash2(const u8 *hash, int mandatory)
823 {
824 	if (hash == NULL) {
825 		if (mandatory) {
826 			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash2 "
827 				   "attribute missing");
828 			return -1;
829 		}
830 		return 0;
831 	}
832 	return 0;
833 }
834 
835 
836 static int wps_validate_encr_settings(const u8 *encr_settings, size_t len,
837 				   int mandatory)
838 {
839 	if (encr_settings == NULL) {
840 		if (mandatory) {
841 			wpa_printf(MSG_INFO, "WPS-STRICT: Encrypted Settings "
842 				   "attribute missing");
843 			return -1;
844 		}
845 		return 0;
846 	}
847 	if (len < 16) {
848 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encrypted Settings "
849 			   "attribute length %d", (int) len);
850 		return -1;
851 	}
852 	return 0;
853 }
854 
855 
856 static int wps_validate_settings_delay_time(const u8 *delay, int mandatory)
857 {
858 	if (delay == NULL) {
859 		if (mandatory) {
860 			wpa_printf(MSG_INFO, "WPS-STRICT: Settings Delay Time "
861 				   "attribute missing");
862 			return -1;
863 		}
864 		return 0;
865 	}
866 	return 0;
867 }
868 
869 
870 static int wps_validate_r_snonce1(const u8 *nonce, int mandatory)
871 {
872 	if (nonce == NULL) {
873 		if (mandatory) {
874 			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce1 "
875 				   "attribute missing");
876 			return -1;
877 		}
878 		return 0;
879 	}
880 	return 0;
881 }
882 
883 
884 static int wps_validate_r_snonce2(const u8 *nonce, int mandatory)
885 {
886 	if (nonce == NULL) {
887 		if (mandatory) {
888 			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce2 "
889 				   "attribute missing");
890 			return -1;
891 		}
892 		return 0;
893 	}
894 	return 0;
895 }
896 
897 
898 static int wps_validate_e_snonce1(const u8 *nonce, int mandatory)
899 {
900 	if (nonce == NULL) {
901 		if (mandatory) {
902 			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce1 "
903 				   "attribute missing");
904 			return -1;
905 		}
906 		return 0;
907 	}
908 	return 0;
909 }
910 
911 
912 static int wps_validate_e_snonce2(const u8 *nonce, int mandatory)
913 {
914 	if (nonce == NULL) {
915 		if (mandatory) {
916 			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce2 "
917 				   "attribute missing");
918 			return -1;
919 		}
920 		return 0;
921 	}
922 	return 0;
923 }
924 
925 
926 static int wps_validate_key_wrap_auth(const u8 *auth, int mandatory)
927 {
928 	if (auth == NULL) {
929 		if (mandatory) {
930 			wpa_printf(MSG_INFO, "WPS-STRICT: Key Wrap "
931 				   "Authenticator attribute missing");
932 			return -1;
933 		}
934 		return 0;
935 	}
936 	return 0;
937 }
938 
939 
940 static int wps_validate_ssid(const u8 *ssid, size_t ssid_len, int mandatory)
941 {
942 	if (ssid == NULL) {
943 		if (mandatory) {
944 			wpa_printf(MSG_INFO, "WPS-STRICT: SSID "
945 				   "attribute missing");
946 			return -1;
947 		}
948 		return 0;
949 	}
950 	if (ssid_len == 0 || ssid[ssid_len - 1] == 0) {
951 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid SSID "
952 				  "attribute value", ssid, ssid_len);
953 		return -1;
954 	}
955 	return 0;
956 }
957 
958 
959 static int wps_validate_network_key_index(const u8 *idx, int mandatory)
960 {
961 	if (idx == NULL) {
962 		if (mandatory) {
963 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key Index "
964 				   "attribute missing");
965 			return -1;
966 		}
967 		return 0;
968 	}
969 	return 0;
970 }
971 
972 
973 static int wps_validate_network_idx(const u8 *idx, int mandatory)
974 {
975 	if (idx == NULL) {
976 		if (mandatory) {
977 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Index "
978 				   "attribute missing");
979 			return -1;
980 		}
981 		return 0;
982 	}
983 	return 0;
984 }
985 
986 
987 static int wps_validate_network_key(const u8 *key, size_t key_len,
988 				    const u8 *encr_type, int mandatory)
989 {
990 	if (key == NULL) {
991 		if (mandatory) {
992 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
993 				   "attribute missing");
994 			return -1;
995 		}
996 		return 0;
997 	}
998 	if (((encr_type == NULL || WPA_GET_BE16(encr_type) != WPS_ENCR_WEP) &&
999 	     key_len > 8 && key_len < 64 && key[key_len - 1] == 0) ||
1000 	    key_len > 64) {
1001 		wpa_hexdump_ascii_key(MSG_INFO, "WPS-STRICT: Invalid Network "
1002 				      "Key attribute value", key, key_len);
1003 		return -1;
1004 	}
1005 	return 0;
1006 }
1007 
1008 
1009 static int wps_validate_network_key_shareable(const u8 *val, int mandatory)
1010 {
1011 	if (val == NULL) {
1012 		if (mandatory) {
1013 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
1014 				   "Shareable attribute missing");
1015 			return -1;
1016 		}
1017 		return 0;
1018 	}
1019 	if (*val > 1) {
1020 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Network Key "
1021 			   "Shareable attribute value 0x%x", *val);
1022 		return -1;
1023 	}
1024 	return 0;
1025 }
1026 
1027 
1028 static int wps_validate_cred(const u8 *cred, size_t len)
1029 {
1030 	struct wps_parse_attr attr;
1031 	struct wpabuf buf;
1032 
1033 	if (cred == NULL)
1034 		return -1;
1035 	wpabuf_set(&buf, cred, len);
1036 	if (wps_parse_msg(&buf, &attr) < 0) {
1037 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse Credential");
1038 		return -1;
1039 	}
1040 
1041 	if (wps_validate_network_idx(attr.network_idx, 1) ||
1042 	    wps_validate_ssid(attr.ssid, attr.ssid_len, 1) ||
1043 	    wps_validate_auth_type(attr.auth_type, 1) ||
1044 	    wps_validate_encr_type(attr.encr_type, 1) ||
1045 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1046 	    wps_validate_network_key(attr.network_key, attr.network_key_len,
1047 				     attr.encr_type, 1) ||
1048 	    wps_validate_mac_addr(attr.mac_addr, 1) ||
1049 	    wps_validate_network_key_shareable(attr.network_key_shareable, 0))
1050 	{
1051 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Credential");
1052 		return -1;
1053 	}
1054 
1055 
1056 	return 0;
1057 }
1058 
1059 
1060 static int wps_validate_credential(const u8 *cred[], u16 len[], size_t num,
1061 				   int mandatory)
1062 {
1063 	size_t i;
1064 
1065 	if (num == 0) {
1066 		if (mandatory) {
1067 			wpa_printf(MSG_INFO, "WPS-STRICT: Credential "
1068 				   "attribute missing");
1069 			return -1;
1070 		}
1071 		return 0;
1072 	}
1073 
1074 	for (i = 0; i < num; i++) {
1075 		if (wps_validate_cred(cred[i], len[i]) < 0)
1076 			return -1;
1077 	}
1078 
1079 	return 0;
1080 }
1081 
1082 
1083 int wps_validate_beacon(const struct wpabuf *wps_ie)
1084 {
1085 	struct wps_parse_attr attr;
1086 	int wps2, sel_reg;
1087 
1088 	if (wps_ie == NULL) {
1089 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in Beacon frame");
1090 		return -1;
1091 	}
1092 	if (wps_parse_msg(wps_ie, &attr) < 0) {
1093 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1094 			   "Beacon frame");
1095 		return -1;
1096 	}
1097 
1098 	wps2 = attr.version2 != NULL;
1099 	sel_reg = attr.selected_registrar != NULL &&
1100 		*attr.selected_registrar != 0;
1101 	if (wps_validate_version(attr.version, 1) ||
1102 	    wps_validate_wps_state(attr.wps_state, 1) ||
1103 	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
1104 	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
1105 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1106 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1107 						wps2, sel_reg) ||
1108 	    wps_validate_uuid_e(attr.uuid_e, 0) ||
1109 	    wps_validate_rf_bands(attr.rf_bands, 0) ||
1110 	    wps_validate_version2(attr.version2, wps2) ||
1111 	    wps_validate_authorized_macs(attr.authorized_macs,
1112 					 attr.authorized_macs_len, 0)) {
1113 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Beacon frame");
1114 		return -1;
1115 	}
1116 
1117 	return 0;
1118 }
1119 
1120 
1121 int wps_validate_beacon_probe_resp(const struct wpabuf *wps_ie, int probe,
1122 				   const u8 *addr)
1123 {
1124 	struct wps_parse_attr attr;
1125 	int wps2, sel_reg;
1126 
1127 	if (wps_ie == NULL) {
1128 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1129 			   "%sProbe Response frame", probe ? "" : "Beacon/");
1130 		return -1;
1131 	}
1132 	if (wps_parse_msg(wps_ie, &attr) < 0) {
1133 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1134 			   "%sProbe Response frame", probe ? "" : "Beacon/");
1135 		return -1;
1136 	}
1137 
1138 	wps2 = attr.version2 != NULL;
1139 	sel_reg = attr.selected_registrar != NULL &&
1140 		*attr.selected_registrar != 0;
1141 	if (wps_validate_version(attr.version, 1) ||
1142 	    wps_validate_wps_state(attr.wps_state, 1) ||
1143 	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
1144 	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
1145 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1146 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1147 						wps2, sel_reg) ||
1148 	    wps_validate_response_type(attr.response_type, probe) ||
1149 	    wps_validate_uuid_e(attr.uuid_e, probe) ||
1150 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1151 				      probe) ||
1152 	    wps_validate_model_name(attr.model_name, attr.model_name_len,
1153 				    probe) ||
1154 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1155 				      probe) ||
1156 	    wps_validate_serial_number(attr.serial_number,
1157 				       attr.serial_number_len, probe) ||
1158 	    wps_validate_primary_dev_type(attr.primary_dev_type, probe) ||
1159 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, probe) ||
1160 	    wps_validate_ap_config_methods(attr.config_methods, wps2, probe) ||
1161 	    wps_validate_rf_bands(attr.rf_bands, 0) ||
1162 	    wps_validate_version2(attr.version2, wps2) ||
1163 	    wps_validate_authorized_macs(attr.authorized_macs,
1164 					 attr.authorized_macs_len, 0)) {
1165 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid %sProbe Response "
1166 			   "frame from " MACSTR, probe ? "" : "Beacon/",
1167 			   MAC2STR(addr));
1168 #ifdef WPS_STRICT_WPS2
1169 		if (wps2)
1170 			return -1;
1171 #else /* WPS_STRICT_WPS2 */
1172 		return -1;
1173 #endif /* WPS_STRICT_WPS2 */
1174 	}
1175 
1176 	return 0;
1177 }
1178 
1179 
1180 int wps_validate_probe_req(const struct wpabuf *wps_ie, const u8 *addr)
1181 {
1182 	struct wps_parse_attr attr;
1183 	int wps2;
1184 
1185 	if (wps_ie == NULL) {
1186 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1187 			   "Probe Request frame");
1188 		return -1;
1189 	}
1190 	if (wps_parse_msg(wps_ie, &attr) < 0) {
1191 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1192 			   "Probe Request frame");
1193 		return -1;
1194 	}
1195 
1196 	wps2 = attr.version2 != NULL;
1197 	if (wps_validate_version(attr.version, 1) ||
1198 	    wps_validate_request_type(attr.request_type, 1) ||
1199 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1200 	    wps_validate_uuid_e(attr.uuid_e, attr.uuid_r == NULL) ||
1201 	    wps_validate_uuid_r(attr.uuid_r, attr.uuid_e == NULL) ||
1202 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1203 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1204 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1205 	    wps_validate_config_error(attr.config_error, 1) ||
1206 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
1207 	    wps_validate_version2(attr.version2, wps2) ||
1208 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1209 				      wps2) ||
1210 	    wps_validate_model_name(attr.model_name, attr.model_name_len,
1211 				    wps2) ||
1212 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1213 				      wps2) ||
1214 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, wps2) ||
1215 	    wps_validate_request_to_enroll(attr.request_to_enroll, 0) ||
1216 	    wps_validate_req_dev_type(attr.req_dev_type, attr.num_req_dev_type,
1217 				      0)) {
1218 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Probe Request "
1219 			   "frame from " MACSTR, MAC2STR(addr));
1220 		return -1;
1221 	}
1222 
1223 	return 0;
1224 }
1225 
1226 
1227 int wps_validate_assoc_req(const struct wpabuf *wps_ie)
1228 {
1229 	struct wps_parse_attr attr;
1230 	int wps2;
1231 
1232 	if (wps_ie == NULL) {
1233 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1234 			   "(Re)Association Request frame");
1235 		return -1;
1236 	}
1237 	if (wps_parse_msg(wps_ie, &attr) < 0) {
1238 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1239 			   "(Re)Association Request frame");
1240 		return -1;
1241 	}
1242 
1243 	wps2 = attr.version2 != NULL;
1244 	if (wps_validate_version(attr.version, 1) ||
1245 	    wps_validate_request_type(attr.request_type, 1) ||
1246 	    wps_validate_version2(attr.version2, wps2)) {
1247 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
1248 			   "Request frame");
1249 		return -1;
1250 	}
1251 
1252 	return 0;
1253 }
1254 
1255 
1256 int wps_validate_assoc_resp(const struct wpabuf *wps_ie)
1257 {
1258 	struct wps_parse_attr attr;
1259 	int wps2;
1260 
1261 	if (wps_ie == NULL) {
1262 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1263 			   "(Re)Association Response frame");
1264 		return -1;
1265 	}
1266 	if (wps_parse_msg(wps_ie, &attr) < 0) {
1267 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1268 			   "(Re)Association Response frame");
1269 		return -1;
1270 	}
1271 
1272 	wps2 = attr.version2 != NULL;
1273 	if (wps_validate_version(attr.version, 1) ||
1274 	    wps_validate_response_type(attr.response_type, 1) ||
1275 	    wps_validate_version2(attr.version2, wps2)) {
1276 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
1277 			   "Response frame");
1278 		return -1;
1279 	}
1280 
1281 	return 0;
1282 }
1283 
1284 
1285 int wps_validate_m1(const struct wpabuf *tlvs)
1286 {
1287 	struct wps_parse_attr attr;
1288 	int wps2;
1289 
1290 	if (tlvs == NULL) {
1291 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M1");
1292 		return -1;
1293 	}
1294 	if (wps_parse_msg(tlvs, &attr) < 0) {
1295 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1296 			   "in M1");
1297 		return -1;
1298 	}
1299 
1300 	wps2 = attr.version2 != NULL;
1301 	if (wps_validate_version(attr.version, 1) ||
1302 	    wps_validate_msg_type(attr.msg_type, 1) ||
1303 	    wps_validate_uuid_e(attr.uuid_e, 1) ||
1304 	    wps_validate_mac_addr(attr.mac_addr, 1) ||
1305 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1306 	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
1307 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
1308 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
1309 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
1310 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1311 	    wps_validate_wps_state(attr.wps_state, 1) ||
1312 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1313 				      1) ||
1314 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
1315 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1316 				      1) ||
1317 	    wps_validate_serial_number(attr.serial_number,
1318 				       attr.serial_number_len, 1) ||
1319 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1320 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
1321 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1322 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1323 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
1324 	    wps_validate_config_error(attr.config_error, 1) ||
1325 	    wps_validate_os_version(attr.os_version, 1) ||
1326 	    wps_validate_version2(attr.version2, wps2) ||
1327 	    wps_validate_request_to_enroll(attr.request_to_enroll, 0)) {
1328 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M1");
1329 #ifdef WPS_STRICT_WPS2
1330 		if (wps2)
1331 			return -1;
1332 #else /* WPS_STRICT_WPS2 */
1333 		return -1;
1334 #endif /* WPS_STRICT_WPS2 */
1335 	}
1336 
1337 	return 0;
1338 }
1339 
1340 
1341 int wps_validate_m2(const struct wpabuf *tlvs)
1342 {
1343 	struct wps_parse_attr attr;
1344 	int wps2;
1345 
1346 	if (tlvs == NULL) {
1347 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2");
1348 		return -1;
1349 	}
1350 	if (wps_parse_msg(tlvs, &attr) < 0) {
1351 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1352 			   "in M2");
1353 		return -1;
1354 	}
1355 
1356 	wps2 = attr.version2 != NULL;
1357 	if (wps_validate_version(attr.version, 1) ||
1358 	    wps_validate_msg_type(attr.msg_type, 1) ||
1359 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1360 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1361 	    wps_validate_uuid_r(attr.uuid_r, 1) ||
1362 	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
1363 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
1364 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
1365 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
1366 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1367 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1368 				      1) ||
1369 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
1370 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1371 				      1) ||
1372 	    wps_validate_serial_number(attr.serial_number,
1373 				       attr.serial_number_len, 1) ||
1374 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1375 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
1376 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1377 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1378 	    wps_validate_config_error(attr.config_error, 1) ||
1379 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
1380 	    wps_validate_os_version(attr.os_version, 1) ||
1381 	    wps_validate_version2(attr.version2, wps2) ||
1382 	    wps_validate_authenticator(attr.authenticator, 1)) {
1383 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2");
1384 #ifdef WPS_STRICT_WPS2
1385 		if (wps2)
1386 			return -1;
1387 #else /* WPS_STRICT_WPS2 */
1388 		return -1;
1389 #endif /* WPS_STRICT_WPS2 */
1390 	}
1391 
1392 	return 0;
1393 }
1394 
1395 
1396 int wps_validate_m2d(const struct wpabuf *tlvs)
1397 {
1398 	struct wps_parse_attr attr;
1399 	int wps2;
1400 
1401 	if (tlvs == NULL) {
1402 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2D");
1403 		return -1;
1404 	}
1405 	if (wps_parse_msg(tlvs, &attr) < 0) {
1406 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1407 			   "in M2D");
1408 		return -1;
1409 	}
1410 
1411 	wps2 = attr.version2 != NULL;
1412 	if (wps_validate_version(attr.version, 1) ||
1413 	    wps_validate_msg_type(attr.msg_type, 1) ||
1414 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1415 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1416 	    wps_validate_uuid_r(attr.uuid_r, 1) ||
1417 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
1418 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
1419 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
1420 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1421 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1422 				      1) ||
1423 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
1424 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1425 				      1) ||
1426 	    wps_validate_serial_number(attr.serial_number,
1427 				       attr.serial_number_len, 1) ||
1428 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1429 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
1430 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1431 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1432 	    wps_validate_config_error(attr.config_error, 1) ||
1433 	    wps_validate_os_version(attr.os_version, 1) ||
1434 	    wps_validate_version2(attr.version2, wps2)) {
1435 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2D");
1436 #ifdef WPS_STRICT_WPS2
1437 		if (wps2)
1438 			return -1;
1439 #else /* WPS_STRICT_WPS2 */
1440 		return -1;
1441 #endif /* WPS_STRICT_WPS2 */
1442 	}
1443 
1444 	return 0;
1445 }
1446 
1447 
1448 int wps_validate_m3(const struct wpabuf *tlvs)
1449 {
1450 	struct wps_parse_attr attr;
1451 	int wps2;
1452 
1453 	if (tlvs == NULL) {
1454 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M3");
1455 		return -1;
1456 	}
1457 	if (wps_parse_msg(tlvs, &attr) < 0) {
1458 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1459 			   "in M3");
1460 		return -1;
1461 	}
1462 
1463 	wps2 = attr.version2 != NULL;
1464 	if (wps_validate_version(attr.version, 1) ||
1465 	    wps_validate_msg_type(attr.msg_type, 1) ||
1466 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1467 	    wps_validate_e_hash1(attr.e_hash1, 1) ||
1468 	    wps_validate_e_hash2(attr.e_hash2, 1) ||
1469 	    wps_validate_version2(attr.version2, wps2) ||
1470 	    wps_validate_authenticator(attr.authenticator, 1)) {
1471 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M3");
1472 #ifdef WPS_STRICT_WPS2
1473 		if (wps2)
1474 			return -1;
1475 #else /* WPS_STRICT_WPS2 */
1476 		return -1;
1477 #endif /* WPS_STRICT_WPS2 */
1478 	}
1479 
1480 	return 0;
1481 }
1482 
1483 
1484 int wps_validate_m4(const struct wpabuf *tlvs)
1485 {
1486 	struct wps_parse_attr attr;
1487 	int wps2;
1488 
1489 	if (tlvs == NULL) {
1490 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4");
1491 		return -1;
1492 	}
1493 	if (wps_parse_msg(tlvs, &attr) < 0) {
1494 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1495 			   "in M4");
1496 		return -1;
1497 	}
1498 
1499 	wps2 = attr.version2 != NULL;
1500 	if (wps_validate_version(attr.version, 1) ||
1501 	    wps_validate_msg_type(attr.msg_type, 1) ||
1502 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1503 	    wps_validate_r_hash1(attr.r_hash1, 1) ||
1504 	    wps_validate_r_hash2(attr.r_hash2, 1) ||
1505 	    wps_validate_encr_settings(attr.encr_settings,
1506 				       attr.encr_settings_len, 1) ||
1507 	    wps_validate_version2(attr.version2, wps2) ||
1508 	    wps_validate_authenticator(attr.authenticator, 1)) {
1509 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4");
1510 #ifdef WPS_STRICT_WPS2
1511 		if (wps2)
1512 			return -1;
1513 #else /* WPS_STRICT_WPS2 */
1514 		return -1;
1515 #endif /* WPS_STRICT_WPS2 */
1516 	}
1517 
1518 	return 0;
1519 }
1520 
1521 
1522 int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2)
1523 {
1524 	struct wps_parse_attr attr;
1525 
1526 	if (tlvs == NULL) {
1527 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted "
1528 			   "settings");
1529 		return -1;
1530 	}
1531 	if (wps_parse_msg(tlvs, &attr) < 0) {
1532 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1533 			   "in M4 encrypted settings");
1534 		return -1;
1535 	}
1536 
1537 	if (wps_validate_r_snonce1(attr.r_snonce1, 1) ||
1538 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1539 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted "
1540 			   "settings");
1541 #ifdef WPS_STRICT_WPS2
1542 		if (wps2)
1543 			return -1;
1544 #else /* WPS_STRICT_WPS2 */
1545 		return -1;
1546 #endif /* WPS_STRICT_WPS2 */
1547 	}
1548 
1549 	return 0;
1550 }
1551 
1552 
1553 int wps_validate_m5(const struct wpabuf *tlvs)
1554 {
1555 	struct wps_parse_attr attr;
1556 	int wps2;
1557 
1558 	if (tlvs == NULL) {
1559 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5");
1560 		return -1;
1561 	}
1562 	if (wps_parse_msg(tlvs, &attr) < 0) {
1563 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1564 			   "in M5");
1565 		return -1;
1566 	}
1567 
1568 	wps2 = attr.version2 != NULL;
1569 	if (wps_validate_version(attr.version, 1) ||
1570 	    wps_validate_msg_type(attr.msg_type, 1) ||
1571 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1572 	    wps_validate_encr_settings(attr.encr_settings,
1573 				       attr.encr_settings_len, 1) ||
1574 	    wps_validate_version2(attr.version2, wps2) ||
1575 	    wps_validate_authenticator(attr.authenticator, 1)) {
1576 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5");
1577 #ifdef WPS_STRICT_WPS2
1578 		if (wps2)
1579 			return -1;
1580 #else /* WPS_STRICT_WPS2 */
1581 		return -1;
1582 #endif /* WPS_STRICT_WPS2 */
1583 	}
1584 
1585 	return 0;
1586 }
1587 
1588 
1589 int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2)
1590 {
1591 	struct wps_parse_attr attr;
1592 
1593 	if (tlvs == NULL) {
1594 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted "
1595 			   "settings");
1596 		return -1;
1597 	}
1598 	if (wps_parse_msg(tlvs, &attr) < 0) {
1599 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1600 			   "in M5 encrypted settings");
1601 		return -1;
1602 	}
1603 
1604 	if (wps_validate_e_snonce1(attr.e_snonce1, 1) ||
1605 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1606 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted "
1607 			   "settings");
1608 #ifdef WPS_STRICT_WPS2
1609 		if (wps2)
1610 			return -1;
1611 #else /* WPS_STRICT_WPS2 */
1612 		return -1;
1613 #endif /* WPS_STRICT_WPS2 */
1614 	}
1615 
1616 	return 0;
1617 }
1618 
1619 
1620 int wps_validate_m6(const struct wpabuf *tlvs)
1621 {
1622 	struct wps_parse_attr attr;
1623 	int wps2;
1624 
1625 	if (tlvs == NULL) {
1626 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6");
1627 		return -1;
1628 	}
1629 	if (wps_parse_msg(tlvs, &attr) < 0) {
1630 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1631 			   "in M6");
1632 		return -1;
1633 	}
1634 
1635 	wps2 = attr.version2 != NULL;
1636 	if (wps_validate_version(attr.version, 1) ||
1637 	    wps_validate_msg_type(attr.msg_type, 1) ||
1638 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1639 	    wps_validate_encr_settings(attr.encr_settings,
1640 				       attr.encr_settings_len, 1) ||
1641 	    wps_validate_version2(attr.version2, wps2) ||
1642 	    wps_validate_authenticator(attr.authenticator, 1)) {
1643 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6");
1644 #ifdef WPS_STRICT_WPS2
1645 		if (wps2)
1646 			return -1;
1647 #else /* WPS_STRICT_WPS2 */
1648 		return -1;
1649 #endif /* WPS_STRICT_WPS2 */
1650 	}
1651 
1652 	return 0;
1653 }
1654 
1655 
1656 int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2)
1657 {
1658 	struct wps_parse_attr attr;
1659 
1660 	if (tlvs == NULL) {
1661 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted "
1662 			   "settings");
1663 		return -1;
1664 	}
1665 	if (wps_parse_msg(tlvs, &attr) < 0) {
1666 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1667 			   "in M6 encrypted settings");
1668 		return -1;
1669 	}
1670 
1671 	if (wps_validate_r_snonce2(attr.r_snonce2, 1) ||
1672 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1673 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted "
1674 			   "settings");
1675 #ifdef WPS_STRICT_WPS2
1676 		if (wps2)
1677 			return -1;
1678 #else /* WPS_STRICT_WPS2 */
1679 		return -1;
1680 #endif /* WPS_STRICT_WPS2 */
1681 	}
1682 
1683 	return 0;
1684 }
1685 
1686 
1687 int wps_validate_m7(const struct wpabuf *tlvs)
1688 {
1689 	struct wps_parse_attr attr;
1690 	int wps2;
1691 
1692 	if (tlvs == NULL) {
1693 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7");
1694 		return -1;
1695 	}
1696 	if (wps_parse_msg(tlvs, &attr) < 0) {
1697 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1698 			   "in M7");
1699 		return -1;
1700 	}
1701 
1702 	wps2 = attr.version2 != NULL;
1703 	if (wps_validate_version(attr.version, 1) ||
1704 	    wps_validate_msg_type(attr.msg_type, 1) ||
1705 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1706 	    wps_validate_encr_settings(attr.encr_settings,
1707 				       attr.encr_settings_len, 1) ||
1708 	    wps_validate_settings_delay_time(attr.settings_delay_time, 0) ||
1709 	    wps_validate_version2(attr.version2, wps2) ||
1710 	    wps_validate_authenticator(attr.authenticator, 1)) {
1711 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7");
1712 #ifdef WPS_STRICT_WPS2
1713 		if (wps2)
1714 			return -1;
1715 #else /* WPS_STRICT_WPS2 */
1716 		return -1;
1717 #endif /* WPS_STRICT_WPS2 */
1718 	}
1719 
1720 	return 0;
1721 }
1722 
1723 
1724 int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2)
1725 {
1726 	struct wps_parse_attr attr;
1727 
1728 	if (tlvs == NULL) {
1729 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted "
1730 			   "settings");
1731 		return -1;
1732 	}
1733 	if (wps_parse_msg(tlvs, &attr) < 0) {
1734 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1735 			   "in M7 encrypted settings");
1736 		return -1;
1737 	}
1738 
1739 	if (wps_validate_e_snonce2(attr.e_snonce2, 1) ||
1740 	    wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) ||
1741 	    wps_validate_mac_addr(attr.mac_addr, !ap) ||
1742 	    wps_validate_auth_type(attr.auth_type, !ap) ||
1743 	    wps_validate_encr_type(attr.encr_type, !ap) ||
1744 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1745 	    wps_validate_network_key(attr.network_key, attr.network_key_len,
1746 				     attr.encr_type, !ap) ||
1747 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1748 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7 encrypted "
1749 			   "settings");
1750 #ifdef WPS_STRICT_WPS2
1751 		if (wps2)
1752 			return -1;
1753 #else /* WPS_STRICT_WPS2 */
1754 		return -1;
1755 #endif /* WPS_STRICT_WPS2 */
1756 	}
1757 
1758 	return 0;
1759 }
1760 
1761 
1762 int wps_validate_m8(const struct wpabuf *tlvs)
1763 {
1764 	struct wps_parse_attr attr;
1765 	int wps2;
1766 
1767 	if (tlvs == NULL) {
1768 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8");
1769 		return -1;
1770 	}
1771 	if (wps_parse_msg(tlvs, &attr) < 0) {
1772 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1773 			   "in M8");
1774 		return -1;
1775 	}
1776 
1777 	wps2 = attr.version2 != NULL;
1778 	if (wps_validate_version(attr.version, 1) ||
1779 	    wps_validate_msg_type(attr.msg_type, 1) ||
1780 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1781 	    wps_validate_encr_settings(attr.encr_settings,
1782 				       attr.encr_settings_len, 1) ||
1783 	    wps_validate_version2(attr.version2, wps2) ||
1784 	    wps_validate_authenticator(attr.authenticator, 1)) {
1785 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8");
1786 #ifdef WPS_STRICT_WPS2
1787 		if (wps2)
1788 			return -1;
1789 #else /* WPS_STRICT_WPS2 */
1790 		return -1;
1791 #endif /* WPS_STRICT_WPS2 */
1792 	}
1793 
1794 	return 0;
1795 }
1796 
1797 
1798 int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2)
1799 {
1800 	struct wps_parse_attr attr;
1801 
1802 	if (tlvs == NULL) {
1803 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted "
1804 			   "settings");
1805 		return -1;
1806 	}
1807 	if (wps_parse_msg(tlvs, &attr) < 0) {
1808 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1809 			   "in M8 encrypted settings");
1810 		return -1;
1811 	}
1812 
1813 	if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) ||
1814 	    wps_validate_auth_type(attr.auth_type, ap) ||
1815 	    wps_validate_encr_type(attr.encr_type, ap) ||
1816 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1817 	    wps_validate_mac_addr(attr.mac_addr, ap) ||
1818 	    wps_validate_credential(attr.cred, attr.cred_len, attr.num_cred,
1819 				    !ap) ||
1820 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1821 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8 encrypted "
1822 			   "settings");
1823 #ifdef WPS_STRICT_WPS2
1824 		if (wps2)
1825 			return -1;
1826 #else /* WPS_STRICT_WPS2 */
1827 		return -1;
1828 #endif /* WPS_STRICT_WPS2 */
1829 	}
1830 
1831 	return 0;
1832 }
1833 
1834 
1835 int wps_validate_wsc_ack(const struct wpabuf *tlvs)
1836 {
1837 	struct wps_parse_attr attr;
1838 	int wps2;
1839 
1840 	if (tlvs == NULL) {
1841 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_ACK");
1842 		return -1;
1843 	}
1844 	if (wps_parse_msg(tlvs, &attr) < 0) {
1845 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1846 			   "in WSC_ACK");
1847 		return -1;
1848 	}
1849 
1850 	wps2 = attr.version2 != NULL;
1851 	if (wps_validate_version(attr.version, 1) ||
1852 	    wps_validate_msg_type(attr.msg_type, 1) ||
1853 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1854 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1855 	    wps_validate_version2(attr.version2, wps2)) {
1856 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_ACK");
1857 #ifdef WPS_STRICT_WPS2
1858 		if (wps2)
1859 			return -1;
1860 #else /* WPS_STRICT_WPS2 */
1861 		return -1;
1862 #endif /* WPS_STRICT_WPS2 */
1863 	}
1864 
1865 	return 0;
1866 }
1867 
1868 
1869 int wps_validate_wsc_nack(const struct wpabuf *tlvs)
1870 {
1871 	struct wps_parse_attr attr;
1872 	int wps2;
1873 
1874 	if (tlvs == NULL) {
1875 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_NACK");
1876 		return -1;
1877 	}
1878 	if (wps_parse_msg(tlvs, &attr) < 0) {
1879 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1880 			   "in WSC_NACK");
1881 		return -1;
1882 	}
1883 
1884 	wps2 = attr.version2 != NULL;
1885 	if (wps_validate_version(attr.version, 1) ||
1886 	    wps_validate_msg_type(attr.msg_type, 1) ||
1887 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1888 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1889 	    wps_validate_config_error(attr.config_error, 1) ||
1890 	    wps_validate_version2(attr.version2, wps2)) {
1891 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_NACK");
1892 #ifdef WPS_STRICT_WPS2
1893 		if (wps2)
1894 			return -1;
1895 #else /* WPS_STRICT_WPS2 */
1896 		return -1;
1897 #endif /* WPS_STRICT_WPS2 */
1898 	}
1899 
1900 	return 0;
1901 }
1902 
1903 
1904 int wps_validate_wsc_done(const struct wpabuf *tlvs)
1905 {
1906 	struct wps_parse_attr attr;
1907 	int wps2;
1908 
1909 	if (tlvs == NULL) {
1910 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_Done");
1911 		return -1;
1912 	}
1913 	if (wps_parse_msg(tlvs, &attr) < 0) {
1914 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1915 			   "in WSC_Done");
1916 		return -1;
1917 	}
1918 
1919 	wps2 = attr.version2 != NULL;
1920 	if (wps_validate_version(attr.version, 1) ||
1921 	    wps_validate_msg_type(attr.msg_type, 1) ||
1922 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1923 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1924 	    wps_validate_version2(attr.version2, wps2)) {
1925 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_Done");
1926 #ifdef WPS_STRICT_WPS2
1927 		if (wps2)
1928 			return -1;
1929 #else /* WPS_STRICT_WPS2 */
1930 		return -1;
1931 #endif /* WPS_STRICT_WPS2 */
1932 	}
1933 
1934 	return 0;
1935 }
1936 
1937 
1938 int wps_validate_upnp_set_selected_registrar(const struct wpabuf *tlvs)
1939 {
1940 	struct wps_parse_attr attr;
1941 	int wps2;
1942 	int sel_reg;
1943 
1944 	if (tlvs == NULL) {
1945 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in "
1946 			   "SetSelectedRegistrar");
1947 		return -1;
1948 	}
1949 	if (wps_parse_msg(tlvs, &attr) < 0) {
1950 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1951 			   "in SetSelectedRegistrar");
1952 		return -1;
1953 	}
1954 
1955 	wps2 = attr.version2 != NULL;
1956 	sel_reg = attr.selected_registrar != NULL &&
1957 		*attr.selected_registrar != 0;
1958 	if (wps_validate_version(attr.version, 1) ||
1959 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1960 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1961 						wps2, sel_reg) ||
1962 	    wps_validate_version2(attr.version2, wps2) ||
1963 	    wps_validate_authorized_macs(attr.authorized_macs,
1964 					 attr.authorized_macs_len, wps2) ||
1965 	    wps_validate_uuid_r(attr.uuid_r, wps2)) {
1966 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid "
1967 			   "SetSelectedRegistrar");
1968 #ifdef WPS_STRICT_WPS2
1969 		if (wps2)
1970 			return -1;
1971 #else /* WPS_STRICT_WPS2 */
1972 		return -1;
1973 #endif /* WPS_STRICT_WPS2 */
1974 	}
1975 
1976 	return 0;
1977 }
1978