1736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov/*
2736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * Wi-Fi Protected Setup - Strict protocol validation routines
3736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * Copyright (c) 2010, Atheros Communications, Inc.
4736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov *
5736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * This software may be distributed under the terms of the BSD license.
6736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov * See README for more details.
7736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov */
8736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
9736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "utils/includes.h"
10736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
11736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "utils/common.h"
12736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "wps_i.h"
13736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#include "wps.h"
14736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
15736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
16736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifndef WPS_STRICT_ALL
17736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#define WPS_STRICT_WPS2
18736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_ALL */
19736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_version(const u8 *version, int mandatory)
224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (version == NULL) {
24ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt		if (mandatory) {
254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Version attribute "
264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "missing");
27e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
28736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
29e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
30736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
31736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (*version != 0x10) {
32e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version attribute "
33e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "value 0x%x", *version);
344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
35f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	}
36f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	return 0;
3786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov}
3877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
39736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_version2(const u8 *version2, int mandatory)
41f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov{
424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (version2 == NULL) {
43736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
44736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Version2 attribute "
45736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "missing");
46736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
47736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
48736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
49736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
50736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (*version2 < 0x20) {
51e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version2 attribute "
52e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "value 0x%x", *version2);
53e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
54e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
55e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
56736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
57e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
58e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
59e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_request_type(const u8 *request_type, int mandatory)
60e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
61e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (request_type == NULL) {
62e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
63736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Request Type "
64736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
65736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
66736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
671cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		return 0;
684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
69736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (*request_type > 0x03) {
70736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request Type "
71736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "attribute value 0x%x", *request_type);
724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
73736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
74736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
75736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
76736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
77736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_response_type(const u8 *response_type, int mandatory)
79736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
80736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (response_type == NULL) {
81736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
8212a024ca681d877fe16b7e087356f7aff175a218Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Response Type "
83736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
84f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			return -1;
85f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		}
86736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (*response_type > 0x03) {
894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Response Type "
90e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%x", *response_type);
914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
93e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
94e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
95e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
96e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
97e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int valid_config_methods(u16 val, int wps2)
98e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
99e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps2) {
100e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
1014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
10295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov				   "Display flag without old Display flag "
10395068e5d1bea47091e97955f271c789264994550Svetoslav Ganov				   "set");
10495068e5d1bea47091e97955f271c789264994550Svetoslav Ganov			return 0;
105736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
106736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
107736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
108e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov				   "without Physical/Virtual Display flag");
109e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov			return 0;
110e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov		}
111e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
112e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
113e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "PushButton flag without old PushButton "
114e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "flag set");
115e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return 0;
116e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
117e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
118e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
119e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "without Physical/Virtual PushButton flag");
120e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return 0;
121e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
122736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
123736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
124736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 1;
125736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
126736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
127736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
128736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_config_methods(const u8 *config_methods, int wps2,
129736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				       int mandatory)
130736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
131736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	u16 val;
132e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
133e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (config_methods == NULL) {
134e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
135e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration "
136e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "Methods attribute missing");
137736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
138f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
139f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return 0;
140f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
141f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
142f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	val = WPA_GET_BE16(config_methods);
143fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	if (!valid_config_methods(val, wps2)) {
144f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
145f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov			   "Methods attribute value 0x%04x", val);
146f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov		return -1;
14795068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	}
14895068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	return 0;
14995068e5d1bea47091e97955f271c789264994550Svetoslav Ganov}
150e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
151e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
152e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_ap_config_methods(const u8 *config_methods, int wps2,
153e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov					  int mandatory)
154e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
155e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	u16 val;
156e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
157e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_validate_config_methods(config_methods, wps2, mandatory) < 0)
158e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
159e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (config_methods == NULL)
1601cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		return 0;
1611cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	val = WPA_GET_BE16(config_methods);
1621cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	if (val & WPS_CONFIG_PUSHBUTTON) {
163e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
16445af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			   "Methods attribute value 0x%04x in AP info "
1654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "(PushButton not allowed for registering new ER)",
166e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   val);
1674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
169e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
1704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
1714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
172e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
173e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_uuid_e(const u8 *uuid_e, int mandatory)
1744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
175e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (uuid_e == NULL) {
176e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
1774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-E "
17877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov				   "attribute missing");
17977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov			return -1;
18077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		}
181e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
182e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
183e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
184e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
185e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
186e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
187e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_uuid_r(const u8 *uuid_r, int mandatory)
188e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
189e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (uuid_r == NULL) {
190e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
191e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-R "
192e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
193e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
194e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
195e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
196e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
197e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
198e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
199e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
200aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov
201e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_primary_dev_type(const u8 *primary_dev_type,
202e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov					 int mandatory)
203e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
204e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (primary_dev_type == NULL) {
205e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
206e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Primary Device Type "
2074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
208385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov			return -1;
209385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		}
210385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		return 0;
211f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
212f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	return 0;
21377276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
214736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
215736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
216736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_rf_bands(const u8 *rf_bands, int mandatory)
217736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
218736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (rf_bands == NULL) {
219736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
2201cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: RF Bands "
22177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov				   "attribute missing");
222e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
2234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
2244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
225e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
22677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
227e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
228e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
229e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%x", *rf_bands);
230736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
231f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	}
23295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	return 0;
2334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
234ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt
235ea6fbc0981564f7bbf4c6fbb63af0175415121ceCasey Burkhardt
2364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_assoc_state(const u8 *assoc_state, int mandatory)
237e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
238e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	u16 val;
239f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (assoc_state == NULL) {
240f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		if (mandatory) {
241f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Association State "
242f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				   "attribute missing");
243f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
244f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
245e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
246e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
247e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	val = WPA_GET_BE16(assoc_state);
248e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (val > 4) {
249e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Association State "
250e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%04x", val);
251e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
252e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
253e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
254e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
255e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
256e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
257e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_config_error(const u8 *config_error, int mandatory)
258e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
259736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	u16 val;
260736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
2611cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	if (config_error == NULL) {
2621cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		if (mandatory) {
2631cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration Error "
2641cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov				   "attribute missing");
2651cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov			return -1;
266e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
267e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
268e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
269f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	val = WPA_GET_BE16(config_error);
270e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (val > 20) {
271e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
272e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%04x", val);
273e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
274e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
275e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
276e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
277e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
278e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
279e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_dev_password_id(const u8 *dev_password_id,
280e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov					int mandatory)
281e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
282e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	u16 val;
283e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
284e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (dev_password_id == NULL) {
285e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
286e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Device Password ID "
287e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
288e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
28995068e5d1bea47091e97955f271c789264994550Svetoslav Ganov		}
290f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return 0;
291f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
292e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	val = WPA_GET_BE16(dev_password_id);
293e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (val >= 0x0008 && val <= 0x000f) {
294e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
295e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%04x", val);
296e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
297e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
298e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
299e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
300e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
301e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
302e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_manufacturer(const u8 *manufacturer, size_t len,
3031cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov				     int mandatory)
3041cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov{
3051cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	if (manufacturer == NULL) {
306f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		if (mandatory) {
3071cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Manufacturer "
3081cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov				   "attribute missing");
3091cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov			return -1;
3101cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		}
3111cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		return 0;
312736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
313736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (len > 0 && manufacturer[len - 1] == 0) {
3141cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Manufacturer "
31545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			   "attribute value", manufacturer, len);
316736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
3174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
318736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
3194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
320736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
321736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
32245af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganovstatic int wps_validate_model_name(const u8 *model_name, size_t len,
323736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   int mandatory)
324736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
325736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (model_name == NULL) {
32645af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov		if (mandatory) {
327736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Model Name "
328736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
329736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
330736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
331736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
332736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
333736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (len > 0 && model_name[len - 1] == 0) {
3344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Name "
33545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			   "attribute value", model_name, len);
3364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
3374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
338736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
339736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
340736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
341736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
34286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganovstatic int wps_validate_model_number(const u8 *model_number, size_t len,
34377276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov				     int mandatory)
34477276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov{
34577276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (model_number == NULL) {
34677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		if (mandatory) {
347f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Model Number "
3488b681cb8813454aac8a626bf3d7adaa8beca4d75Svetoslav Ganov				   "attribute missing");
349f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
3508b681cb8813454aac8a626bf3d7adaa8beca4d75Svetoslav Ganov		}
35177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		return 0;
35277276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	}
35377276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (len > 0 && model_number[len - 1] == 0) {
35477276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Number "
355f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			   "attribute value", model_number, len);
3568b681cb8813454aac8a626bf3d7adaa8beca4d75Svetoslav Ganov		return -1;
357f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
3588b681cb8813454aac8a626bf3d7adaa8beca4d75Svetoslav Ganov	return 0;
35977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
36077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
36186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
36286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganovstatic int wps_validate_serial_number(const u8 *serial_number, size_t len,
36386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				      int mandatory)
36486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov{
36586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	if (serial_number == NULL) {
3665d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov		if (mandatory) {
3675d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Serial Number "
3685d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov				   "attribute missing");
36986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov			return -1;
370385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		}
371385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		return 0;
372385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	}
373385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	if (len > 0 && serial_number[len - 1] == 0) {
374385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Serial "
37586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				  "Number attribute value",
37686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				  serial_number, len);
3771cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		return -1;
3781cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	}
3791cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	return 0;
38086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov}
38186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
382736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
383736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_dev_name(const u8 *dev_name, size_t len,
384736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				 int mandatory)
385736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
38645af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	if (dev_name == NULL) {
387736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
388736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Device Name "
38945af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov				   "attribute missing");
39045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			return -1;
3914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
3924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
3934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
39445af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	if (len > 0 && dev_name[len - 1] == 0) {
395736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Device Name "
396e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value", dev_name, len);
397e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
398736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
399f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	return 0;
400e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
401e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
402e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
403e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_request_to_enroll(const u8 *request_to_enroll,
40445af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov					  int mandatory)
405e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
406736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (request_to_enroll == NULL) {
407736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
408736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Request to Enroll "
409736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
410736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
411736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
412736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
413e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
414e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (*request_to_enroll > 0x01) {
415e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request to Enroll "
416e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%x", *request_to_enroll);
417e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
418e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
419736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
420736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
421f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
422f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
423f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganovstatic int wps_validate_req_dev_type(const u8 *req_dev_type[], size_t num,
424f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				     int mandatory)
425f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov{
426f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (num == 0) {
427f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		if (mandatory) {
428f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Requested Device "
429f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				   "Type attribute missing");
430f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
431f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
432f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return 0;
433f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
434f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	return 0;
435fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov}
436fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov
437ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov
438ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganovstatic int wps_validate_wps_state(const u8 *wps_state, int mandatory)
439e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
440e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_state == NULL) {
441e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
442e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Wi-Fi Protected "
443e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "Setup State attribute missing");
444e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
445e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
446e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
447e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
448f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	if (*wps_state != WPS_STATE_NOT_CONFIGURED &&
449736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    *wps_state != WPS_STATE_CONFIGURED) {
450f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Wi-Fi Protected "
451f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			   "Setup State attribute value 0x%x", *wps_state);
452f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return -1;
453f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
454f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	return 0;
455f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov}
456f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
457736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
458736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_ap_setup_locked(const u8 *ap_setup_locked,
459736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov					int mandatory)
460736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
461736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (ap_setup_locked == NULL) {
462736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
463736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: AP Setup Locked "
4644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
46591feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			return -1;
46691feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		}
467736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
468736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
469736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (*ap_setup_locked > 1) {
470736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid AP Setup Locked "
471736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "attribute value 0x%x", *ap_setup_locked);
472e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
473e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
474e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
475e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
476e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
477e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
478e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_selected_registrar(const u8 *selected_registrar,
47945af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov					   int mandatory)
48045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov{
48145af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	if (selected_registrar == NULL) {
4824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (mandatory) {
48345af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
4844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
48545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			return -1;
486736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
487e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
488e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
489e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (*selected_registrar > 1) {
490e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
491e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%x", *selected_registrar);
4924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
4934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
4944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
4954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
496e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
497e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
498e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_sel_reg_config_methods(const u8 *config_methods,
4994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov					       int wps2, int mandatory)
50045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov{
501e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	u16 val;
502e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
503e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (config_methods == NULL) {
50495068e5d1bea47091e97955f271c789264994550Svetoslav Ganov		if (mandatory) {
50577276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
50677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov				   "Configuration Methods attribute missing");
50777276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov			return -1;
50877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		}
509e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
510e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
511e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
512e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	val = WPA_GET_BE16(config_methods);
513e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (!valid_config_methods(val, wps2)) {
514ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
515e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "Configuration Methods attribute value 0x%04x",
51691feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			   val);
51791feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		return -1;
518e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
519736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
520736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
521f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
522f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
523f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganovstatic int wps_validate_authorized_macs(const u8 *authorized_macs, size_t len,
524f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov					int mandatory)
525f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov{
526f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (authorized_macs == NULL) {
527f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		if (mandatory) {
528f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Authorized MACs "
529f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				   "attribute missing");
530f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
531f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
532f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return 0;
533f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
534f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (len > 30 && (len % ETH_ALEN) != 0) {
535f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		wpa_hexdump(MSG_INFO, "WPS-STRICT: Invalid Authorized "
536e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			    "MACs attribute value", authorized_macs, len);
537e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
538e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
539e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
540e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
541f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
54291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
543736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_msg_type(const u8 *msg_type, int mandatory)
544736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
545e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (msg_type == NULL) {
546e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
547e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Message Type "
548e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
549e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
550e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
551e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
552e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
553e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (*msg_type < WPS_Beacon || *msg_type > WPS_WSC_DONE) {
554e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Message Type "
555e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value 0x%x", *msg_type);
556ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov		return -1;
557e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
558e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
559e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
56045af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov
56145af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov
562e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_mac_addr(const u8 *mac_addr, int mandatory)
56345af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov{
564e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (mac_addr == NULL) {
56545af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov		if (mandatory) {
566e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: MAC Address "
567e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
56847e02711d78ecac9112aa7f66e5664cdc46fb3d1Svetoslav Ganov			return -1;
569736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
570e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
571e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
572f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (mac_addr[0] & 0x01) {
573736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid MAC Address "
574e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "attribute value " MACSTR, MAC2STR(mac_addr));
575e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
576e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
577e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
578e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
579736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
580736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
581736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_enrollee_nonce(const u8 *enrollee_nonce, int mandatory)
582736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
58300f7b3f76515d1c6fbe5cf9fee9d3760787c03cdSvetoslav Ganov	if (enrollee_nonce == NULL) {
58491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		if (mandatory) {
58591feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Enrollee Nonce "
58691feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov				   "attribute missing");
587736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
588736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
589736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
590736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
591736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
59245af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov}
593736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
594736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
595e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_registrar_nonce(const u8 *registrar_nonce,
596e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov					int mandatory)
597e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
598e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (registrar_nonce == NULL) {
599e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
600e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Registrar Nonce "
601e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
602e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
603e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
604ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov		return 0;
605e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
606e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
607f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov}
608e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
609736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
610736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_public_key(const u8 *public_key, size_t len,
611736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   int mandatory)
612736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
61345af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	if (public_key == NULL) {
614736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
615736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Public Key "
616736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
617736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
618e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
619e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
620e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
621e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (len != 192) {
622736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Public Key "
6234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "attribute length %d", (int) len);
62491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		return -1;
625736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
626736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
627736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
6284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
629736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
630736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int num_bits_set(u16 val)
631736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
632f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	int c;
633f5a07905a3e025f95472a3f8d9935263e49ad6d3Svetoslav Ganov	for (c = 0; val; c++)
634e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		val &= val - 1;
635e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return c;
63677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
637736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
638e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
639f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganovstatic int wps_validate_auth_type_flags(const u8 *flags, int mandatory)
640f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov{
641f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	u16 val;
642f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
643f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (flags == NULL) {
644736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
645736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
646736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "Flags attribute missing");
64745af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov			return -1;
648736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
649736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
650e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
651736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	val = WPA_GET_BE16(flags);
652736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if ((val & ~WPS_AUTH_TYPES) || !(val & WPS_AUTH_WPA2PSK)) {
653736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
654736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "Flags attribute value 0x%04x", val);
655736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
656736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
657736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
658736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
659736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
660736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
661736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_auth_type(const u8 *type, int mandatory)
66291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov{
663736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	u16 val;
664736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
665736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (type == NULL) {
666736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
667736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
668736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
669736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
670736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
671736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
67291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov	}
673736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	val = WPA_GET_BE16(type);
674736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if ((val & ~WPS_AUTH_TYPES) || val == 0 ||
675736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    (num_bits_set(val) > 1 &&
6764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	     val != (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK))) {
677736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
6782e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov			   "attribute value 0x%04x", val);
6792e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov		return -1;
6802e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov	}
681736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
682736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
683e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
684e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
685e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_encr_type_flags(const u8 *flags, int mandatory)
686e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
687e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	u16 val;
688e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
689e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (flags == NULL) {
690e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
691e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
692e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "Flags attribute missing");
693e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
694e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
695e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
696e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
697e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	val = WPA_GET_BE16(flags);
698e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if ((val & ~WPS_ENCR_TYPES) || !(val & WPS_ENCR_AES)) {
699e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
700e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "Flags attribute value 0x%04x", val);
701e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
702e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
703e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
704e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
705736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
70691feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
70791feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganovstatic int wps_validate_encr_type(const u8 *type, int mandatory)
708736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
709736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	u16 val;
710736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
711736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (type == NULL) {
712736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
71391feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
71491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov				   "attribute missing");
715736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
716736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
717736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
718736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
719736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	val = WPA_GET_BE16(type);
720736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if ((val & ~WPS_ENCR_TYPES) || val == 0 ||
721736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    (num_bits_set(val) > 1 && val != (WPS_ENCR_TKIP | WPS_ENCR_AES))) {
72291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
72391feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			   "attribute value 0x%04x", val);
724736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
725736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
726736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
727736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
728736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
729aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov
730aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganovstatic int wps_validate_conn_type_flags(const u8 *flags, int mandatory)
731aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov{
732aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov	if (flags == NULL) {
733aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov		if (mandatory) {
734aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Connection Type "
735aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov				   "Flags attribute missing");
736aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov			return -1;
7372e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov		}
73877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		return 0;
73977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	}
74077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if ((*flags & ~(WPS_CONN_ESS | WPS_CONN_IBSS)) ||
741aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov	    !(*flags & WPS_CONN_ESS)) {
742aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Connection Type "
743aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov			   "Flags attribute value 0x%02x", *flags);
744aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov		return -1;
745aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov	}
746aeb8d0ed0d98d398a66a092c418f4f2bca8719e0Svetoslav Ganov	return 0;
7472e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov}
7482e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov
749736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
750e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_os_version(const u8 *os_version, int mandatory)
751736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
752736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (os_version == NULL) {
753736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
754736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: OS Version "
755736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
756736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
757736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
758736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
759736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
760736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
7612e1c66bd53d30d2148afaa4b393b60cd59976d65Svetoslav Ganov}
762736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
763736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
764736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_authenticator(const u8 *authenticator, int mandatory)
765736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
766736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (authenticator == NULL) {
767736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
768736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Authenticator "
769736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
7704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
7714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
772736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
773f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	}
774f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	return 0;
775736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
776736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
777e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
77877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganovstatic int wps_validate_e_hash1(const u8 *hash, int mandatory)
77977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov{
78077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (hash == NULL) {
78177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		if (mandatory) {
782736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash1 "
783e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
784e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
785e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
786736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
7874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
788736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
789736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
790736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
791736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
792e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_e_hash2(const u8 *hash, int mandatory)
793736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
794736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (hash == NULL) {
795736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
796736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash2 "
797736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
798736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
7994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
8004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
8014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
8024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
8034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
8044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
8054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
8064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_r_hash1(const u8 *hash, int mandatory)
8074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
8084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (hash == NULL) {
8094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (mandatory) {
8104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash1 "
8114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
8124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
8134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
8144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
8154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
8164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
8174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
8184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
819e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
82077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganovstatic int wps_validate_r_hash2(const u8 *hash, int mandatory)
82177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov{
82277276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (hash == NULL) {
82377276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		if (mandatory) {
82477276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash2 "
82577276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov				   "attribute missing");
82677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov			return -1;
8274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
8284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
8294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
8304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
8314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
8324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
8334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
8344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_encr_settings(const u8 *encr_settings, size_t len,
8354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   int mandatory)
8364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
8374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (encr_settings == NULL) {
8384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (mandatory) {
8394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Encrypted Settings "
8404213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
8414213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
8424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
8434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
844e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
8454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (len < 16) {
8464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encrypted Settings "
8474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "attribute length %d", (int) len);
8484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
8494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
8504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
8514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
85295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov
8534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
8544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_settings_delay_time(const u8 *delay, int mandatory)
8554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
856e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (delay == NULL) {
8574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (mandatory) {
8584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Settings Delay Time "
8594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				   "attribute missing");
8604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
861736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
86277276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		return 0;
86377276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	}
86477276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	return 0;
86577276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
86677276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
86777276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
86877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganovstatic int wps_validate_r_snonce1(const u8 *nonce, int mandatory)
86977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov{
87077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (nonce == NULL) {
871f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		if (mandatory) {
872f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce1 "
873f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				   "attribute missing");
874f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
875f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
876f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return 0;
877f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
878f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	return 0;
87977276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
88077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
88177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
88277276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganovstatic int wps_validate_r_snonce2(const u8 *nonce, int mandatory)
883736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
884736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (nonce == NULL) {
885736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
886736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce2 "
887736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
888736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
889736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
8904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return 0;
8914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
892f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	return 0;
893f804420d6e37748b75478406e989c69303756980Svetoslav Ganov}
894736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
895f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
896f804420d6e37748b75478406e989c69303756980Svetoslav Ganovstatic int wps_validate_e_snonce1(const u8 *nonce, int mandatory)
897736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
8984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (nonce == NULL) {
899f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		if (mandatory) {
900f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce1 "
901f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				   "attribute missing");
902736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
903f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		}
904f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return 0;
905f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	}
906736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
9074213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
908736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
909736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
910f804420d6e37748b75478406e989c69303756980Svetoslav Ganovstatic int wps_validate_e_snonce2(const u8 *nonce, int mandatory)
9114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
912736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (nonce == NULL) {
913736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
914f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce2 "
915f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				   "attribute missing");
916f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			return -1;
917f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		}
918f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return 0;
919736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
920f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	return 0;
921e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
922e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
923e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
924e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_key_wrap_auth(const u8 *auth, int mandatory)
925e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
926f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (auth == NULL) {
927e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
928e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Key Wrap "
929e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "Authenticator attribute missing");
930f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			return -1;
931f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		}
932fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov		return 0;
933e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
934e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
935e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
936e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
937e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
938e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_ssid(const u8 *ssid, size_t ssid_len, int mandatory)
939e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
940f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	if (ssid == NULL) {
941f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		if (mandatory) {
942f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: SSID "
943f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				   "attribute missing");
944e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
945e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
946e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
947f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
948e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (ssid_len == 0 || ssid[ssid_len - 1] == 0) {
949736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid SSID "
950736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				  "attribute value", ssid, ssid_len);
951736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
952736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
953736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
954736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
955736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
956736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
957736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_network_key_index(const u8 *idx, int mandatory)
958736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
959736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (idx == NULL) {
9604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (mandatory) {
961f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key Index "
962f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				   "attribute missing");
963736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
964736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
965736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
9664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
967736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
968736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
969f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
970f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
971f804420d6e37748b75478406e989c69303756980Svetoslav Ganovstatic int wps_validate_network_idx(const u8 *idx, int mandatory)
972736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
973736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (idx == NULL) {
974736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
975736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Network Index "
976736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
977736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
978736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		}
979736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
980736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
981736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
9824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
983736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
984736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
9854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovstatic int wps_validate_network_key(const u8 *key, size_t key_len,
986f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				    const u8 *encr_type, int mandatory)
987736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
988736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (key == NULL) {
989736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (mandatory) {
990736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
991736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   "attribute missing");
9924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
9934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		}
994736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
995736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
996736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (((encr_type == NULL || WPA_GET_BE16(encr_type) != WPS_ENCR_WEP) &&
997f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	     key_len > 8 && key_len < 64 && key[key_len - 1] == 0) ||
998f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    key_len > 64) {
999f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		wpa_hexdump_ascii_key(MSG_INFO, "WPS-STRICT: Invalid Network "
1000f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				      "Key attribute value", key, key_len);
1001f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return -1;
10024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
1003f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	return 0;
1004f804420d6e37748b75478406e989c69303756980Svetoslav Ganov}
1005f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1006f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1007f804420d6e37748b75478406e989c69303756980Svetoslav Ganovstatic int wps_validate_network_key_shareable(const u8 *val, int mandatory)
1008f804420d6e37748b75478406e989c69303756980Svetoslav Ganov{
100991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov	if (val == NULL) {
101091feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		if (mandatory) {
101191feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
101291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov				   "Shareable attribute missing");
10134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
101491feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		}
1015736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return 0;
1016736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1017f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	if (*val > 1) {
1018736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Network Key "
1019736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "Shareable attribute value 0x%x", *val);
1020736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1021736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1022736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1023736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1024736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1025736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1026736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovstatic int wps_validate_cred(const u8 *cred, size_t len)
1027bd206d129fdd1777b9f9646a834d7fc342a8941eSvetoslav Ganov{
1028bd206d129fdd1777b9f9646a834d7fc342a8941eSvetoslav Ganov	struct wps_parse_attr attr;
1029f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	struct wpabuf buf;
1030f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1031f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	if (cred == NULL)
1032736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1033736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wpabuf_set(&buf, cred, len);
1034736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(&buf, &attr) < 0) {
103591feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse Credential");
1036736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
103700f7b3f76515d1c6fbe5cf9fee9d3760787c03cdSvetoslav Ganov	}
103891feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov
103991feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov	if (wps_validate_network_idx(attr.network_idx, 1) ||
1040736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_ssid(attr.ssid, attr.ssid_len, 1) ||
1041736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_auth_type(attr.auth_type, 1) ||
104291feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov	    wps_validate_encr_type(attr.encr_type, 1) ||
104391feae3c5994bd4768cea3507c62c65746adcfa6Svetoslav Ganov	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1044f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_network_key(attr.network_key, attr.network_key_len,
1045f804420d6e37748b75478406e989c69303756980Svetoslav Ganov				     attr.encr_type, 1) ||
1046f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_mac_addr(attr.mac_addr, 1) ||
1047f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_network_key_shareable(attr.network_key_shareable, 0))
1048f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	{
1049f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Credential");
1050f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return -1;
1051f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	}
1052f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1053f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1054f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	return 0;
10554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
1056f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1057f804420d6e37748b75478406e989c69303756980Svetoslav Ganov
1058e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovstatic int wps_validate_credential(const u8 *cred[], size_t len[], size_t num,
1059e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   int mandatory)
1060e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
1061e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	size_t i;
1062e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1063e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (num == 0) {
1064e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (mandatory) {
1065e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			wpa_printf(MSG_INFO, "WPS-STRICT: Credential "
1066e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				   "attribute missing");
1067e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
1068e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		}
1069e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return 0;
1070e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1071e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1072e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	for (i = 0; i < num; i++) {
1073e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (wps_validate_cred(cred[i], len[i]) < 0)
1074e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
1075e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1076e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1077e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
1078e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1079e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1080e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1081e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_beacon(const struct wpabuf *wps_ie)
1082e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
1083e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	struct wps_parse_attr attr;
1084e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2, sel_reg;
1085e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1086e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_ie == NULL) {
1087e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in Beacon frame");
1088f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return -1;
10894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
1090f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	if (wps_parse_msg(wps_ie, &attr) < 0) {
1091f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1092f804420d6e37748b75478406e989c69303756980Svetoslav Ganov			   "Beacon frame");
1093f804420d6e37748b75478406e989c69303756980Svetoslav Ganov		return -1;
1094f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	}
10951cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
109645af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	wps2 = attr.version2 != NULL;
109745af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	sel_reg = attr.selected_registrar != NULL &&
109845af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov		*attr.selected_registrar != 0;
109945af84a483165f06c04d74baba67f90da29c6ad2Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
11001cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_wps_state(attr.wps_state, 1) ||
1101f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
11024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
11034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1104f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1105f804420d6e37748b75478406e989c69303756980Svetoslav Ganov						wps2, sel_reg) ||
1106f804420d6e37748b75478406e989c69303756980Svetoslav Ganov	    wps_validate_uuid_e(attr.uuid_e, 0) ||
1107736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 0) ||
1108736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1109736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_authorized_macs(attr.authorized_macs,
1110736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov					 attr.authorized_macs_len, 0)) {
1111736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Beacon frame");
1112736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1113736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1114736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1115736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1116736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1117736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1118736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1119736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_beacon_probe_resp(const struct wpabuf *wps_ie, int probe,
1120736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				   const u8 *addr)
11214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
1122736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	struct wps_parse_attr attr;
11234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	int wps2, sel_reg;
1124736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1125736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_ie == NULL) {
1126736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1127736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "%sProbe Response frame", probe ? "" : "Beacon/");
1128736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1129736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1130736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(wps_ie, &attr) < 0) {
11314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1132736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "%sProbe Response frame", probe ? "" : "Beacon/");
11334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1134736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1135736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1136736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1137736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	sel_reg = attr.selected_registrar != NULL &&
1138736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		*attr.selected_registrar != 0;
1139736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1140736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_wps_state(attr.wps_state, 1) ||
1141736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
1142736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
1143736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1144736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1145e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov						wps2, sel_reg) ||
1146e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_response_type(attr.response_type, probe) ||
1147e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_uuid_e(attr.uuid_e, probe) ||
1148e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1149e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				      probe) ||
11501cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_model_name(attr.model_name, attr.model_name_len,
1151e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				    probe) ||
1152e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1153e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				      probe) ||
1154e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_serial_number(attr.serial_number,
11551cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov				       attr.serial_number_len, probe) ||
11561cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_primary_dev_type(attr.primary_dev_type, probe) ||
1157e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, probe) ||
1158e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_ap_config_methods(attr.config_methods, wps2, probe) ||
1159e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 0) ||
1160e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1161e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_authorized_macs(attr.authorized_macs,
1162e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov					 attr.authorized_macs_len, 0)) {
1163e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid %sProbe Response "
1164e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "frame from " MACSTR, probe ? "" : "Beacon/",
1165e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   MAC2STR(addr));
11661cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov#ifdef WPS_STRICT_WPS2
1167e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (wps2)
1168e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
1169e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
11701cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov		return -1;
11711cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
11721cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	}
11731cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov
1174e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
1175e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1176e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1177e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1178e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_probe_req(const struct wpabuf *wps_ie, const u8 *addr)
11791cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov{
11801cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	struct wps_parse_attr attr;
1181e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2;
1182e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1183e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_ie == NULL) {
1184e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1185e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "Probe Request frame");
1186e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1187e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1188e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_parse_msg(wps_ie, &attr) < 0) {
1189e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
1190e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "Probe Request frame");
1191e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1192e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1193e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1194e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	wps2 = attr.version2 != NULL;
1195e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1196e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_request_type(attr.request_type, 1) ||
1197e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1198e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_uuid_e(attr.uuid_e, attr.uuid_r == NULL) ||
1199e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_uuid_r(attr.uuid_r, attr.uuid_e == NULL) ||
1200e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1201e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1202e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1203e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_config_error(attr.config_error, 1) ||
1204e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
1205e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1206e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1207e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				      wps2) ||
1208e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_model_name(attr.model_name, attr.model_name_len,
120958d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov				    wps2) ||
121058d37b55bd228032355360ea3303e46a804e0516Svetoslav Ganov	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1211e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				      wps2) ||
1212e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, wps2) ||
1213f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	    wps_validate_request_to_enroll(attr.request_to_enroll, 0) ||
1214f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	    wps_validate_req_dev_type(attr.req_dev_type, attr.num_req_dev_type,
1215f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov				      0)) {
1216f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Probe Request "
1217f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			   "frame from " MACSTR, MAC2STR(addr));
1218f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return -1;
1219e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
122086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
122186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	return 0;
1222e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1223e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1224e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
122586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganovint wps_validate_assoc_req(const struct wpabuf *wps_ie)
12265d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov{
12275d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	struct wps_parse_attr attr;
122886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	int wps2;
122986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
123086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	if (wps_ie == NULL) {
123186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
123286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov			   "(Re)Association Request frame");
123386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		return -1;
123486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	}
123586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	if (wps_parse_msg(wps_ie, &attr) < 0) {
123686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
123786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov			   "(Re)Association Request frame");
123886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		return -1;
123986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	}
124086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
124186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	wps2 = attr.version2 != NULL;
124286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
124386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_request_type(attr.request_type, 1) ||
124486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
124586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
1246385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov			   "Request frame");
1247385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		return -1;
1248385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	}
1249385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov
1250385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	return 0;
1251385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov}
1252385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov
1253385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov
1254385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganovint wps_validate_assoc_resp(const struct wpabuf *wps_ie)
125586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov{
125686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	struct wps_parse_attr attr;
1257e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2;
1258e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1259e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_ie == NULL) {
1260e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
1261e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "(Re)Association Response frame");
1262e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1263e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1264e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_parse_msg(wps_ie, &attr) < 0) {
1265e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
126686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov			   "(Re)Association Response frame");
126786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		return -1;
1268e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1269e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1270e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	wps2 = attr.version2 != NULL;
1271e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1272e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_response_type(attr.response_type, 1) ||
1273e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
1274e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
1275e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "Response frame");
1276e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1277e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1278e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1279e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
1280e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1281e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1282e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1283e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_m1(const struct wpabuf *tlvs)
1284e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
1285e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	struct wps_parse_attr attr;
1286e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2;
1287e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1288e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (tlvs == NULL) {
1289e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M1");
1290e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1291e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1292e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1293736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1294736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in M1");
1295736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1296736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1297736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1298736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1299736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
13004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1301736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_uuid_e(attr.uuid_e, 1) ||
13024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_mac_addr(attr.mac_addr, 1) ||
1303736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1304736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
1305736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
1306736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
1307736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
1308736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
1309736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_wps_state(attr.wps_state, 1) ||
1310736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
1311736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				      1) ||
13121cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
13131cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_model_number(attr.model_number, attr.model_number_len,
13141cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov				      1) ||
13151cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_serial_number(attr.serial_number,
1316736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				       attr.serial_number_len, 1) ||
13171cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
13181cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
13191cf70bbf96930662cab0e699d70b62865766ff52Svetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 1) ||
1320736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_assoc_state(attr.assoc_state, 1) ||
1321736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
1322736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_config_error(attr.config_error, 1) ||
132351cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	    wps_validate_os_version(attr.os_version, 1) ||
132451cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
132551cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	    wps_validate_request_to_enroll(attr.request_to_enroll, 0)) {
132651cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M1");
132751cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov#ifdef WPS_STRICT_WPS2
132851cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov		if (wps2)
132951cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov			return -1;
133051cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
133151cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov		return -1;
133251cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
133351cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	}
133451cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov
133551cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	return 0;
13364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
13374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
133851cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov
133951cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganovint wps_validate_m2(const struct wpabuf *tlvs)
134051cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov{
134151cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	struct wps_parse_attr attr;
134251cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov	int wps2;
134351cccf0845b36539d42503495f0689d487712b3aSvetoslav Ganov
13444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
1345736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2");
13464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
13474213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
13484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
13494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
13504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M2");
13514213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
13524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
13534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
135495068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	wps2 = attr.version2 != NULL;
135595068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
135695068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
135795068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
135895068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
135995068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_uuid_r(attr.uuid_r, 1) ||
136095068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
136195068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
136295068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
136395068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
136495068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
136595068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
136695068e5d1bea47091e97955f271c789264994550Svetoslav Ganov				      1) ||
136795068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
1368aed4b6f812674bc60a04470013ca449e5c114fa5Svetoslav Ganov	    wps_validate_model_number(attr.model_number, attr.model_number_len,
1369aed4b6f812674bc60a04470013ca449e5c114fa5Svetoslav Ganov				      1) ||
1370aed4b6f812674bc60a04470013ca449e5c114fa5Svetoslav Ganov	    wps_validate_serial_number(attr.serial_number,
1371aed4b6f812674bc60a04470013ca449e5c114fa5Svetoslav Ganov				       attr.serial_number_len, 1) ||
1372aed4b6f812674bc60a04470013ca449e5c114fa5Svetoslav Ganov	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
137395068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
137495068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 1) ||
137595068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_assoc_state(attr.assoc_state, 1) ||
137695068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_config_error(attr.config_error, 1) ||
137795068e5d1bea47091e97955f271c789264994550Svetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
13784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_os_version(attr.os_version, 1) ||
13794213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
13804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
13814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2");
13824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
13834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (wps2)
1384e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
13854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
13864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1387e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
13884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
13894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
13904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
139177276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov}
13924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
13934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
13944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovint wps_validate_m2d(const struct wpabuf *tlvs)
13954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
13964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
139777276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	int wps2;
13984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
13994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
14004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2D");
14014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
14024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
1403ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1404ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1405ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov			   "in M2D");
1406ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov		return -1;
1407ebac1b79c4a355d8cd73b49df059deb00d7aa256Svetoslav Ganov	}
140886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
140986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	wps2 = attr.version2 != NULL;
1410238099c0dbbdc66b8443552126680ad1c7cab17dSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1411238099c0dbbdc66b8443552126680ad1c7cab17dSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1412238099c0dbbdc66b8443552126680ad1c7cab17dSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1413238099c0dbbdc66b8443552126680ad1c7cab17dSvetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14145d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_uuid_r(attr.uuid_r, 1) ||
14155d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
141686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
141786783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
141886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
141986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
142086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				      1) ||
142186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
142286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_model_number(attr.model_number, attr.model_number_len,
142386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				      1) ||
142486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_serial_number(attr.serial_number,
142586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov				       attr.serial_number_len, 1) ||
142686783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
1427e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
142886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_rf_bands(attr.rf_bands, 1) ||
142986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_assoc_state(attr.assoc_state, 1) ||
143086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_config_error(attr.config_error, 1) ||
143186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_os_version(attr.os_version, 1) ||
143286783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
143386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2D");
1434385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov#ifdef WPS_STRICT_WPS2
1435385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		if (wps2)
1436385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov			return -1;
1437385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
1438385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov		return -1;
1439385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1440385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	}
1441385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov
1442385d9f24b5ce2acb86c0dc192ce702718ab01c39Svetoslav Ganov	return 0;
144386783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov}
144486783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
144586783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
1446e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_m3(const struct wpabuf *tlvs)
1447238099c0dbbdc66b8443552126680ad1c7cab17dSvetoslav Ganov{
144886783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	struct wps_parse_attr attr;
144986783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	int wps2;
145086783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov
145186783474fdec98a22bc22e224462767eab13e273Svetoslav Ganov	if (tlvs == NULL) {
1452f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M3");
14534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1454e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
14554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
14564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M3");
14584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
14594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
146077276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov
14614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	wps2 = attr.version2 != NULL;
14624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
14634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
14644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_e_hash1(attr.e_hash1, 1) ||
14664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_e_hash2(attr.e_hash2, 1) ||
14674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
14684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
14694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M3");
14704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
14714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (wps2)
1472e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
1473e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1474e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1475e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1476e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1477e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1478e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
14794213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
14804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
14814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1482e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_m4(const struct wpabuf *tlvs)
1483e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
1484e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	struct wps_parse_attr attr;
1485e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2;
1486e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
148777276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov	if (tlvs == NULL) {
148877276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4");
14894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1490e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
14914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
14924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1493e47957a0bbe2164467ff6e7a566b0c9e4689cdc9Svetoslav Ganov			   "in M4");
1494e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1495e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1496e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1497e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	wps2 = attr.version2 != NULL;
1498e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1499e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1500e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1501e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_r_hash1(attr.r_hash1, 1) ||
1502e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_r_hash2(attr.r_hash2, 1) ||
1503e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_encr_settings(attr.encr_settings,
1504e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov				       attr.encr_settings_len, 1) ||
1505e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1506e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
1507e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4");
15084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
15094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (wps2)
15104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
15114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
15124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
15134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
15144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
1515e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1516e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
15174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
15184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
15194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1520e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2)
15214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
15224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
1523e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1524e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (tlvs == NULL) {
15254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted "
15264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
15274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
15284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
15294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1530e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M4 encrypted settings");
15324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
15334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
15344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
15354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_validate_r_snonce1(attr.r_snonce1, 1) ||
15364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
15374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted "
1538e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "settings");
1539e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1540e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (wps2)
1541e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
15424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
1543f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return -1;
1544f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1545e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1546f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
1547f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	return 0;
1548f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov}
1549f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
1550f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
1551f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganovint wps_validate_m5(const struct wpabuf *tlvs)
155277276b60851a158ad3e142cb3b091d57ae5ceffbSvetoslav Ganov{
1553e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	struct wps_parse_attr attr;
1554e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	int wps2;
15554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
15564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
15574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5");
15584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1559f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
1560f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1561f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1562f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov			   "in M5");
1563f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov		return -1;
1564f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	}
1565f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov
1566f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	wps2 = attr.version2 != NULL;
1567fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1568fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1569fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1570fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	    wps_validate_encr_settings(attr.encr_settings,
1571fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov				       attr.encr_settings_len, 1) ||
1572fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1573f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
1574fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5");
1575fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1576fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov		if (wps2)
1577fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov			return -1;
1578fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1579fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov		return -1;
1580fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1581fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	}
1582fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov
1583fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	return 0;
1584fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov}
1585fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov
1586fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov
1587fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganovint wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2)
1588fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov{
1589f068fed6c4c3fc2003aec19b6e7e892358179b02Svetoslav Ganov	struct wps_parse_attr attr;
1590fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov
1591fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov	if (tlvs == NULL) {
1592fe304b893968887323b93764caafa66ee8ad44deSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted "
15934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
15944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
15954213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
15964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
15974213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15984213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M5 encrypted settings");
15994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16014213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16024213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_validate_e_snonce1(attr.e_snonce1, 1) ||
16034213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16044213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted "
16054213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
16064213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
1607e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (wps2)
1608e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			return -1;
16094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
16105d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov		return -1;
16115d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
16125d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	}
16134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
16154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
16164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovint wps_validate_m6(const struct wpabuf *tlvs)
16194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
16204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
16214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	int wps2;
16224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
16244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6");
16254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
16284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16294213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M6");
16304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16324213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16334213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	wps2 = attr.version2 != NULL;
16344213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
16354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
16364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
16374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_encr_settings(attr.encr_settings,
16384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov				       attr.encr_settings_len, 1) ||
16394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1640e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
1641e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6");
1642e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1643e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		if (wps2)
16445d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov			return -1;
16455d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
16465d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov		return -1;
16475d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
16484213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16494213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16504213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
1651e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
16524213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16534213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16544213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovint wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2)
16554213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
16564213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
16574213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16584213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
16594213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted "
16604213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
16614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16634213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
16644213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16654213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M6 encrypted settings");
16664213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16674213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16694213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_validate_r_snonce2(attr.r_snonce2, 1) ||
16704213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted "
16724213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
16734213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
16744213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (wps2)
16754213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
16764213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
16774213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16784213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
16794213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16804213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16814213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
16824213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
16834213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16844213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16854213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovint wps_validate_m7(const struct wpabuf *tlvs)
16864213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
16874213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
16884213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	int wps2;
16894213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
16904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
16914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7");
16924213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
16934213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
16944213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1695e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16964213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M7");
1697e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1698e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
16994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17004213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	wps2 = attr.version2 != NULL;
17015d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
17025d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
17035d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
17045d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_encr_settings(attr.encr_settings,
17055d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov				       attr.encr_settings_len, 1) ||
17065d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_settings_delay_time(attr.settings_delay_time, 0) ||
17075d043ce8cc2f588fdfb336cc843fb3b07b196f83Svetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
17084213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
17094213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7");
17104213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#ifdef WPS_STRICT_WPS2
17114213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		if (wps2)
17124213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
17134213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
17144213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
17154213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#endif /* WPS_STRICT_WPS2 */
17164213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
17174213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17184213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	return 0;
17194213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov}
17204213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17214213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17224213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganovint wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2)
17234213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
17244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
17254213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
17264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
17274213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted "
17284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "settings");
1729736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1730736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1731736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1732736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1733736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in M7 encrypted settings");
1734736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1735736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1736736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1737736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_e_snonce2(attr.e_snonce2, 1) ||
1738736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) ||
1739736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_mac_addr(attr.mac_addr, !ap) ||
1740736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_auth_type(attr.auth_type, !ap) ||
1741736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_encr_type(attr.encr_type, !ap) ||
1742736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1743736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_network_key(attr.network_key, attr.network_key_len,
1744736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				     attr.encr_type, !ap) ||
1745736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1746736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7 encrypted "
1747736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "settings");
1748736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1749736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
1750736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
1751736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1752736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1753736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1754736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1755736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1756736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1757736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1758736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1759736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1760736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_m8(const struct wpabuf *tlvs)
17614213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
17624213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
1763736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	int wps2;
1764e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1765e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (tlvs == NULL) {
1766736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8");
1767736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1768736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1769736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1770736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
17714213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "in M8");
1772736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
177376c0dd48279531cb31e2a284a270c535664cbf81Svetoslav Ganov	}
1774736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1775736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1776736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1777736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1778736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1779736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_encr_settings(attr.encr_settings,
1780736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov				       attr.encr_settings_len, 1) ||
1781736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1782736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_authenticator(attr.authenticator, 1)) {
1783736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8");
1784736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1785736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
1786736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
1787736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1788736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1789736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
17904213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
17914213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1792736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1793736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1794736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1795736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1796736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2)
1797736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
1798736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	struct wps_parse_attr attr;
17994213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1800e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	if (tlvs == NULL) {
1801e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted "
1802e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov			   "settings");
1803e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov		return -1;
1804e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	}
1805736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1806736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1807736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in M8 encrypted settings");
180800f7b3f76515d1c6fbe5cf9fee9d3760787c03cdSvetoslav Ganov		return -1;
1809736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1810736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1811736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) ||
1812736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_auth_type(attr.auth_type, ap) ||
1813736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_encr_type(attr.encr_type, ap) ||
1814736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
1815736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_mac_addr(attr.mac_addr, ap) ||
1816736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_credential(attr.cred, attr.cred_len, attr.num_cred,
181700f7b3f76515d1c6fbe5cf9fee9d3760787c03cdSvetoslav Ganov				    !ap) ||
1818736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
1819736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8 encrypted "
1820736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "settings");
1821736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1822736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
1823736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
18244213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov#else /* WPS_STRICT_WPS2 */
1825736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1826736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1827736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1828736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1829e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	return 0;
1830e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov}
1831e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1832e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov
1833e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganovint wps_validate_wsc_ack(const struct wpabuf *tlvs)
1834e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov{
1835e15ccb93add99ebb9cd7aec03a04faa37f45b39dSvetoslav Ganov	struct wps_parse_attr attr;
18364213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	int wps2;
1837736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
18384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
18394213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_ACK");
1840736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1841736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1842736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
18434213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1844736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in WSC_ACK");
18454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
18464213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
1847736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1848736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1849736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1850736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1851736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1852736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1853736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
1854736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_ACK");
1855736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1856736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
1857736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
1858736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1859736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1860736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1861736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1862736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1863736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1864736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1865736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1866736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1867736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_wsc_nack(const struct wpabuf *tlvs)
1868736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
1869736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	struct wps_parse_attr attr;
1870736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	int wps2;
1871736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1872736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (tlvs == NULL) {
1873736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_NACK");
1874736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1875736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1876736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1877736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1878736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in WSC_NACK");
1879736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1880736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1881736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1882736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1883736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1884736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1885736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1886736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1887736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_config_error(attr.config_error, 1) ||
1888736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
1889736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_NACK");
1890736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1891736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
1892736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			return -1;
1893736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1894736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1895736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1896736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1897736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1898736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1899736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1900736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1901736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1902736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_wsc_done(const struct wpabuf *tlvs)
1903736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov{
1904736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	struct wps_parse_attr attr;
1905736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	int wps2;
1906736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1907736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (tlvs == NULL) {
1908736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_Done");
1909736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1910736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1911736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1912736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1913736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in WSC_Done");
1914736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1915736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1916736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1917736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1918736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1919736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_msg_type(attr.msg_type, 1) ||
1920736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
1921736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
1922736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2)) {
1923736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_Done");
1924736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1925736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
19264213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
1927736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
19284213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1929736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
19304213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	}
19314213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1932736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1933736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1934736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
19354213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov
1936736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganovint wps_validate_upnp_set_selected_registrar(const struct wpabuf *tlvs)
19374213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov{
19384213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	struct wps_parse_attr attr;
1939736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	int wps2;
1940736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	int sel_reg;
1941736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
19424213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov	if (tlvs == NULL) {
1943736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in "
19444213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			   "SetSelectedRegistrar");
19454213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov		return -1;
1946736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1947736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_parse_msg(tlvs, &attr) < 0) {
1948736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
1949736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "in SetSelectedRegistrar");
1950736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1951736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1952736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1953736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	wps2 = attr.version2 != NULL;
1954736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	sel_reg = attr.selected_registrar != NULL &&
1955736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		*attr.selected_registrar != 0;
1956736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	if (wps_validate_version(attr.version, 1) ||
1957736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
1958736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
1959736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov						wps2, sel_reg) ||
1960736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_version2(attr.version2, wps2) ||
1961736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_authorized_macs(attr.authorized_macs,
1962736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov					 attr.authorized_macs_len, wps2) ||
1963736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	    wps_validate_uuid_r(attr.uuid_r, wps2)) {
1964736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid "
1965736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov			   "SetSelectedRegistrar");
1966736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#ifdef WPS_STRICT_WPS2
1967736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		if (wps2)
19684213804541a8b05cd0587b138a2fd9a3b7fd9350Svetoslav Ganov			return -1;
1969736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#else /* WPS_STRICT_WPS2 */
1970736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov		return -1;
1971736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov#endif /* WPS_STRICT_WPS2 */
1972736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	}
1973736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov
1974736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov	return 0;
1975736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov}
1976736c2756bf3c14ae9fef7255c119057f7a2be1edSvetoslav Ganov