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