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