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