xref: /dflybsd-src/contrib/wpa_supplicant/src/wps/wps_validate.c (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
13ff40c12SJohn Marino /*
23ff40c12SJohn Marino  * Wi-Fi Protected Setup - Strict protocol validation routines
33ff40c12SJohn Marino  * Copyright (c) 2010, Atheros Communications, Inc.
43ff40c12SJohn Marino  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
73ff40c12SJohn Marino  */
83ff40c12SJohn Marino 
93ff40c12SJohn Marino #include "utils/includes.h"
103ff40c12SJohn Marino 
113ff40c12SJohn Marino #include "utils/common.h"
123ff40c12SJohn Marino #include "wps_i.h"
133ff40c12SJohn Marino #include "wps.h"
143ff40c12SJohn Marino 
153ff40c12SJohn Marino 
163ff40c12SJohn Marino #ifndef WPS_STRICT_ALL
173ff40c12SJohn Marino #define WPS_STRICT_WPS2
183ff40c12SJohn Marino #endif /* WPS_STRICT_ALL */
193ff40c12SJohn Marino 
203ff40c12SJohn Marino 
wps_validate_version(const u8 * version,int mandatory)213ff40c12SJohn Marino static int wps_validate_version(const u8 *version, int mandatory)
223ff40c12SJohn Marino {
233ff40c12SJohn Marino 	if (version == NULL) {
243ff40c12SJohn Marino 		if (mandatory) {
253ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Version attribute "
263ff40c12SJohn Marino 				   "missing");
273ff40c12SJohn Marino 			return -1;
283ff40c12SJohn Marino 		}
293ff40c12SJohn Marino 		return 0;
303ff40c12SJohn Marino 	}
313ff40c12SJohn Marino 	if (*version != 0x10) {
323ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version attribute "
333ff40c12SJohn Marino 			   "value 0x%x", *version);
343ff40c12SJohn Marino 		return -1;
353ff40c12SJohn Marino 	}
363ff40c12SJohn Marino 	return 0;
373ff40c12SJohn Marino }
383ff40c12SJohn Marino 
393ff40c12SJohn Marino 
wps_validate_version2(const u8 * version2,int mandatory)403ff40c12SJohn Marino static int wps_validate_version2(const u8 *version2, int mandatory)
413ff40c12SJohn Marino {
423ff40c12SJohn Marino 	if (version2 == NULL) {
433ff40c12SJohn Marino 		if (mandatory) {
443ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Version2 attribute "
453ff40c12SJohn Marino 				   "missing");
463ff40c12SJohn Marino 			return -1;
473ff40c12SJohn Marino 		}
483ff40c12SJohn Marino 		return 0;
493ff40c12SJohn Marino 	}
503ff40c12SJohn Marino 	if (*version2 < 0x20) {
513ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version2 attribute "
523ff40c12SJohn Marino 			   "value 0x%x", *version2);
533ff40c12SJohn Marino 		return -1;
543ff40c12SJohn Marino 	}
553ff40c12SJohn Marino 	return 0;
563ff40c12SJohn Marino }
573ff40c12SJohn Marino 
583ff40c12SJohn Marino 
wps_validate_request_type(const u8 * request_type,int mandatory)593ff40c12SJohn Marino static int wps_validate_request_type(const u8 *request_type, int mandatory)
603ff40c12SJohn Marino {
613ff40c12SJohn Marino 	if (request_type == NULL) {
623ff40c12SJohn Marino 		if (mandatory) {
633ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Request Type "
643ff40c12SJohn Marino 				   "attribute missing");
653ff40c12SJohn Marino 			return -1;
663ff40c12SJohn Marino 		}
673ff40c12SJohn Marino 		return 0;
683ff40c12SJohn Marino 	}
693ff40c12SJohn Marino 	if (*request_type > 0x03) {
703ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request Type "
713ff40c12SJohn Marino 			   "attribute value 0x%x", *request_type);
723ff40c12SJohn Marino 		return -1;
733ff40c12SJohn Marino 	}
743ff40c12SJohn Marino 	return 0;
753ff40c12SJohn Marino }
763ff40c12SJohn Marino 
773ff40c12SJohn Marino 
wps_validate_response_type(const u8 * response_type,int mandatory)783ff40c12SJohn Marino static int wps_validate_response_type(const u8 *response_type, int mandatory)
793ff40c12SJohn Marino {
803ff40c12SJohn Marino 	if (response_type == NULL) {
813ff40c12SJohn Marino 		if (mandatory) {
823ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Response Type "
833ff40c12SJohn Marino 				   "attribute missing");
843ff40c12SJohn Marino 			return -1;
853ff40c12SJohn Marino 		}
863ff40c12SJohn Marino 		return 0;
873ff40c12SJohn Marino 	}
883ff40c12SJohn Marino 	if (*response_type > 0x03) {
893ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Response Type "
903ff40c12SJohn Marino 			   "attribute value 0x%x", *response_type);
913ff40c12SJohn Marino 		return -1;
923ff40c12SJohn Marino 	}
933ff40c12SJohn Marino 	return 0;
943ff40c12SJohn Marino }
953ff40c12SJohn Marino 
963ff40c12SJohn Marino 
valid_config_methods(u16 val,int wps2)973ff40c12SJohn Marino static int valid_config_methods(u16 val, int wps2)
983ff40c12SJohn Marino {
993ff40c12SJohn Marino 	if (wps2) {
1003ff40c12SJohn Marino 		if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
1013ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
1023ff40c12SJohn Marino 				   "Display flag without old Display flag "
1033ff40c12SJohn Marino 				   "set");
1043ff40c12SJohn Marino 			return 0;
1053ff40c12SJohn Marino 		}
1063ff40c12SJohn Marino 		if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
1073ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
1083ff40c12SJohn Marino 				   "without Physical/Virtual Display flag");
1093ff40c12SJohn Marino 			return 0;
1103ff40c12SJohn Marino 		}
1113ff40c12SJohn Marino 		if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
1123ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
1133ff40c12SJohn Marino 				   "PushButton flag without old PushButton "
1143ff40c12SJohn Marino 				   "flag set");
1153ff40c12SJohn Marino 			return 0;
1163ff40c12SJohn Marino 		}
1173ff40c12SJohn Marino 		if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
1183ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
1193ff40c12SJohn Marino 				   "without Physical/Virtual PushButton flag");
1203ff40c12SJohn Marino 			return 0;
1213ff40c12SJohn Marino 		}
1223ff40c12SJohn Marino 	}
1233ff40c12SJohn Marino 
1243ff40c12SJohn Marino 	return 1;
1253ff40c12SJohn Marino }
1263ff40c12SJohn Marino 
1273ff40c12SJohn Marino 
wps_validate_config_methods(const u8 * config_methods,int wps2,int mandatory)1283ff40c12SJohn Marino static int wps_validate_config_methods(const u8 *config_methods, int wps2,
1293ff40c12SJohn Marino 				       int mandatory)
1303ff40c12SJohn Marino {
1313ff40c12SJohn Marino 	u16 val;
1323ff40c12SJohn Marino 
1333ff40c12SJohn Marino 	if (config_methods == NULL) {
1343ff40c12SJohn Marino 		if (mandatory) {
1353ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration "
1363ff40c12SJohn Marino 				   "Methods attribute missing");
1373ff40c12SJohn Marino 			return -1;
1383ff40c12SJohn Marino 		}
1393ff40c12SJohn Marino 		return 0;
1403ff40c12SJohn Marino 	}
1413ff40c12SJohn Marino 
1423ff40c12SJohn Marino 	val = WPA_GET_BE16(config_methods);
1433ff40c12SJohn Marino 	if (!valid_config_methods(val, wps2)) {
1443ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
1453ff40c12SJohn Marino 			   "Methods attribute value 0x%04x", val);
1463ff40c12SJohn Marino 		return -1;
1473ff40c12SJohn Marino 	}
1483ff40c12SJohn Marino 	return 0;
1493ff40c12SJohn Marino }
1503ff40c12SJohn Marino 
1513ff40c12SJohn Marino 
wps_validate_ap_config_methods(const u8 * config_methods,int wps2,int mandatory)1523ff40c12SJohn Marino static int wps_validate_ap_config_methods(const u8 *config_methods, int wps2,
1533ff40c12SJohn Marino 					  int mandatory)
1543ff40c12SJohn Marino {
1553ff40c12SJohn Marino 	u16 val;
1563ff40c12SJohn Marino 
1573ff40c12SJohn Marino 	if (wps_validate_config_methods(config_methods, wps2, mandatory) < 0)
1583ff40c12SJohn Marino 		return -1;
1593ff40c12SJohn Marino 	if (config_methods == NULL)
1603ff40c12SJohn Marino 		return 0;
1613ff40c12SJohn Marino 	val = WPA_GET_BE16(config_methods);
1623ff40c12SJohn Marino 	if (val & WPS_CONFIG_PUSHBUTTON) {
1633ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
1643ff40c12SJohn Marino 			   "Methods attribute value 0x%04x in AP info "
1653ff40c12SJohn Marino 			   "(PushButton not allowed for registering new ER)",
1663ff40c12SJohn Marino 			   val);
1673ff40c12SJohn Marino 		return -1;
1683ff40c12SJohn Marino 	}
1693ff40c12SJohn Marino 	return 0;
1703ff40c12SJohn Marino }
1713ff40c12SJohn Marino 
1723ff40c12SJohn Marino 
wps_validate_uuid_e(const u8 * uuid_e,int mandatory)1733ff40c12SJohn Marino static int wps_validate_uuid_e(const u8 *uuid_e, int mandatory)
1743ff40c12SJohn Marino {
1753ff40c12SJohn Marino 	if (uuid_e == NULL) {
1763ff40c12SJohn Marino 		if (mandatory) {
1773ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-E "
1783ff40c12SJohn Marino 				   "attribute missing");
1793ff40c12SJohn Marino 			return -1;
1803ff40c12SJohn Marino 		}
1813ff40c12SJohn Marino 		return 0;
1823ff40c12SJohn Marino 	}
1833ff40c12SJohn Marino 	return 0;
1843ff40c12SJohn Marino }
1853ff40c12SJohn Marino 
1863ff40c12SJohn Marino 
wps_validate_uuid_r(const u8 * uuid_r,int mandatory)1873ff40c12SJohn Marino static int wps_validate_uuid_r(const u8 *uuid_r, int mandatory)
1883ff40c12SJohn Marino {
1893ff40c12SJohn Marino 	if (uuid_r == NULL) {
1903ff40c12SJohn Marino 		if (mandatory) {
1913ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-R "
1923ff40c12SJohn Marino 				   "attribute missing");
1933ff40c12SJohn Marino 			return -1;
1943ff40c12SJohn Marino 		}
1953ff40c12SJohn Marino 		return 0;
1963ff40c12SJohn Marino 	}
1973ff40c12SJohn Marino 	return 0;
1983ff40c12SJohn Marino }
1993ff40c12SJohn Marino 
2003ff40c12SJohn Marino 
wps_validate_primary_dev_type(const u8 * primary_dev_type,int mandatory)2013ff40c12SJohn Marino static int wps_validate_primary_dev_type(const u8 *primary_dev_type,
2023ff40c12SJohn Marino 					 int mandatory)
2033ff40c12SJohn Marino {
2043ff40c12SJohn Marino 	if (primary_dev_type == NULL) {
2053ff40c12SJohn Marino 		if (mandatory) {
2063ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Primary Device Type "
2073ff40c12SJohn Marino 				   "attribute missing");
2083ff40c12SJohn Marino 			return -1;
2093ff40c12SJohn Marino 		}
2103ff40c12SJohn Marino 		return 0;
2113ff40c12SJohn Marino 	}
2123ff40c12SJohn Marino 	return 0;
2133ff40c12SJohn Marino }
2143ff40c12SJohn Marino 
2153ff40c12SJohn Marino 
wps_validate_rf_bands(const u8 * rf_bands,int mandatory)2163ff40c12SJohn Marino static int wps_validate_rf_bands(const u8 *rf_bands, int mandatory)
2173ff40c12SJohn Marino {
2183ff40c12SJohn Marino 	if (rf_bands == NULL) {
2193ff40c12SJohn Marino 		if (mandatory) {
2203ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: RF Bands "
2213ff40c12SJohn Marino 				   "attribute missing");
2223ff40c12SJohn Marino 			return -1;
2233ff40c12SJohn Marino 		}
2243ff40c12SJohn Marino 		return 0;
2253ff40c12SJohn Marino 	}
2263ff40c12SJohn Marino 	if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
227*a1157835SDaniel Fojt 	    *rf_bands != WPS_RF_60GHZ &&
228*a1157835SDaniel Fojt 	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ | WPS_RF_60GHZ) &&
2293ff40c12SJohn Marino 	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
2303ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
2313ff40c12SJohn Marino 			   "attribute value 0x%x", *rf_bands);
2323ff40c12SJohn Marino 		return -1;
2333ff40c12SJohn Marino 	}
2343ff40c12SJohn Marino 	return 0;
2353ff40c12SJohn Marino }
2363ff40c12SJohn Marino 
2373ff40c12SJohn Marino 
wps_validate_assoc_state(const u8 * assoc_state,int mandatory)2383ff40c12SJohn Marino static int wps_validate_assoc_state(const u8 *assoc_state, int mandatory)
2393ff40c12SJohn Marino {
2403ff40c12SJohn Marino 	u16 val;
2413ff40c12SJohn Marino 	if (assoc_state == NULL) {
2423ff40c12SJohn Marino 		if (mandatory) {
2433ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Association State "
2443ff40c12SJohn Marino 				   "attribute missing");
2453ff40c12SJohn Marino 			return -1;
2463ff40c12SJohn Marino 		}
2473ff40c12SJohn Marino 		return 0;
2483ff40c12SJohn Marino 	}
2493ff40c12SJohn Marino 	val = WPA_GET_BE16(assoc_state);
2503ff40c12SJohn Marino 	if (val > 4) {
2513ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Association State "
2523ff40c12SJohn Marino 			   "attribute value 0x%04x", val);
2533ff40c12SJohn Marino 		return -1;
2543ff40c12SJohn Marino 	}
2553ff40c12SJohn Marino 	return 0;
2563ff40c12SJohn Marino }
2573ff40c12SJohn Marino 
2583ff40c12SJohn Marino 
wps_validate_config_error(const u8 * config_error,int mandatory)2593ff40c12SJohn Marino static int wps_validate_config_error(const u8 *config_error, int mandatory)
2603ff40c12SJohn Marino {
2613ff40c12SJohn Marino 	u16 val;
2623ff40c12SJohn Marino 
2633ff40c12SJohn Marino 	if (config_error == NULL) {
2643ff40c12SJohn Marino 		if (mandatory) {
2653ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration Error "
2663ff40c12SJohn Marino 				   "attribute missing");
2673ff40c12SJohn Marino 			return -1;
2683ff40c12SJohn Marino 		}
2693ff40c12SJohn Marino 		return 0;
2703ff40c12SJohn Marino 	}
2713ff40c12SJohn Marino 	val = WPA_GET_BE16(config_error);
2723ff40c12SJohn Marino 	if (val > 20) {
2733ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
2743ff40c12SJohn Marino 			   "attribute value 0x%04x", val);
2753ff40c12SJohn Marino 		return -1;
2763ff40c12SJohn Marino 	}
2773ff40c12SJohn Marino 	return 0;
2783ff40c12SJohn Marino }
2793ff40c12SJohn Marino 
2803ff40c12SJohn Marino 
wps_validate_dev_password_id(const u8 * dev_password_id,int mandatory)2813ff40c12SJohn Marino static int wps_validate_dev_password_id(const u8 *dev_password_id,
2823ff40c12SJohn Marino 					int mandatory)
2833ff40c12SJohn Marino {
2843ff40c12SJohn Marino 	u16 val;
2853ff40c12SJohn Marino 
2863ff40c12SJohn Marino 	if (dev_password_id == NULL) {
2873ff40c12SJohn Marino 		if (mandatory) {
2883ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Device Password ID "
2893ff40c12SJohn Marino 				   "attribute missing");
2903ff40c12SJohn Marino 			return -1;
2913ff40c12SJohn Marino 		}
2923ff40c12SJohn Marino 		return 0;
2933ff40c12SJohn Marino 	}
2943ff40c12SJohn Marino 	val = WPA_GET_BE16(dev_password_id);
2953ff40c12SJohn Marino 	if (val >= 0x0008 && val <= 0x000f) {
2963ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
2973ff40c12SJohn Marino 			   "attribute value 0x%04x", val);
2983ff40c12SJohn Marino 		return -1;
2993ff40c12SJohn Marino 	}
3003ff40c12SJohn Marino 	return 0;
3013ff40c12SJohn Marino }
3023ff40c12SJohn Marino 
3033ff40c12SJohn Marino 
wps_validate_manufacturer(const u8 * manufacturer,size_t len,int mandatory)3043ff40c12SJohn Marino static int wps_validate_manufacturer(const u8 *manufacturer, size_t len,
3053ff40c12SJohn Marino 				     int mandatory)
3063ff40c12SJohn Marino {
3073ff40c12SJohn Marino 	if (manufacturer == NULL) {
3083ff40c12SJohn Marino 		if (mandatory) {
3093ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Manufacturer "
3103ff40c12SJohn Marino 				   "attribute missing");
3113ff40c12SJohn Marino 			return -1;
3123ff40c12SJohn Marino 		}
3133ff40c12SJohn Marino 		return 0;
3143ff40c12SJohn Marino 	}
3153ff40c12SJohn Marino 	if (len > 0 && manufacturer[len - 1] == 0) {
3163ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Manufacturer "
3173ff40c12SJohn Marino 			   "attribute value", manufacturer, len);
3183ff40c12SJohn Marino 		return -1;
3193ff40c12SJohn Marino 	}
3203ff40c12SJohn Marino 	return 0;
3213ff40c12SJohn Marino }
3223ff40c12SJohn Marino 
3233ff40c12SJohn Marino 
wps_validate_model_name(const u8 * model_name,size_t len,int mandatory)3243ff40c12SJohn Marino static int wps_validate_model_name(const u8 *model_name, size_t len,
3253ff40c12SJohn Marino 				   int mandatory)
3263ff40c12SJohn Marino {
3273ff40c12SJohn Marino 	if (model_name == NULL) {
3283ff40c12SJohn Marino 		if (mandatory) {
3293ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Model Name "
3303ff40c12SJohn Marino 				   "attribute missing");
3313ff40c12SJohn Marino 			return -1;
3323ff40c12SJohn Marino 		}
3333ff40c12SJohn Marino 		return 0;
3343ff40c12SJohn Marino 	}
3353ff40c12SJohn Marino 	if (len > 0 && model_name[len - 1] == 0) {
3363ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Name "
3373ff40c12SJohn Marino 			   "attribute value", model_name, len);
3383ff40c12SJohn Marino 		return -1;
3393ff40c12SJohn Marino 	}
3403ff40c12SJohn Marino 	return 0;
3413ff40c12SJohn Marino }
3423ff40c12SJohn Marino 
3433ff40c12SJohn Marino 
wps_validate_model_number(const u8 * model_number,size_t len,int mandatory)3443ff40c12SJohn Marino static int wps_validate_model_number(const u8 *model_number, size_t len,
3453ff40c12SJohn Marino 				     int mandatory)
3463ff40c12SJohn Marino {
3473ff40c12SJohn Marino 	if (model_number == NULL) {
3483ff40c12SJohn Marino 		if (mandatory) {
3493ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Model Number "
3503ff40c12SJohn Marino 				   "attribute missing");
3513ff40c12SJohn Marino 			return -1;
3523ff40c12SJohn Marino 		}
3533ff40c12SJohn Marino 		return 0;
3543ff40c12SJohn Marino 	}
3553ff40c12SJohn Marino 	if (len > 0 && model_number[len - 1] == 0) {
3563ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Number "
3573ff40c12SJohn Marino 			   "attribute value", model_number, len);
3583ff40c12SJohn Marino 		return -1;
3593ff40c12SJohn Marino 	}
3603ff40c12SJohn Marino 	return 0;
3613ff40c12SJohn Marino }
3623ff40c12SJohn Marino 
3633ff40c12SJohn Marino 
wps_validate_serial_number(const u8 * serial_number,size_t len,int mandatory)3643ff40c12SJohn Marino static int wps_validate_serial_number(const u8 *serial_number, size_t len,
3653ff40c12SJohn Marino 				      int mandatory)
3663ff40c12SJohn Marino {
3673ff40c12SJohn Marino 	if (serial_number == NULL) {
3683ff40c12SJohn Marino 		if (mandatory) {
3693ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Serial Number "
3703ff40c12SJohn Marino 				   "attribute missing");
3713ff40c12SJohn Marino 			return -1;
3723ff40c12SJohn Marino 		}
3733ff40c12SJohn Marino 		return 0;
3743ff40c12SJohn Marino 	}
3753ff40c12SJohn Marino 	if (len > 0 && serial_number[len - 1] == 0) {
3763ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Serial "
3773ff40c12SJohn Marino 				  "Number attribute value",
3783ff40c12SJohn Marino 				  serial_number, len);
3793ff40c12SJohn Marino 		return -1;
3803ff40c12SJohn Marino 	}
3813ff40c12SJohn Marino 	return 0;
3823ff40c12SJohn Marino }
3833ff40c12SJohn Marino 
3843ff40c12SJohn Marino 
wps_validate_dev_name(const u8 * dev_name,size_t len,int mandatory)3853ff40c12SJohn Marino static int wps_validate_dev_name(const u8 *dev_name, size_t len,
3863ff40c12SJohn Marino 				 int mandatory)
3873ff40c12SJohn Marino {
3883ff40c12SJohn Marino 	if (dev_name == NULL) {
3893ff40c12SJohn Marino 		if (mandatory) {
3903ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Device Name "
3913ff40c12SJohn Marino 				   "attribute missing");
3923ff40c12SJohn Marino 			return -1;
3933ff40c12SJohn Marino 		}
3943ff40c12SJohn Marino 		return 0;
3953ff40c12SJohn Marino 	}
3963ff40c12SJohn Marino 	if (len > 0 && dev_name[len - 1] == 0) {
3973ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Device Name "
3983ff40c12SJohn Marino 			   "attribute value", dev_name, len);
3993ff40c12SJohn Marino 		return -1;
4003ff40c12SJohn Marino 	}
4013ff40c12SJohn Marino 	return 0;
4023ff40c12SJohn Marino }
4033ff40c12SJohn Marino 
4043ff40c12SJohn Marino 
wps_validate_request_to_enroll(const u8 * request_to_enroll,int mandatory)4053ff40c12SJohn Marino static int wps_validate_request_to_enroll(const u8 *request_to_enroll,
4063ff40c12SJohn Marino 					  int mandatory)
4073ff40c12SJohn Marino {
4083ff40c12SJohn Marino 	if (request_to_enroll == NULL) {
4093ff40c12SJohn Marino 		if (mandatory) {
4103ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Request to Enroll "
4113ff40c12SJohn Marino 				   "attribute missing");
4123ff40c12SJohn Marino 			return -1;
4133ff40c12SJohn Marino 		}
4143ff40c12SJohn Marino 		return 0;
4153ff40c12SJohn Marino 	}
4163ff40c12SJohn Marino 	if (*request_to_enroll > 0x01) {
4173ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request to Enroll "
4183ff40c12SJohn Marino 			   "attribute value 0x%x", *request_to_enroll);
4193ff40c12SJohn Marino 		return -1;
4203ff40c12SJohn Marino 	}
4213ff40c12SJohn Marino 	return 0;
4223ff40c12SJohn Marino }
4233ff40c12SJohn Marino 
4243ff40c12SJohn Marino 
wps_validate_req_dev_type(const u8 * req_dev_type[],size_t num,int mandatory)4253ff40c12SJohn Marino static int wps_validate_req_dev_type(const u8 *req_dev_type[], size_t num,
4263ff40c12SJohn Marino 				     int mandatory)
4273ff40c12SJohn Marino {
4283ff40c12SJohn Marino 	if (num == 0) {
4293ff40c12SJohn Marino 		if (mandatory) {
4303ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Requested Device "
4313ff40c12SJohn Marino 				   "Type attribute missing");
4323ff40c12SJohn Marino 			return -1;
4333ff40c12SJohn Marino 		}
4343ff40c12SJohn Marino 		return 0;
4353ff40c12SJohn Marino 	}
4363ff40c12SJohn Marino 	return 0;
4373ff40c12SJohn Marino }
4383ff40c12SJohn Marino 
4393ff40c12SJohn Marino 
wps_validate_wps_state(const u8 * wps_state,int mandatory)4403ff40c12SJohn Marino static int wps_validate_wps_state(const u8 *wps_state, int mandatory)
4413ff40c12SJohn Marino {
4423ff40c12SJohn Marino 	if (wps_state == NULL) {
4433ff40c12SJohn Marino 		if (mandatory) {
4443ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Wi-Fi Protected "
4453ff40c12SJohn Marino 				   "Setup State attribute missing");
4463ff40c12SJohn Marino 			return -1;
4473ff40c12SJohn Marino 		}
4483ff40c12SJohn Marino 		return 0;
4493ff40c12SJohn Marino 	}
4503ff40c12SJohn Marino 	if (*wps_state != WPS_STATE_NOT_CONFIGURED &&
4513ff40c12SJohn Marino 	    *wps_state != WPS_STATE_CONFIGURED) {
4523ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Wi-Fi Protected "
4533ff40c12SJohn Marino 			   "Setup State attribute value 0x%x", *wps_state);
4543ff40c12SJohn Marino 		return -1;
4553ff40c12SJohn Marino 	}
4563ff40c12SJohn Marino 	return 0;
4573ff40c12SJohn Marino }
4583ff40c12SJohn Marino 
4593ff40c12SJohn Marino 
wps_validate_ap_setup_locked(const u8 * ap_setup_locked,int mandatory)4603ff40c12SJohn Marino static int wps_validate_ap_setup_locked(const u8 *ap_setup_locked,
4613ff40c12SJohn Marino 					int mandatory)
4623ff40c12SJohn Marino {
4633ff40c12SJohn Marino 	if (ap_setup_locked == NULL) {
4643ff40c12SJohn Marino 		if (mandatory) {
4653ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: AP Setup Locked "
4663ff40c12SJohn Marino 				   "attribute missing");
4673ff40c12SJohn Marino 			return -1;
4683ff40c12SJohn Marino 		}
4693ff40c12SJohn Marino 		return 0;
4703ff40c12SJohn Marino 	}
4713ff40c12SJohn Marino 	if (*ap_setup_locked > 1) {
4723ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid AP Setup Locked "
4733ff40c12SJohn Marino 			   "attribute value 0x%x", *ap_setup_locked);
4743ff40c12SJohn Marino 		return -1;
4753ff40c12SJohn Marino 	}
4763ff40c12SJohn Marino 	return 0;
4773ff40c12SJohn Marino }
4783ff40c12SJohn Marino 
4793ff40c12SJohn Marino 
wps_validate_selected_registrar(const u8 * selected_registrar,int mandatory)4803ff40c12SJohn Marino static int wps_validate_selected_registrar(const u8 *selected_registrar,
4813ff40c12SJohn Marino 					   int mandatory)
4823ff40c12SJohn Marino {
4833ff40c12SJohn Marino 	if (selected_registrar == NULL) {
4843ff40c12SJohn Marino 		if (mandatory) {
4853ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
4863ff40c12SJohn Marino 				   "attribute missing");
4873ff40c12SJohn Marino 			return -1;
4883ff40c12SJohn Marino 		}
4893ff40c12SJohn Marino 		return 0;
4903ff40c12SJohn Marino 	}
4913ff40c12SJohn Marino 	if (*selected_registrar > 1) {
4923ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
4933ff40c12SJohn Marino 			   "attribute value 0x%x", *selected_registrar);
4943ff40c12SJohn Marino 		return -1;
4953ff40c12SJohn Marino 	}
4963ff40c12SJohn Marino 	return 0;
4973ff40c12SJohn Marino }
4983ff40c12SJohn Marino 
4993ff40c12SJohn Marino 
wps_validate_sel_reg_config_methods(const u8 * config_methods,int wps2,int mandatory)5003ff40c12SJohn Marino static int wps_validate_sel_reg_config_methods(const u8 *config_methods,
5013ff40c12SJohn Marino 					       int wps2, int mandatory)
5023ff40c12SJohn Marino {
5033ff40c12SJohn Marino 	u16 val;
5043ff40c12SJohn Marino 
5053ff40c12SJohn Marino 	if (config_methods == NULL) {
5063ff40c12SJohn Marino 		if (mandatory) {
5073ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
5083ff40c12SJohn Marino 				   "Configuration Methods attribute missing");
5093ff40c12SJohn Marino 			return -1;
5103ff40c12SJohn Marino 		}
5113ff40c12SJohn Marino 		return 0;
5123ff40c12SJohn Marino 	}
5133ff40c12SJohn Marino 
5143ff40c12SJohn Marino 	val = WPA_GET_BE16(config_methods);
5153ff40c12SJohn Marino 	if (!valid_config_methods(val, wps2)) {
5163ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
5173ff40c12SJohn Marino 			   "Configuration Methods attribute value 0x%04x",
5183ff40c12SJohn Marino 			   val);
5193ff40c12SJohn Marino 		return -1;
5203ff40c12SJohn Marino 	}
5213ff40c12SJohn Marino 	return 0;
5223ff40c12SJohn Marino }
5233ff40c12SJohn Marino 
5243ff40c12SJohn Marino 
wps_validate_authorized_macs(const u8 * authorized_macs,size_t len,int mandatory)5253ff40c12SJohn Marino static int wps_validate_authorized_macs(const u8 *authorized_macs, size_t len,
5263ff40c12SJohn Marino 					int mandatory)
5273ff40c12SJohn Marino {
5283ff40c12SJohn Marino 	if (authorized_macs == NULL) {
5293ff40c12SJohn Marino 		if (mandatory) {
5303ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Authorized MACs "
5313ff40c12SJohn Marino 				   "attribute missing");
5323ff40c12SJohn Marino 			return -1;
5333ff40c12SJohn Marino 		}
5343ff40c12SJohn Marino 		return 0;
5353ff40c12SJohn Marino 	}
5363ff40c12SJohn Marino 	if (len > 30 && (len % ETH_ALEN) != 0) {
5373ff40c12SJohn Marino 		wpa_hexdump(MSG_INFO, "WPS-STRICT: Invalid Authorized "
5383ff40c12SJohn Marino 			    "MACs attribute value", authorized_macs, len);
5393ff40c12SJohn Marino 		return -1;
5403ff40c12SJohn Marino 	}
5413ff40c12SJohn Marino 	return 0;
5423ff40c12SJohn Marino }
5433ff40c12SJohn Marino 
5443ff40c12SJohn Marino 
wps_validate_msg_type(const u8 * msg_type,int mandatory)5453ff40c12SJohn Marino static int wps_validate_msg_type(const u8 *msg_type, int mandatory)
5463ff40c12SJohn Marino {
5473ff40c12SJohn Marino 	if (msg_type == NULL) {
5483ff40c12SJohn Marino 		if (mandatory) {
5493ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Message Type "
5503ff40c12SJohn Marino 				   "attribute missing");
5513ff40c12SJohn Marino 			return -1;
5523ff40c12SJohn Marino 		}
5533ff40c12SJohn Marino 		return 0;
5543ff40c12SJohn Marino 	}
5553ff40c12SJohn Marino 	if (*msg_type < WPS_Beacon || *msg_type > WPS_WSC_DONE) {
5563ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Message Type "
5573ff40c12SJohn Marino 			   "attribute value 0x%x", *msg_type);
5583ff40c12SJohn Marino 		return -1;
5593ff40c12SJohn Marino 	}
5603ff40c12SJohn Marino 	return 0;
5613ff40c12SJohn Marino }
5623ff40c12SJohn Marino 
5633ff40c12SJohn Marino 
wps_validate_mac_addr(const u8 * mac_addr,int mandatory)5643ff40c12SJohn Marino static int wps_validate_mac_addr(const u8 *mac_addr, int mandatory)
5653ff40c12SJohn Marino {
5663ff40c12SJohn Marino 	if (mac_addr == NULL) {
5673ff40c12SJohn Marino 		if (mandatory) {
5683ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: MAC Address "
5693ff40c12SJohn Marino 				   "attribute missing");
5703ff40c12SJohn Marino 			return -1;
5713ff40c12SJohn Marino 		}
5723ff40c12SJohn Marino 		return 0;
5733ff40c12SJohn Marino 	}
5743ff40c12SJohn Marino 	if (mac_addr[0] & 0x01) {
5753ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid MAC Address "
5763ff40c12SJohn Marino 			   "attribute value " MACSTR, MAC2STR(mac_addr));
5773ff40c12SJohn Marino 		return -1;
5783ff40c12SJohn Marino 	}
5793ff40c12SJohn Marino 	return 0;
5803ff40c12SJohn Marino }
5813ff40c12SJohn Marino 
5823ff40c12SJohn Marino 
wps_validate_enrollee_nonce(const u8 * enrollee_nonce,int mandatory)5833ff40c12SJohn Marino static int wps_validate_enrollee_nonce(const u8 *enrollee_nonce, int mandatory)
5843ff40c12SJohn Marino {
5853ff40c12SJohn Marino 	if (enrollee_nonce == NULL) {
5863ff40c12SJohn Marino 		if (mandatory) {
5873ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Enrollee Nonce "
5883ff40c12SJohn Marino 				   "attribute missing");
5893ff40c12SJohn Marino 			return -1;
5903ff40c12SJohn Marino 		}
5913ff40c12SJohn Marino 		return 0;
5923ff40c12SJohn Marino 	}
5933ff40c12SJohn Marino 	return 0;
5943ff40c12SJohn Marino }
5953ff40c12SJohn Marino 
5963ff40c12SJohn Marino 
wps_validate_registrar_nonce(const u8 * registrar_nonce,int mandatory)5973ff40c12SJohn Marino static int wps_validate_registrar_nonce(const u8 *registrar_nonce,
5983ff40c12SJohn Marino 					int mandatory)
5993ff40c12SJohn Marino {
6003ff40c12SJohn Marino 	if (registrar_nonce == NULL) {
6013ff40c12SJohn Marino 		if (mandatory) {
6023ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Registrar Nonce "
6033ff40c12SJohn Marino 				   "attribute missing");
6043ff40c12SJohn Marino 			return -1;
6053ff40c12SJohn Marino 		}
6063ff40c12SJohn Marino 		return 0;
6073ff40c12SJohn Marino 	}
6083ff40c12SJohn Marino 	return 0;
6093ff40c12SJohn Marino }
6103ff40c12SJohn Marino 
6113ff40c12SJohn Marino 
wps_validate_public_key(const u8 * public_key,size_t len,int mandatory)6123ff40c12SJohn Marino static int wps_validate_public_key(const u8 *public_key, size_t len,
6133ff40c12SJohn Marino 				   int mandatory)
6143ff40c12SJohn Marino {
6153ff40c12SJohn Marino 	if (public_key == NULL) {
6163ff40c12SJohn Marino 		if (mandatory) {
6173ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Public Key "
6183ff40c12SJohn Marino 				   "attribute missing");
6193ff40c12SJohn Marino 			return -1;
6203ff40c12SJohn Marino 		}
6213ff40c12SJohn Marino 		return 0;
6223ff40c12SJohn Marino 	}
6233ff40c12SJohn Marino 	if (len != 192) {
6243ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Public Key "
6253ff40c12SJohn Marino 			   "attribute length %d", (int) len);
6263ff40c12SJohn Marino 		return -1;
6273ff40c12SJohn Marino 	}
6283ff40c12SJohn Marino 	return 0;
6293ff40c12SJohn Marino }
6303ff40c12SJohn Marino 
6313ff40c12SJohn Marino 
num_bits_set(u16 val)6323ff40c12SJohn Marino static int num_bits_set(u16 val)
6333ff40c12SJohn Marino {
6343ff40c12SJohn Marino 	int c;
6353ff40c12SJohn Marino 	for (c = 0; val; c++)
6363ff40c12SJohn Marino 		val &= val - 1;
6373ff40c12SJohn Marino 	return c;
6383ff40c12SJohn Marino }
6393ff40c12SJohn Marino 
6403ff40c12SJohn Marino 
wps_validate_auth_type_flags(const u8 * flags,int mandatory)6413ff40c12SJohn Marino static int wps_validate_auth_type_flags(const u8 *flags, int mandatory)
6423ff40c12SJohn Marino {
6433ff40c12SJohn Marino 	u16 val;
6443ff40c12SJohn Marino 
6453ff40c12SJohn Marino 	if (flags == NULL) {
6463ff40c12SJohn Marino 		if (mandatory) {
6473ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
6483ff40c12SJohn Marino 				   "Flags attribute missing");
6493ff40c12SJohn Marino 			return -1;
6503ff40c12SJohn Marino 		}
6513ff40c12SJohn Marino 		return 0;
6523ff40c12SJohn Marino 	}
6533ff40c12SJohn Marino 	val = WPA_GET_BE16(flags);
6543ff40c12SJohn Marino 	if ((val & ~WPS_AUTH_TYPES) || !(val & WPS_AUTH_WPA2PSK)) {
6553ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
6563ff40c12SJohn Marino 			   "Flags attribute value 0x%04x", val);
6573ff40c12SJohn Marino 		return -1;
6583ff40c12SJohn Marino 	}
6593ff40c12SJohn Marino 	return 0;
6603ff40c12SJohn Marino }
6613ff40c12SJohn Marino 
6623ff40c12SJohn Marino 
wps_validate_auth_type(const u8 * type,int mandatory)6633ff40c12SJohn Marino static int wps_validate_auth_type(const u8 *type, int mandatory)
6643ff40c12SJohn Marino {
6653ff40c12SJohn Marino 	u16 val;
6663ff40c12SJohn Marino 
6673ff40c12SJohn Marino 	if (type == NULL) {
6683ff40c12SJohn Marino 		if (mandatory) {
6693ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
6703ff40c12SJohn Marino 				   "attribute missing");
6713ff40c12SJohn Marino 			return -1;
6723ff40c12SJohn Marino 		}
6733ff40c12SJohn Marino 		return 0;
6743ff40c12SJohn Marino 	}
6753ff40c12SJohn Marino 	val = WPA_GET_BE16(type);
6763ff40c12SJohn Marino 	if ((val & ~WPS_AUTH_TYPES) || val == 0 ||
6773ff40c12SJohn Marino 	    (num_bits_set(val) > 1 &&
6783ff40c12SJohn Marino 	     val != (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK))) {
6793ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
6803ff40c12SJohn Marino 			   "attribute value 0x%04x", val);
6813ff40c12SJohn Marino 		return -1;
6823ff40c12SJohn Marino 	}
6833ff40c12SJohn Marino 	return 0;
6843ff40c12SJohn Marino }
6853ff40c12SJohn Marino 
6863ff40c12SJohn Marino 
wps_validate_encr_type_flags(const u8 * flags,int mandatory)6873ff40c12SJohn Marino static int wps_validate_encr_type_flags(const u8 *flags, int mandatory)
6883ff40c12SJohn Marino {
6893ff40c12SJohn Marino 	u16 val;
6903ff40c12SJohn Marino 
6913ff40c12SJohn Marino 	if (flags == NULL) {
6923ff40c12SJohn Marino 		if (mandatory) {
6933ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
6943ff40c12SJohn Marino 				   "Flags attribute missing");
6953ff40c12SJohn Marino 			return -1;
6963ff40c12SJohn Marino 		}
6973ff40c12SJohn Marino 		return 0;
6983ff40c12SJohn Marino 	}
6993ff40c12SJohn Marino 	val = WPA_GET_BE16(flags);
7003ff40c12SJohn Marino 	if ((val & ~WPS_ENCR_TYPES) || !(val & WPS_ENCR_AES)) {
7013ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
7023ff40c12SJohn Marino 			   "Flags attribute value 0x%04x", val);
7033ff40c12SJohn Marino 		return -1;
7043ff40c12SJohn Marino 	}
7053ff40c12SJohn Marino 	return 0;
7063ff40c12SJohn Marino }
7073ff40c12SJohn Marino 
7083ff40c12SJohn Marino 
wps_validate_encr_type(const u8 * type,int mandatory)7093ff40c12SJohn Marino static int wps_validate_encr_type(const u8 *type, int mandatory)
7103ff40c12SJohn Marino {
7113ff40c12SJohn Marino 	u16 val;
7123ff40c12SJohn Marino 
7133ff40c12SJohn Marino 	if (type == NULL) {
7143ff40c12SJohn Marino 		if (mandatory) {
7153ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
7163ff40c12SJohn Marino 				   "attribute missing");
7173ff40c12SJohn Marino 			return -1;
7183ff40c12SJohn Marino 		}
7193ff40c12SJohn Marino 		return 0;
7203ff40c12SJohn Marino 	}
7213ff40c12SJohn Marino 	val = WPA_GET_BE16(type);
7223ff40c12SJohn Marino 	if ((val & ~WPS_ENCR_TYPES) || val == 0 ||
7233ff40c12SJohn Marino 	    (num_bits_set(val) > 1 && val != (WPS_ENCR_TKIP | WPS_ENCR_AES))) {
7243ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
7253ff40c12SJohn Marino 			   "attribute value 0x%04x", val);
7263ff40c12SJohn Marino 		return -1;
7273ff40c12SJohn Marino 	}
7283ff40c12SJohn Marino 	return 0;
7293ff40c12SJohn Marino }
7303ff40c12SJohn Marino 
7313ff40c12SJohn Marino 
wps_validate_conn_type_flags(const u8 * flags,int mandatory)7323ff40c12SJohn Marino static int wps_validate_conn_type_flags(const u8 *flags, int mandatory)
7333ff40c12SJohn Marino {
7343ff40c12SJohn Marino 	if (flags == NULL) {
7353ff40c12SJohn Marino 		if (mandatory) {
7363ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Connection Type "
7373ff40c12SJohn Marino 				   "Flags attribute missing");
7383ff40c12SJohn Marino 			return -1;
7393ff40c12SJohn Marino 		}
7403ff40c12SJohn Marino 		return 0;
7413ff40c12SJohn Marino 	}
7423ff40c12SJohn Marino 	if ((*flags & ~(WPS_CONN_ESS | WPS_CONN_IBSS)) ||
7433ff40c12SJohn Marino 	    !(*flags & WPS_CONN_ESS)) {
7443ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Connection Type "
7453ff40c12SJohn Marino 			   "Flags attribute value 0x%02x", *flags);
7463ff40c12SJohn Marino 		return -1;
7473ff40c12SJohn Marino 	}
7483ff40c12SJohn Marino 	return 0;
7493ff40c12SJohn Marino }
7503ff40c12SJohn Marino 
7513ff40c12SJohn Marino 
wps_validate_os_version(const u8 * os_version,int mandatory)7523ff40c12SJohn Marino static int wps_validate_os_version(const u8 *os_version, int mandatory)
7533ff40c12SJohn Marino {
7543ff40c12SJohn Marino 	if (os_version == NULL) {
7553ff40c12SJohn Marino 		if (mandatory) {
7563ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: OS Version "
7573ff40c12SJohn Marino 				   "attribute missing");
7583ff40c12SJohn Marino 			return -1;
7593ff40c12SJohn Marino 		}
7603ff40c12SJohn Marino 		return 0;
7613ff40c12SJohn Marino 	}
7623ff40c12SJohn Marino 	return 0;
7633ff40c12SJohn Marino }
7643ff40c12SJohn Marino 
7653ff40c12SJohn Marino 
wps_validate_authenticator(const u8 * authenticator,int mandatory)7663ff40c12SJohn Marino static int wps_validate_authenticator(const u8 *authenticator, int mandatory)
7673ff40c12SJohn Marino {
7683ff40c12SJohn Marino 	if (authenticator == NULL) {
7693ff40c12SJohn Marino 		if (mandatory) {
7703ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Authenticator "
7713ff40c12SJohn Marino 				   "attribute missing");
7723ff40c12SJohn Marino 			return -1;
7733ff40c12SJohn Marino 		}
7743ff40c12SJohn Marino 		return 0;
7753ff40c12SJohn Marino 	}
7763ff40c12SJohn Marino 	return 0;
7773ff40c12SJohn Marino }
7783ff40c12SJohn Marino 
7793ff40c12SJohn Marino 
wps_validate_e_hash1(const u8 * hash,int mandatory)7803ff40c12SJohn Marino static int wps_validate_e_hash1(const u8 *hash, int mandatory)
7813ff40c12SJohn Marino {
7823ff40c12SJohn Marino 	if (hash == NULL) {
7833ff40c12SJohn Marino 		if (mandatory) {
7843ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash1 "
7853ff40c12SJohn Marino 				   "attribute missing");
7863ff40c12SJohn Marino 			return -1;
7873ff40c12SJohn Marino 		}
7883ff40c12SJohn Marino 		return 0;
7893ff40c12SJohn Marino 	}
7903ff40c12SJohn Marino 	return 0;
7913ff40c12SJohn Marino }
7923ff40c12SJohn Marino 
7933ff40c12SJohn Marino 
wps_validate_e_hash2(const u8 * hash,int mandatory)7943ff40c12SJohn Marino static int wps_validate_e_hash2(const u8 *hash, int mandatory)
7953ff40c12SJohn Marino {
7963ff40c12SJohn Marino 	if (hash == NULL) {
7973ff40c12SJohn Marino 		if (mandatory) {
7983ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash2 "
7993ff40c12SJohn Marino 				   "attribute missing");
8003ff40c12SJohn Marino 			return -1;
8013ff40c12SJohn Marino 		}
8023ff40c12SJohn Marino 		return 0;
8033ff40c12SJohn Marino 	}
8043ff40c12SJohn Marino 	return 0;
8053ff40c12SJohn Marino }
8063ff40c12SJohn Marino 
8073ff40c12SJohn Marino 
wps_validate_r_hash1(const u8 * hash,int mandatory)8083ff40c12SJohn Marino static int wps_validate_r_hash1(const u8 *hash, int mandatory)
8093ff40c12SJohn Marino {
8103ff40c12SJohn Marino 	if (hash == NULL) {
8113ff40c12SJohn Marino 		if (mandatory) {
8123ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash1 "
8133ff40c12SJohn Marino 				   "attribute missing");
8143ff40c12SJohn Marino 			return -1;
8153ff40c12SJohn Marino 		}
8163ff40c12SJohn Marino 		return 0;
8173ff40c12SJohn Marino 	}
8183ff40c12SJohn Marino 	return 0;
8193ff40c12SJohn Marino }
8203ff40c12SJohn Marino 
8213ff40c12SJohn Marino 
wps_validate_r_hash2(const u8 * hash,int mandatory)8223ff40c12SJohn Marino static int wps_validate_r_hash2(const u8 *hash, int mandatory)
8233ff40c12SJohn Marino {
8243ff40c12SJohn Marino 	if (hash == NULL) {
8253ff40c12SJohn Marino 		if (mandatory) {
8263ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash2 "
8273ff40c12SJohn Marino 				   "attribute missing");
8283ff40c12SJohn Marino 			return -1;
8293ff40c12SJohn Marino 		}
8303ff40c12SJohn Marino 		return 0;
8313ff40c12SJohn Marino 	}
8323ff40c12SJohn Marino 	return 0;
8333ff40c12SJohn Marino }
8343ff40c12SJohn Marino 
8353ff40c12SJohn Marino 
wps_validate_encr_settings(const u8 * encr_settings,size_t len,int mandatory)8363ff40c12SJohn Marino static int wps_validate_encr_settings(const u8 *encr_settings, size_t len,
8373ff40c12SJohn Marino 				   int mandatory)
8383ff40c12SJohn Marino {
8393ff40c12SJohn Marino 	if (encr_settings == NULL) {
8403ff40c12SJohn Marino 		if (mandatory) {
8413ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Encrypted Settings "
8423ff40c12SJohn Marino 				   "attribute missing");
8433ff40c12SJohn Marino 			return -1;
8443ff40c12SJohn Marino 		}
8453ff40c12SJohn Marino 		return 0;
8463ff40c12SJohn Marino 	}
8473ff40c12SJohn Marino 	if (len < 16) {
8483ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encrypted Settings "
8493ff40c12SJohn Marino 			   "attribute length %d", (int) len);
8503ff40c12SJohn Marino 		return -1;
8513ff40c12SJohn Marino 	}
8523ff40c12SJohn Marino 	return 0;
8533ff40c12SJohn Marino }
8543ff40c12SJohn Marino 
8553ff40c12SJohn Marino 
wps_validate_settings_delay_time(const u8 * delay,int mandatory)8563ff40c12SJohn Marino static int wps_validate_settings_delay_time(const u8 *delay, int mandatory)
8573ff40c12SJohn Marino {
8583ff40c12SJohn Marino 	if (delay == NULL) {
8593ff40c12SJohn Marino 		if (mandatory) {
8603ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Settings Delay Time "
8613ff40c12SJohn Marino 				   "attribute missing");
8623ff40c12SJohn Marino 			return -1;
8633ff40c12SJohn Marino 		}
8643ff40c12SJohn Marino 		return 0;
8653ff40c12SJohn Marino 	}
8663ff40c12SJohn Marino 	return 0;
8673ff40c12SJohn Marino }
8683ff40c12SJohn Marino 
8693ff40c12SJohn Marino 
wps_validate_r_snonce1(const u8 * nonce,int mandatory)8703ff40c12SJohn Marino static int wps_validate_r_snonce1(const u8 *nonce, int mandatory)
8713ff40c12SJohn Marino {
8723ff40c12SJohn Marino 	if (nonce == NULL) {
8733ff40c12SJohn Marino 		if (mandatory) {
8743ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce1 "
8753ff40c12SJohn Marino 				   "attribute missing");
8763ff40c12SJohn Marino 			return -1;
8773ff40c12SJohn Marino 		}
8783ff40c12SJohn Marino 		return 0;
8793ff40c12SJohn Marino 	}
8803ff40c12SJohn Marino 	return 0;
8813ff40c12SJohn Marino }
8823ff40c12SJohn Marino 
8833ff40c12SJohn Marino 
wps_validate_r_snonce2(const u8 * nonce,int mandatory)8843ff40c12SJohn Marino static int wps_validate_r_snonce2(const u8 *nonce, int mandatory)
8853ff40c12SJohn Marino {
8863ff40c12SJohn Marino 	if (nonce == NULL) {
8873ff40c12SJohn Marino 		if (mandatory) {
8883ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce2 "
8893ff40c12SJohn Marino 				   "attribute missing");
8903ff40c12SJohn Marino 			return -1;
8913ff40c12SJohn Marino 		}
8923ff40c12SJohn Marino 		return 0;
8933ff40c12SJohn Marino 	}
8943ff40c12SJohn Marino 	return 0;
8953ff40c12SJohn Marino }
8963ff40c12SJohn Marino 
8973ff40c12SJohn Marino 
wps_validate_e_snonce1(const u8 * nonce,int mandatory)8983ff40c12SJohn Marino static int wps_validate_e_snonce1(const u8 *nonce, int mandatory)
8993ff40c12SJohn Marino {
9003ff40c12SJohn Marino 	if (nonce == NULL) {
9013ff40c12SJohn Marino 		if (mandatory) {
9023ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce1 "
9033ff40c12SJohn Marino 				   "attribute missing");
9043ff40c12SJohn Marino 			return -1;
9053ff40c12SJohn Marino 		}
9063ff40c12SJohn Marino 		return 0;
9073ff40c12SJohn Marino 	}
9083ff40c12SJohn Marino 	return 0;
9093ff40c12SJohn Marino }
9103ff40c12SJohn Marino 
9113ff40c12SJohn Marino 
wps_validate_e_snonce2(const u8 * nonce,int mandatory)9123ff40c12SJohn Marino static int wps_validate_e_snonce2(const u8 *nonce, int mandatory)
9133ff40c12SJohn Marino {
9143ff40c12SJohn Marino 	if (nonce == NULL) {
9153ff40c12SJohn Marino 		if (mandatory) {
9163ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce2 "
9173ff40c12SJohn Marino 				   "attribute missing");
9183ff40c12SJohn Marino 			return -1;
9193ff40c12SJohn Marino 		}
9203ff40c12SJohn Marino 		return 0;
9213ff40c12SJohn Marino 	}
9223ff40c12SJohn Marino 	return 0;
9233ff40c12SJohn Marino }
9243ff40c12SJohn Marino 
9253ff40c12SJohn Marino 
wps_validate_key_wrap_auth(const u8 * auth,int mandatory)9263ff40c12SJohn Marino static int wps_validate_key_wrap_auth(const u8 *auth, int mandatory)
9273ff40c12SJohn Marino {
9283ff40c12SJohn Marino 	if (auth == NULL) {
9293ff40c12SJohn Marino 		if (mandatory) {
9303ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Key Wrap "
9313ff40c12SJohn Marino 				   "Authenticator attribute missing");
9323ff40c12SJohn Marino 			return -1;
9333ff40c12SJohn Marino 		}
9343ff40c12SJohn Marino 		return 0;
9353ff40c12SJohn Marino 	}
9363ff40c12SJohn Marino 	return 0;
9373ff40c12SJohn Marino }
9383ff40c12SJohn Marino 
9393ff40c12SJohn Marino 
wps_validate_ssid(const u8 * ssid,size_t ssid_len,int mandatory)9403ff40c12SJohn Marino static int wps_validate_ssid(const u8 *ssid, size_t ssid_len, int mandatory)
9413ff40c12SJohn Marino {
9423ff40c12SJohn Marino 	if (ssid == NULL) {
9433ff40c12SJohn Marino 		if (mandatory) {
9443ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: SSID "
9453ff40c12SJohn Marino 				   "attribute missing");
9463ff40c12SJohn Marino 			return -1;
9473ff40c12SJohn Marino 		}
9483ff40c12SJohn Marino 		return 0;
9493ff40c12SJohn Marino 	}
9503ff40c12SJohn Marino 	if (ssid_len == 0 || ssid[ssid_len - 1] == 0) {
9513ff40c12SJohn Marino 		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid SSID "
9523ff40c12SJohn Marino 				  "attribute value", ssid, ssid_len);
9533ff40c12SJohn Marino 		return -1;
9543ff40c12SJohn Marino 	}
9553ff40c12SJohn Marino 	return 0;
9563ff40c12SJohn Marino }
9573ff40c12SJohn Marino 
9583ff40c12SJohn Marino 
wps_validate_network_key_index(const u8 * idx,int mandatory)9593ff40c12SJohn Marino static int wps_validate_network_key_index(const u8 *idx, int mandatory)
9603ff40c12SJohn Marino {
9613ff40c12SJohn Marino 	if (idx == NULL) {
9623ff40c12SJohn Marino 		if (mandatory) {
9633ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key Index "
9643ff40c12SJohn Marino 				   "attribute missing");
9653ff40c12SJohn Marino 			return -1;
9663ff40c12SJohn Marino 		}
9673ff40c12SJohn Marino 		return 0;
9683ff40c12SJohn Marino 	}
9693ff40c12SJohn Marino 	return 0;
9703ff40c12SJohn Marino }
9713ff40c12SJohn Marino 
9723ff40c12SJohn Marino 
wps_validate_network_idx(const u8 * idx,int mandatory)9733ff40c12SJohn Marino static int wps_validate_network_idx(const u8 *idx, int mandatory)
9743ff40c12SJohn Marino {
9753ff40c12SJohn Marino 	if (idx == NULL) {
9763ff40c12SJohn Marino 		if (mandatory) {
9773ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Index "
9783ff40c12SJohn Marino 				   "attribute missing");
9793ff40c12SJohn Marino 			return -1;
9803ff40c12SJohn Marino 		}
9813ff40c12SJohn Marino 		return 0;
9823ff40c12SJohn Marino 	}
9833ff40c12SJohn Marino 	return 0;
9843ff40c12SJohn Marino }
9853ff40c12SJohn Marino 
9863ff40c12SJohn Marino 
wps_validate_network_key(const u8 * key,size_t key_len,const u8 * encr_type,int mandatory)9873ff40c12SJohn Marino static int wps_validate_network_key(const u8 *key, size_t key_len,
9883ff40c12SJohn Marino 				    const u8 *encr_type, int mandatory)
9893ff40c12SJohn Marino {
9903ff40c12SJohn Marino 	if (key == NULL) {
9913ff40c12SJohn Marino 		if (mandatory) {
9923ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
9933ff40c12SJohn Marino 				   "attribute missing");
9943ff40c12SJohn Marino 			return -1;
9953ff40c12SJohn Marino 		}
9963ff40c12SJohn Marino 		return 0;
9973ff40c12SJohn Marino 	}
9983ff40c12SJohn Marino 	if (((encr_type == NULL || WPA_GET_BE16(encr_type) != WPS_ENCR_WEP) &&
9993ff40c12SJohn Marino 	     key_len > 8 && key_len < 64 && key[key_len - 1] == 0) ||
10003ff40c12SJohn Marino 	    key_len > 64) {
10013ff40c12SJohn Marino 		wpa_hexdump_ascii_key(MSG_INFO, "WPS-STRICT: Invalid Network "
10023ff40c12SJohn Marino 				      "Key attribute value", key, key_len);
10033ff40c12SJohn Marino 		return -1;
10043ff40c12SJohn Marino 	}
10053ff40c12SJohn Marino 	return 0;
10063ff40c12SJohn Marino }
10073ff40c12SJohn Marino 
10083ff40c12SJohn Marino 
wps_validate_network_key_shareable(const u8 * val,int mandatory)10093ff40c12SJohn Marino static int wps_validate_network_key_shareable(const u8 *val, int mandatory)
10103ff40c12SJohn Marino {
10113ff40c12SJohn Marino 	if (val == NULL) {
10123ff40c12SJohn Marino 		if (mandatory) {
10133ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
10143ff40c12SJohn Marino 				   "Shareable attribute missing");
10153ff40c12SJohn Marino 			return -1;
10163ff40c12SJohn Marino 		}
10173ff40c12SJohn Marino 		return 0;
10183ff40c12SJohn Marino 	}
10193ff40c12SJohn Marino 	if (*val > 1) {
10203ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Network Key "
10213ff40c12SJohn Marino 			   "Shareable attribute value 0x%x", *val);
10223ff40c12SJohn Marino 		return -1;
10233ff40c12SJohn Marino 	}
10243ff40c12SJohn Marino 	return 0;
10253ff40c12SJohn Marino }
10263ff40c12SJohn Marino 
10273ff40c12SJohn Marino 
wps_validate_cred(const u8 * cred,size_t len)10283ff40c12SJohn Marino static int wps_validate_cred(const u8 *cred, size_t len)
10293ff40c12SJohn Marino {
10303ff40c12SJohn Marino 	struct wps_parse_attr attr;
10313ff40c12SJohn Marino 	struct wpabuf buf;
10323ff40c12SJohn Marino 
10333ff40c12SJohn Marino 	if (cred == NULL)
10343ff40c12SJohn Marino 		return -1;
10353ff40c12SJohn Marino 	wpabuf_set(&buf, cred, len);
10363ff40c12SJohn Marino 	if (wps_parse_msg(&buf, &attr) < 0) {
10373ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse Credential");
10383ff40c12SJohn Marino 		return -1;
10393ff40c12SJohn Marino 	}
10403ff40c12SJohn Marino 
10413ff40c12SJohn Marino 	if (wps_validate_network_idx(attr.network_idx, 1) ||
10423ff40c12SJohn Marino 	    wps_validate_ssid(attr.ssid, attr.ssid_len, 1) ||
10433ff40c12SJohn Marino 	    wps_validate_auth_type(attr.auth_type, 1) ||
10443ff40c12SJohn Marino 	    wps_validate_encr_type(attr.encr_type, 1) ||
10453ff40c12SJohn Marino 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
10463ff40c12SJohn Marino 	    wps_validate_network_key(attr.network_key, attr.network_key_len,
10473ff40c12SJohn Marino 				     attr.encr_type, 1) ||
10483ff40c12SJohn Marino 	    wps_validate_mac_addr(attr.mac_addr, 1) ||
10493ff40c12SJohn Marino 	    wps_validate_network_key_shareable(attr.network_key_shareable, 0))
10503ff40c12SJohn Marino 	{
10513ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Credential");
10523ff40c12SJohn Marino 		return -1;
10533ff40c12SJohn Marino 	}
10543ff40c12SJohn Marino 
10553ff40c12SJohn Marino 
10563ff40c12SJohn Marino 	return 0;
10573ff40c12SJohn Marino }
10583ff40c12SJohn Marino 
10593ff40c12SJohn Marino 
wps_validate_credential(const u8 * cred[],u16 len[],size_t num,int mandatory)1060*a1157835SDaniel Fojt static int wps_validate_credential(const u8 *cred[], u16 len[], size_t num,
10613ff40c12SJohn Marino 				   int mandatory)
10623ff40c12SJohn Marino {
10633ff40c12SJohn Marino 	size_t i;
10643ff40c12SJohn Marino 
10653ff40c12SJohn Marino 	if (num == 0) {
10663ff40c12SJohn Marino 		if (mandatory) {
10673ff40c12SJohn Marino 			wpa_printf(MSG_INFO, "WPS-STRICT: Credential "
10683ff40c12SJohn Marino 				   "attribute missing");
10693ff40c12SJohn Marino 			return -1;
10703ff40c12SJohn Marino 		}
10713ff40c12SJohn Marino 		return 0;
10723ff40c12SJohn Marino 	}
10733ff40c12SJohn Marino 
10743ff40c12SJohn Marino 	for (i = 0; i < num; i++) {
10753ff40c12SJohn Marino 		if (wps_validate_cred(cred[i], len[i]) < 0)
10763ff40c12SJohn Marino 			return -1;
10773ff40c12SJohn Marino 	}
10783ff40c12SJohn Marino 
10793ff40c12SJohn Marino 	return 0;
10803ff40c12SJohn Marino }
10813ff40c12SJohn Marino 
10823ff40c12SJohn Marino 
wps_validate_beacon(const struct wpabuf * wps_ie)10833ff40c12SJohn Marino int wps_validate_beacon(const struct wpabuf *wps_ie)
10843ff40c12SJohn Marino {
10853ff40c12SJohn Marino 	struct wps_parse_attr attr;
10863ff40c12SJohn Marino 	int wps2, sel_reg;
10873ff40c12SJohn Marino 
10883ff40c12SJohn Marino 	if (wps_ie == NULL) {
10893ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in Beacon frame");
10903ff40c12SJohn Marino 		return -1;
10913ff40c12SJohn Marino 	}
10923ff40c12SJohn Marino 	if (wps_parse_msg(wps_ie, &attr) < 0) {
10933ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
10943ff40c12SJohn Marino 			   "Beacon frame");
10953ff40c12SJohn Marino 		return -1;
10963ff40c12SJohn Marino 	}
10973ff40c12SJohn Marino 
10983ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
10993ff40c12SJohn Marino 	sel_reg = attr.selected_registrar != NULL &&
11003ff40c12SJohn Marino 		*attr.selected_registrar != 0;
11013ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
11023ff40c12SJohn Marino 	    wps_validate_wps_state(attr.wps_state, 1) ||
11033ff40c12SJohn Marino 	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
11043ff40c12SJohn Marino 	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
11053ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
11063ff40c12SJohn Marino 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
11073ff40c12SJohn Marino 						wps2, sel_reg) ||
11083ff40c12SJohn Marino 	    wps_validate_uuid_e(attr.uuid_e, 0) ||
11093ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 0) ||
11103ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
11113ff40c12SJohn Marino 	    wps_validate_authorized_macs(attr.authorized_macs,
11123ff40c12SJohn Marino 					 attr.authorized_macs_len, 0)) {
11133ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Beacon frame");
11143ff40c12SJohn Marino 		return -1;
11153ff40c12SJohn Marino 	}
11163ff40c12SJohn Marino 
11173ff40c12SJohn Marino 	return 0;
11183ff40c12SJohn Marino }
11193ff40c12SJohn Marino 
11203ff40c12SJohn Marino 
wps_validate_beacon_probe_resp(const struct wpabuf * wps_ie,int probe,const u8 * addr)11213ff40c12SJohn Marino int wps_validate_beacon_probe_resp(const struct wpabuf *wps_ie, int probe,
11223ff40c12SJohn Marino 				   const u8 *addr)
11233ff40c12SJohn Marino {
11243ff40c12SJohn Marino 	struct wps_parse_attr attr;
11253ff40c12SJohn Marino 	int wps2, sel_reg;
11263ff40c12SJohn Marino 
11273ff40c12SJohn Marino 	if (wps_ie == NULL) {
11283ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
11293ff40c12SJohn Marino 			   "%sProbe Response frame", probe ? "" : "Beacon/");
11303ff40c12SJohn Marino 		return -1;
11313ff40c12SJohn Marino 	}
11323ff40c12SJohn Marino 	if (wps_parse_msg(wps_ie, &attr) < 0) {
11333ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
11343ff40c12SJohn Marino 			   "%sProbe Response frame", probe ? "" : "Beacon/");
11353ff40c12SJohn Marino 		return -1;
11363ff40c12SJohn Marino 	}
11373ff40c12SJohn Marino 
11383ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
11393ff40c12SJohn Marino 	sel_reg = attr.selected_registrar != NULL &&
11403ff40c12SJohn Marino 		*attr.selected_registrar != 0;
11413ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
11423ff40c12SJohn Marino 	    wps_validate_wps_state(attr.wps_state, 1) ||
11433ff40c12SJohn Marino 	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
11443ff40c12SJohn Marino 	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
11453ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
11463ff40c12SJohn Marino 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
11473ff40c12SJohn Marino 						wps2, sel_reg) ||
11483ff40c12SJohn Marino 	    wps_validate_response_type(attr.response_type, probe) ||
11493ff40c12SJohn Marino 	    wps_validate_uuid_e(attr.uuid_e, probe) ||
11503ff40c12SJohn Marino 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
11513ff40c12SJohn Marino 				      probe) ||
11523ff40c12SJohn Marino 	    wps_validate_model_name(attr.model_name, attr.model_name_len,
11533ff40c12SJohn Marino 				    probe) ||
11543ff40c12SJohn Marino 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
11553ff40c12SJohn Marino 				      probe) ||
11563ff40c12SJohn Marino 	    wps_validate_serial_number(attr.serial_number,
11573ff40c12SJohn Marino 				       attr.serial_number_len, probe) ||
11583ff40c12SJohn Marino 	    wps_validate_primary_dev_type(attr.primary_dev_type, probe) ||
11593ff40c12SJohn Marino 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, probe) ||
11603ff40c12SJohn Marino 	    wps_validate_ap_config_methods(attr.config_methods, wps2, probe) ||
11613ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 0) ||
11623ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
11633ff40c12SJohn Marino 	    wps_validate_authorized_macs(attr.authorized_macs,
11643ff40c12SJohn Marino 					 attr.authorized_macs_len, 0)) {
11653ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid %sProbe Response "
11663ff40c12SJohn Marino 			   "frame from " MACSTR, probe ? "" : "Beacon/",
11673ff40c12SJohn Marino 			   MAC2STR(addr));
11683ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
11693ff40c12SJohn Marino 		if (wps2)
11703ff40c12SJohn Marino 			return -1;
11713ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
11723ff40c12SJohn Marino 		return -1;
11733ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
11743ff40c12SJohn Marino 	}
11753ff40c12SJohn Marino 
11763ff40c12SJohn Marino 	return 0;
11773ff40c12SJohn Marino }
11783ff40c12SJohn Marino 
11793ff40c12SJohn Marino 
wps_validate_probe_req(const struct wpabuf * wps_ie,const u8 * addr)11803ff40c12SJohn Marino int wps_validate_probe_req(const struct wpabuf *wps_ie, const u8 *addr)
11813ff40c12SJohn Marino {
11823ff40c12SJohn Marino 	struct wps_parse_attr attr;
11833ff40c12SJohn Marino 	int wps2;
11843ff40c12SJohn Marino 
11853ff40c12SJohn Marino 	if (wps_ie == NULL) {
11863ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
11873ff40c12SJohn Marino 			   "Probe Request frame");
11883ff40c12SJohn Marino 		return -1;
11893ff40c12SJohn Marino 	}
11903ff40c12SJohn Marino 	if (wps_parse_msg(wps_ie, &attr) < 0) {
11913ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
11923ff40c12SJohn Marino 			   "Probe Request frame");
11933ff40c12SJohn Marino 		return -1;
11943ff40c12SJohn Marino 	}
11953ff40c12SJohn Marino 
11963ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
11973ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
11983ff40c12SJohn Marino 	    wps_validate_request_type(attr.request_type, 1) ||
11993ff40c12SJohn Marino 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
12003ff40c12SJohn Marino 	    wps_validate_uuid_e(attr.uuid_e, attr.uuid_r == NULL) ||
12013ff40c12SJohn Marino 	    wps_validate_uuid_r(attr.uuid_r, attr.uuid_e == NULL) ||
12023ff40c12SJohn Marino 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
12033ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
12043ff40c12SJohn Marino 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
12053ff40c12SJohn Marino 	    wps_validate_config_error(attr.config_error, 1) ||
12063ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
12073ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
12083ff40c12SJohn Marino 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
12093ff40c12SJohn Marino 				      wps2) ||
12103ff40c12SJohn Marino 	    wps_validate_model_name(attr.model_name, attr.model_name_len,
12113ff40c12SJohn Marino 				    wps2) ||
12123ff40c12SJohn Marino 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
12133ff40c12SJohn Marino 				      wps2) ||
12143ff40c12SJohn Marino 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, wps2) ||
12153ff40c12SJohn Marino 	    wps_validate_request_to_enroll(attr.request_to_enroll, 0) ||
12163ff40c12SJohn Marino 	    wps_validate_req_dev_type(attr.req_dev_type, attr.num_req_dev_type,
12173ff40c12SJohn Marino 				      0)) {
12183ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Probe Request "
12193ff40c12SJohn Marino 			   "frame from " MACSTR, MAC2STR(addr));
12203ff40c12SJohn Marino 		return -1;
12213ff40c12SJohn Marino 	}
12223ff40c12SJohn Marino 
12233ff40c12SJohn Marino 	return 0;
12243ff40c12SJohn Marino }
12253ff40c12SJohn Marino 
12263ff40c12SJohn Marino 
wps_validate_assoc_req(const struct wpabuf * wps_ie)12273ff40c12SJohn Marino int wps_validate_assoc_req(const struct wpabuf *wps_ie)
12283ff40c12SJohn Marino {
12293ff40c12SJohn Marino 	struct wps_parse_attr attr;
12303ff40c12SJohn Marino 	int wps2;
12313ff40c12SJohn Marino 
12323ff40c12SJohn Marino 	if (wps_ie == NULL) {
12333ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
12343ff40c12SJohn Marino 			   "(Re)Association Request frame");
12353ff40c12SJohn Marino 		return -1;
12363ff40c12SJohn Marino 	}
12373ff40c12SJohn Marino 	if (wps_parse_msg(wps_ie, &attr) < 0) {
12383ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
12393ff40c12SJohn Marino 			   "(Re)Association Request frame");
12403ff40c12SJohn Marino 		return -1;
12413ff40c12SJohn Marino 	}
12423ff40c12SJohn Marino 
12433ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
12443ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
12453ff40c12SJohn Marino 	    wps_validate_request_type(attr.request_type, 1) ||
12463ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
12473ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
12483ff40c12SJohn Marino 			   "Request frame");
12493ff40c12SJohn Marino 		return -1;
12503ff40c12SJohn Marino 	}
12513ff40c12SJohn Marino 
12523ff40c12SJohn Marino 	return 0;
12533ff40c12SJohn Marino }
12543ff40c12SJohn Marino 
12553ff40c12SJohn Marino 
wps_validate_assoc_resp(const struct wpabuf * wps_ie)12563ff40c12SJohn Marino int wps_validate_assoc_resp(const struct wpabuf *wps_ie)
12573ff40c12SJohn Marino {
12583ff40c12SJohn Marino 	struct wps_parse_attr attr;
12593ff40c12SJohn Marino 	int wps2;
12603ff40c12SJohn Marino 
12613ff40c12SJohn Marino 	if (wps_ie == NULL) {
12623ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
12633ff40c12SJohn Marino 			   "(Re)Association Response frame");
12643ff40c12SJohn Marino 		return -1;
12653ff40c12SJohn Marino 	}
12663ff40c12SJohn Marino 	if (wps_parse_msg(wps_ie, &attr) < 0) {
12673ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
12683ff40c12SJohn Marino 			   "(Re)Association Response frame");
12693ff40c12SJohn Marino 		return -1;
12703ff40c12SJohn Marino 	}
12713ff40c12SJohn Marino 
12723ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
12733ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
12743ff40c12SJohn Marino 	    wps_validate_response_type(attr.response_type, 1) ||
12753ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
12763ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
12773ff40c12SJohn Marino 			   "Response frame");
12783ff40c12SJohn Marino 		return -1;
12793ff40c12SJohn Marino 	}
12803ff40c12SJohn Marino 
12813ff40c12SJohn Marino 	return 0;
12823ff40c12SJohn Marino }
12833ff40c12SJohn Marino 
12843ff40c12SJohn Marino 
wps_validate_m1(const struct wpabuf * tlvs)12853ff40c12SJohn Marino int wps_validate_m1(const struct wpabuf *tlvs)
12863ff40c12SJohn Marino {
12873ff40c12SJohn Marino 	struct wps_parse_attr attr;
12883ff40c12SJohn Marino 	int wps2;
12893ff40c12SJohn Marino 
12903ff40c12SJohn Marino 	if (tlvs == NULL) {
12913ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M1");
12923ff40c12SJohn Marino 		return -1;
12933ff40c12SJohn Marino 	}
12943ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
12953ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
12963ff40c12SJohn Marino 			   "in M1");
12973ff40c12SJohn Marino 		return -1;
12983ff40c12SJohn Marino 	}
12993ff40c12SJohn Marino 
13003ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
13013ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
13023ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
13033ff40c12SJohn Marino 	    wps_validate_uuid_e(attr.uuid_e, 1) ||
13043ff40c12SJohn Marino 	    wps_validate_mac_addr(attr.mac_addr, 1) ||
13053ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
13063ff40c12SJohn Marino 	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
13073ff40c12SJohn Marino 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
13083ff40c12SJohn Marino 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
13093ff40c12SJohn Marino 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
13103ff40c12SJohn Marino 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
13113ff40c12SJohn Marino 	    wps_validate_wps_state(attr.wps_state, 1) ||
13123ff40c12SJohn Marino 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
13133ff40c12SJohn Marino 				      1) ||
13143ff40c12SJohn Marino 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
13153ff40c12SJohn Marino 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
13163ff40c12SJohn Marino 				      1) ||
13173ff40c12SJohn Marino 	    wps_validate_serial_number(attr.serial_number,
13183ff40c12SJohn Marino 				       attr.serial_number_len, 1) ||
13193ff40c12SJohn Marino 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
13203ff40c12SJohn Marino 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
13213ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
13223ff40c12SJohn Marino 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
13233ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
13243ff40c12SJohn Marino 	    wps_validate_config_error(attr.config_error, 1) ||
13253ff40c12SJohn Marino 	    wps_validate_os_version(attr.os_version, 1) ||
13263ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
13273ff40c12SJohn Marino 	    wps_validate_request_to_enroll(attr.request_to_enroll, 0)) {
13283ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M1");
13293ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
13303ff40c12SJohn Marino 		if (wps2)
13313ff40c12SJohn Marino 			return -1;
13323ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
13333ff40c12SJohn Marino 		return -1;
13343ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
13353ff40c12SJohn Marino 	}
13363ff40c12SJohn Marino 
13373ff40c12SJohn Marino 	return 0;
13383ff40c12SJohn Marino }
13393ff40c12SJohn Marino 
13403ff40c12SJohn Marino 
wps_validate_m2(const struct wpabuf * tlvs)13413ff40c12SJohn Marino int wps_validate_m2(const struct wpabuf *tlvs)
13423ff40c12SJohn Marino {
13433ff40c12SJohn Marino 	struct wps_parse_attr attr;
13443ff40c12SJohn Marino 	int wps2;
13453ff40c12SJohn Marino 
13463ff40c12SJohn Marino 	if (tlvs == NULL) {
13473ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2");
13483ff40c12SJohn Marino 		return -1;
13493ff40c12SJohn Marino 	}
13503ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
13513ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
13523ff40c12SJohn Marino 			   "in M2");
13533ff40c12SJohn Marino 		return -1;
13543ff40c12SJohn Marino 	}
13553ff40c12SJohn Marino 
13563ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
13573ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
13583ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
13593ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
13603ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
13613ff40c12SJohn Marino 	    wps_validate_uuid_r(attr.uuid_r, 1) ||
13623ff40c12SJohn Marino 	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
13633ff40c12SJohn Marino 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
13643ff40c12SJohn Marino 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
13653ff40c12SJohn Marino 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
13663ff40c12SJohn Marino 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
13673ff40c12SJohn Marino 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
13683ff40c12SJohn Marino 				      1) ||
13693ff40c12SJohn Marino 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
13703ff40c12SJohn Marino 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
13713ff40c12SJohn Marino 				      1) ||
13723ff40c12SJohn Marino 	    wps_validate_serial_number(attr.serial_number,
13733ff40c12SJohn Marino 				       attr.serial_number_len, 1) ||
13743ff40c12SJohn Marino 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
13753ff40c12SJohn Marino 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
13763ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
13773ff40c12SJohn Marino 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
13783ff40c12SJohn Marino 	    wps_validate_config_error(attr.config_error, 1) ||
13793ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
13803ff40c12SJohn Marino 	    wps_validate_os_version(attr.os_version, 1) ||
13813ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
13823ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
13833ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2");
13843ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
13853ff40c12SJohn Marino 		if (wps2)
13863ff40c12SJohn Marino 			return -1;
13873ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
13883ff40c12SJohn Marino 		return -1;
13893ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
13903ff40c12SJohn Marino 	}
13913ff40c12SJohn Marino 
13923ff40c12SJohn Marino 	return 0;
13933ff40c12SJohn Marino }
13943ff40c12SJohn Marino 
13953ff40c12SJohn Marino 
wps_validate_m2d(const struct wpabuf * tlvs)13963ff40c12SJohn Marino int wps_validate_m2d(const struct wpabuf *tlvs)
13973ff40c12SJohn Marino {
13983ff40c12SJohn Marino 	struct wps_parse_attr attr;
13993ff40c12SJohn Marino 	int wps2;
14003ff40c12SJohn Marino 
14013ff40c12SJohn Marino 	if (tlvs == NULL) {
14023ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2D");
14033ff40c12SJohn Marino 		return -1;
14043ff40c12SJohn Marino 	}
14053ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
14063ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14073ff40c12SJohn Marino 			   "in M2D");
14083ff40c12SJohn Marino 		return -1;
14093ff40c12SJohn Marino 	}
14103ff40c12SJohn Marino 
14113ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
14123ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
14133ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
14143ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
14153ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14163ff40c12SJohn Marino 	    wps_validate_uuid_r(attr.uuid_r, 1) ||
14173ff40c12SJohn Marino 	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
14183ff40c12SJohn Marino 	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
14193ff40c12SJohn Marino 	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
14203ff40c12SJohn Marino 	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
14213ff40c12SJohn Marino 	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
14223ff40c12SJohn Marino 				      1) ||
14233ff40c12SJohn Marino 	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
14243ff40c12SJohn Marino 	    wps_validate_model_number(attr.model_number, attr.model_number_len,
14253ff40c12SJohn Marino 				      1) ||
14263ff40c12SJohn Marino 	    wps_validate_serial_number(attr.serial_number,
14273ff40c12SJohn Marino 				       attr.serial_number_len, 1) ||
14283ff40c12SJohn Marino 	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
14293ff40c12SJohn Marino 	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
14303ff40c12SJohn Marino 	    wps_validate_rf_bands(attr.rf_bands, 1) ||
14313ff40c12SJohn Marino 	    wps_validate_assoc_state(attr.assoc_state, 1) ||
14323ff40c12SJohn Marino 	    wps_validate_config_error(attr.config_error, 1) ||
14333ff40c12SJohn Marino 	    wps_validate_os_version(attr.os_version, 1) ||
14343ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
14353ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2D");
14363ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
14373ff40c12SJohn Marino 		if (wps2)
14383ff40c12SJohn Marino 			return -1;
14393ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
14403ff40c12SJohn Marino 		return -1;
14413ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
14423ff40c12SJohn Marino 	}
14433ff40c12SJohn Marino 
14443ff40c12SJohn Marino 	return 0;
14453ff40c12SJohn Marino }
14463ff40c12SJohn Marino 
14473ff40c12SJohn Marino 
wps_validate_m3(const struct wpabuf * tlvs)14483ff40c12SJohn Marino int wps_validate_m3(const struct wpabuf *tlvs)
14493ff40c12SJohn Marino {
14503ff40c12SJohn Marino 	struct wps_parse_attr attr;
14513ff40c12SJohn Marino 	int wps2;
14523ff40c12SJohn Marino 
14533ff40c12SJohn Marino 	if (tlvs == NULL) {
14543ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M3");
14553ff40c12SJohn Marino 		return -1;
14563ff40c12SJohn Marino 	}
14573ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
14583ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14593ff40c12SJohn Marino 			   "in M3");
14603ff40c12SJohn Marino 		return -1;
14613ff40c12SJohn Marino 	}
14623ff40c12SJohn Marino 
14633ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
14643ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
14653ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
14663ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14673ff40c12SJohn Marino 	    wps_validate_e_hash1(attr.e_hash1, 1) ||
14683ff40c12SJohn Marino 	    wps_validate_e_hash2(attr.e_hash2, 1) ||
14693ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
14703ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
14713ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M3");
14723ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
14733ff40c12SJohn Marino 		if (wps2)
14743ff40c12SJohn Marino 			return -1;
14753ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
14763ff40c12SJohn Marino 		return -1;
14773ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
14783ff40c12SJohn Marino 	}
14793ff40c12SJohn Marino 
14803ff40c12SJohn Marino 	return 0;
14813ff40c12SJohn Marino }
14823ff40c12SJohn Marino 
14833ff40c12SJohn Marino 
wps_validate_m4(const struct wpabuf * tlvs)14843ff40c12SJohn Marino int wps_validate_m4(const struct wpabuf *tlvs)
14853ff40c12SJohn Marino {
14863ff40c12SJohn Marino 	struct wps_parse_attr attr;
14873ff40c12SJohn Marino 	int wps2;
14883ff40c12SJohn Marino 
14893ff40c12SJohn Marino 	if (tlvs == NULL) {
14903ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4");
14913ff40c12SJohn Marino 		return -1;
14923ff40c12SJohn Marino 	}
14933ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
14943ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14953ff40c12SJohn Marino 			   "in M4");
14963ff40c12SJohn Marino 		return -1;
14973ff40c12SJohn Marino 	}
14983ff40c12SJohn Marino 
14993ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
15003ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
15013ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
15023ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
15033ff40c12SJohn Marino 	    wps_validate_r_hash1(attr.r_hash1, 1) ||
15043ff40c12SJohn Marino 	    wps_validate_r_hash2(attr.r_hash2, 1) ||
15053ff40c12SJohn Marino 	    wps_validate_encr_settings(attr.encr_settings,
15063ff40c12SJohn Marino 				       attr.encr_settings_len, 1) ||
15073ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
15083ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
15093ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4");
15103ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
15113ff40c12SJohn Marino 		if (wps2)
15123ff40c12SJohn Marino 			return -1;
15133ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
15143ff40c12SJohn Marino 		return -1;
15153ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
15163ff40c12SJohn Marino 	}
15173ff40c12SJohn Marino 
15183ff40c12SJohn Marino 	return 0;
15193ff40c12SJohn Marino }
15203ff40c12SJohn Marino 
15213ff40c12SJohn Marino 
wps_validate_m4_encr(const struct wpabuf * tlvs,int wps2)15223ff40c12SJohn Marino int wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2)
15233ff40c12SJohn Marino {
15243ff40c12SJohn Marino 	struct wps_parse_attr attr;
15253ff40c12SJohn Marino 
15263ff40c12SJohn Marino 	if (tlvs == NULL) {
15273ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted "
15283ff40c12SJohn Marino 			   "settings");
15293ff40c12SJohn Marino 		return -1;
15303ff40c12SJohn Marino 	}
15313ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
15323ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15333ff40c12SJohn Marino 			   "in M4 encrypted settings");
15343ff40c12SJohn Marino 		return -1;
15353ff40c12SJohn Marino 	}
15363ff40c12SJohn Marino 
15373ff40c12SJohn Marino 	if (wps_validate_r_snonce1(attr.r_snonce1, 1) ||
15383ff40c12SJohn Marino 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
15393ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted "
15403ff40c12SJohn Marino 			   "settings");
15413ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
15423ff40c12SJohn Marino 		if (wps2)
15433ff40c12SJohn Marino 			return -1;
15443ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
15453ff40c12SJohn Marino 		return -1;
15463ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
15473ff40c12SJohn Marino 	}
15483ff40c12SJohn Marino 
15493ff40c12SJohn Marino 	return 0;
15503ff40c12SJohn Marino }
15513ff40c12SJohn Marino 
15523ff40c12SJohn Marino 
wps_validate_m5(const struct wpabuf * tlvs)15533ff40c12SJohn Marino int wps_validate_m5(const struct wpabuf *tlvs)
15543ff40c12SJohn Marino {
15553ff40c12SJohn Marino 	struct wps_parse_attr attr;
15563ff40c12SJohn Marino 	int wps2;
15573ff40c12SJohn Marino 
15583ff40c12SJohn Marino 	if (tlvs == NULL) {
15593ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5");
15603ff40c12SJohn Marino 		return -1;
15613ff40c12SJohn Marino 	}
15623ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
15633ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15643ff40c12SJohn Marino 			   "in M5");
15653ff40c12SJohn Marino 		return -1;
15663ff40c12SJohn Marino 	}
15673ff40c12SJohn Marino 
15683ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
15693ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
15703ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
15713ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
15723ff40c12SJohn Marino 	    wps_validate_encr_settings(attr.encr_settings,
15733ff40c12SJohn Marino 				       attr.encr_settings_len, 1) ||
15743ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
15753ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
15763ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5");
15773ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
15783ff40c12SJohn Marino 		if (wps2)
15793ff40c12SJohn Marino 			return -1;
15803ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
15813ff40c12SJohn Marino 		return -1;
15823ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
15833ff40c12SJohn Marino 	}
15843ff40c12SJohn Marino 
15853ff40c12SJohn Marino 	return 0;
15863ff40c12SJohn Marino }
15873ff40c12SJohn Marino 
15883ff40c12SJohn Marino 
wps_validate_m5_encr(const struct wpabuf * tlvs,int wps2)15893ff40c12SJohn Marino int wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2)
15903ff40c12SJohn Marino {
15913ff40c12SJohn Marino 	struct wps_parse_attr attr;
15923ff40c12SJohn Marino 
15933ff40c12SJohn Marino 	if (tlvs == NULL) {
15943ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted "
15953ff40c12SJohn Marino 			   "settings");
15963ff40c12SJohn Marino 		return -1;
15973ff40c12SJohn Marino 	}
15983ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
15993ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16003ff40c12SJohn Marino 			   "in M5 encrypted settings");
16013ff40c12SJohn Marino 		return -1;
16023ff40c12SJohn Marino 	}
16033ff40c12SJohn Marino 
16043ff40c12SJohn Marino 	if (wps_validate_e_snonce1(attr.e_snonce1, 1) ||
16053ff40c12SJohn Marino 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16063ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted "
16073ff40c12SJohn Marino 			   "settings");
16083ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
16093ff40c12SJohn Marino 		if (wps2)
16103ff40c12SJohn Marino 			return -1;
16113ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
16123ff40c12SJohn Marino 		return -1;
16133ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
16143ff40c12SJohn Marino 	}
16153ff40c12SJohn Marino 
16163ff40c12SJohn Marino 	return 0;
16173ff40c12SJohn Marino }
16183ff40c12SJohn Marino 
16193ff40c12SJohn Marino 
wps_validate_m6(const struct wpabuf * tlvs)16203ff40c12SJohn Marino int wps_validate_m6(const struct wpabuf *tlvs)
16213ff40c12SJohn Marino {
16223ff40c12SJohn Marino 	struct wps_parse_attr attr;
16233ff40c12SJohn Marino 	int wps2;
16243ff40c12SJohn Marino 
16253ff40c12SJohn Marino 	if (tlvs == NULL) {
16263ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6");
16273ff40c12SJohn Marino 		return -1;
16283ff40c12SJohn Marino 	}
16293ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
16303ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16313ff40c12SJohn Marino 			   "in M6");
16323ff40c12SJohn Marino 		return -1;
16333ff40c12SJohn Marino 	}
16343ff40c12SJohn Marino 
16353ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
16363ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
16373ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
16383ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
16393ff40c12SJohn Marino 	    wps_validate_encr_settings(attr.encr_settings,
16403ff40c12SJohn Marino 				       attr.encr_settings_len, 1) ||
16413ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
16423ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
16433ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6");
16443ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
16453ff40c12SJohn Marino 		if (wps2)
16463ff40c12SJohn Marino 			return -1;
16473ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
16483ff40c12SJohn Marino 		return -1;
16493ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
16503ff40c12SJohn Marino 	}
16513ff40c12SJohn Marino 
16523ff40c12SJohn Marino 	return 0;
16533ff40c12SJohn Marino }
16543ff40c12SJohn Marino 
16553ff40c12SJohn Marino 
wps_validate_m6_encr(const struct wpabuf * tlvs,int wps2)16563ff40c12SJohn Marino int wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2)
16573ff40c12SJohn Marino {
16583ff40c12SJohn Marino 	struct wps_parse_attr attr;
16593ff40c12SJohn Marino 
16603ff40c12SJohn Marino 	if (tlvs == NULL) {
16613ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted "
16623ff40c12SJohn Marino 			   "settings");
16633ff40c12SJohn Marino 		return -1;
16643ff40c12SJohn Marino 	}
16653ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
16663ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16673ff40c12SJohn Marino 			   "in M6 encrypted settings");
16683ff40c12SJohn Marino 		return -1;
16693ff40c12SJohn Marino 	}
16703ff40c12SJohn Marino 
16713ff40c12SJohn Marino 	if (wps_validate_r_snonce2(attr.r_snonce2, 1) ||
16723ff40c12SJohn Marino 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16733ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted "
16743ff40c12SJohn Marino 			   "settings");
16753ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
16763ff40c12SJohn Marino 		if (wps2)
16773ff40c12SJohn Marino 			return -1;
16783ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
16793ff40c12SJohn Marino 		return -1;
16803ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
16813ff40c12SJohn Marino 	}
16823ff40c12SJohn Marino 
16833ff40c12SJohn Marino 	return 0;
16843ff40c12SJohn Marino }
16853ff40c12SJohn Marino 
16863ff40c12SJohn Marino 
wps_validate_m7(const struct wpabuf * tlvs)16873ff40c12SJohn Marino int wps_validate_m7(const struct wpabuf *tlvs)
16883ff40c12SJohn Marino {
16893ff40c12SJohn Marino 	struct wps_parse_attr attr;
16903ff40c12SJohn Marino 	int wps2;
16913ff40c12SJohn Marino 
16923ff40c12SJohn Marino 	if (tlvs == NULL) {
16933ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7");
16943ff40c12SJohn Marino 		return -1;
16953ff40c12SJohn Marino 	}
16963ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
16973ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16983ff40c12SJohn Marino 			   "in M7");
16993ff40c12SJohn Marino 		return -1;
17003ff40c12SJohn Marino 	}
17013ff40c12SJohn Marino 
17023ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
17033ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
17043ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
17053ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
17063ff40c12SJohn Marino 	    wps_validate_encr_settings(attr.encr_settings,
17073ff40c12SJohn Marino 				       attr.encr_settings_len, 1) ||
17083ff40c12SJohn Marino 	    wps_validate_settings_delay_time(attr.settings_delay_time, 0) ||
17093ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
17103ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
17113ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7");
17123ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
17133ff40c12SJohn Marino 		if (wps2)
17143ff40c12SJohn Marino 			return -1;
17153ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
17163ff40c12SJohn Marino 		return -1;
17173ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
17183ff40c12SJohn Marino 	}
17193ff40c12SJohn Marino 
17203ff40c12SJohn Marino 	return 0;
17213ff40c12SJohn Marino }
17223ff40c12SJohn Marino 
17233ff40c12SJohn Marino 
wps_validate_m7_encr(const struct wpabuf * tlvs,int ap,int wps2)17243ff40c12SJohn Marino int wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2)
17253ff40c12SJohn Marino {
17263ff40c12SJohn Marino 	struct wps_parse_attr attr;
17273ff40c12SJohn Marino 
17283ff40c12SJohn Marino 	if (tlvs == NULL) {
17293ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted "
17303ff40c12SJohn Marino 			   "settings");
17313ff40c12SJohn Marino 		return -1;
17323ff40c12SJohn Marino 	}
17333ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
17343ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
17353ff40c12SJohn Marino 			   "in M7 encrypted settings");
17363ff40c12SJohn Marino 		return -1;
17373ff40c12SJohn Marino 	}
17383ff40c12SJohn Marino 
17393ff40c12SJohn Marino 	if (wps_validate_e_snonce2(attr.e_snonce2, 1) ||
17403ff40c12SJohn Marino 	    wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) ||
17413ff40c12SJohn Marino 	    wps_validate_mac_addr(attr.mac_addr, !ap) ||
17423ff40c12SJohn Marino 	    wps_validate_auth_type(attr.auth_type, !ap) ||
17433ff40c12SJohn Marino 	    wps_validate_encr_type(attr.encr_type, !ap) ||
17443ff40c12SJohn Marino 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
17453ff40c12SJohn Marino 	    wps_validate_network_key(attr.network_key, attr.network_key_len,
17463ff40c12SJohn Marino 				     attr.encr_type, !ap) ||
17473ff40c12SJohn Marino 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
17483ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7 encrypted "
17493ff40c12SJohn Marino 			   "settings");
17503ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
17513ff40c12SJohn Marino 		if (wps2)
17523ff40c12SJohn Marino 			return -1;
17533ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
17543ff40c12SJohn Marino 		return -1;
17553ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
17563ff40c12SJohn Marino 	}
17573ff40c12SJohn Marino 
17583ff40c12SJohn Marino 	return 0;
17593ff40c12SJohn Marino }
17603ff40c12SJohn Marino 
17613ff40c12SJohn Marino 
wps_validate_m8(const struct wpabuf * tlvs)17623ff40c12SJohn Marino int wps_validate_m8(const struct wpabuf *tlvs)
17633ff40c12SJohn Marino {
17643ff40c12SJohn Marino 	struct wps_parse_attr attr;
17653ff40c12SJohn Marino 	int wps2;
17663ff40c12SJohn Marino 
17673ff40c12SJohn Marino 	if (tlvs == NULL) {
17683ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8");
17693ff40c12SJohn Marino 		return -1;
17703ff40c12SJohn Marino 	}
17713ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
17723ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
17733ff40c12SJohn Marino 			   "in M8");
17743ff40c12SJohn Marino 		return -1;
17753ff40c12SJohn Marino 	}
17763ff40c12SJohn Marino 
17773ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
17783ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
17793ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
17803ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
17813ff40c12SJohn Marino 	    wps_validate_encr_settings(attr.encr_settings,
17823ff40c12SJohn Marino 				       attr.encr_settings_len, 1) ||
17833ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
17843ff40c12SJohn Marino 	    wps_validate_authenticator(attr.authenticator, 1)) {
17853ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8");
17863ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
17873ff40c12SJohn Marino 		if (wps2)
17883ff40c12SJohn Marino 			return -1;
17893ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
17903ff40c12SJohn Marino 		return -1;
17913ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
17923ff40c12SJohn Marino 	}
17933ff40c12SJohn Marino 
17943ff40c12SJohn Marino 	return 0;
17953ff40c12SJohn Marino }
17963ff40c12SJohn Marino 
17973ff40c12SJohn Marino 
wps_validate_m8_encr(const struct wpabuf * tlvs,int ap,int wps2)17983ff40c12SJohn Marino int wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2)
17993ff40c12SJohn Marino {
18003ff40c12SJohn Marino 	struct wps_parse_attr attr;
18013ff40c12SJohn Marino 
18023ff40c12SJohn Marino 	if (tlvs == NULL) {
18033ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted "
18043ff40c12SJohn Marino 			   "settings");
18053ff40c12SJohn Marino 		return -1;
18063ff40c12SJohn Marino 	}
18073ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
18083ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18093ff40c12SJohn Marino 			   "in M8 encrypted settings");
18103ff40c12SJohn Marino 		return -1;
18113ff40c12SJohn Marino 	}
18123ff40c12SJohn Marino 
18133ff40c12SJohn Marino 	if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) ||
18143ff40c12SJohn Marino 	    wps_validate_auth_type(attr.auth_type, ap) ||
18153ff40c12SJohn Marino 	    wps_validate_encr_type(attr.encr_type, ap) ||
18163ff40c12SJohn Marino 	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
18173ff40c12SJohn Marino 	    wps_validate_mac_addr(attr.mac_addr, ap) ||
18183ff40c12SJohn Marino 	    wps_validate_credential(attr.cred, attr.cred_len, attr.num_cred,
18193ff40c12SJohn Marino 				    !ap) ||
18203ff40c12SJohn Marino 	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
18213ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8 encrypted "
18223ff40c12SJohn Marino 			   "settings");
18233ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
18243ff40c12SJohn Marino 		if (wps2)
18253ff40c12SJohn Marino 			return -1;
18263ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
18273ff40c12SJohn Marino 		return -1;
18283ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
18293ff40c12SJohn Marino 	}
18303ff40c12SJohn Marino 
18313ff40c12SJohn Marino 	return 0;
18323ff40c12SJohn Marino }
18333ff40c12SJohn Marino 
18343ff40c12SJohn Marino 
wps_validate_wsc_ack(const struct wpabuf * tlvs)18353ff40c12SJohn Marino int wps_validate_wsc_ack(const struct wpabuf *tlvs)
18363ff40c12SJohn Marino {
18373ff40c12SJohn Marino 	struct wps_parse_attr attr;
18383ff40c12SJohn Marino 	int wps2;
18393ff40c12SJohn Marino 
18403ff40c12SJohn Marino 	if (tlvs == NULL) {
18413ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_ACK");
18423ff40c12SJohn Marino 		return -1;
18433ff40c12SJohn Marino 	}
18443ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
18453ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18463ff40c12SJohn Marino 			   "in WSC_ACK");
18473ff40c12SJohn Marino 		return -1;
18483ff40c12SJohn Marino 	}
18493ff40c12SJohn Marino 
18503ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
18513ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
18523ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
18533ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
18543ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
18553ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
18563ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_ACK");
18573ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
18583ff40c12SJohn Marino 		if (wps2)
18593ff40c12SJohn Marino 			return -1;
18603ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
18613ff40c12SJohn Marino 		return -1;
18623ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
18633ff40c12SJohn Marino 	}
18643ff40c12SJohn Marino 
18653ff40c12SJohn Marino 	return 0;
18663ff40c12SJohn Marino }
18673ff40c12SJohn Marino 
18683ff40c12SJohn Marino 
wps_validate_wsc_nack(const struct wpabuf * tlvs)18693ff40c12SJohn Marino int wps_validate_wsc_nack(const struct wpabuf *tlvs)
18703ff40c12SJohn Marino {
18713ff40c12SJohn Marino 	struct wps_parse_attr attr;
18723ff40c12SJohn Marino 	int wps2;
18733ff40c12SJohn Marino 
18743ff40c12SJohn Marino 	if (tlvs == NULL) {
18753ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_NACK");
18763ff40c12SJohn Marino 		return -1;
18773ff40c12SJohn Marino 	}
18783ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
18793ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18803ff40c12SJohn Marino 			   "in WSC_NACK");
18813ff40c12SJohn Marino 		return -1;
18823ff40c12SJohn Marino 	}
18833ff40c12SJohn Marino 
18843ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
18853ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
18863ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
18873ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
18883ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
18893ff40c12SJohn Marino 	    wps_validate_config_error(attr.config_error, 1) ||
18903ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
18913ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_NACK");
18923ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
18933ff40c12SJohn Marino 		if (wps2)
18943ff40c12SJohn Marino 			return -1;
18953ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
18963ff40c12SJohn Marino 		return -1;
18973ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
18983ff40c12SJohn Marino 	}
18993ff40c12SJohn Marino 
19003ff40c12SJohn Marino 	return 0;
19013ff40c12SJohn Marino }
19023ff40c12SJohn Marino 
19033ff40c12SJohn Marino 
wps_validate_wsc_done(const struct wpabuf * tlvs)19043ff40c12SJohn Marino int wps_validate_wsc_done(const struct wpabuf *tlvs)
19053ff40c12SJohn Marino {
19063ff40c12SJohn Marino 	struct wps_parse_attr attr;
19073ff40c12SJohn Marino 	int wps2;
19083ff40c12SJohn Marino 
19093ff40c12SJohn Marino 	if (tlvs == NULL) {
19103ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_Done");
19113ff40c12SJohn Marino 		return -1;
19123ff40c12SJohn Marino 	}
19133ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
19143ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
19153ff40c12SJohn Marino 			   "in WSC_Done");
19163ff40c12SJohn Marino 		return -1;
19173ff40c12SJohn Marino 	}
19183ff40c12SJohn Marino 
19193ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
19203ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
19213ff40c12SJohn Marino 	    wps_validate_msg_type(attr.msg_type, 1) ||
19223ff40c12SJohn Marino 	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
19233ff40c12SJohn Marino 	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
19243ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2)) {
19253ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_Done");
19263ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
19273ff40c12SJohn Marino 		if (wps2)
19283ff40c12SJohn Marino 			return -1;
19293ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
19303ff40c12SJohn Marino 		return -1;
19313ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
19323ff40c12SJohn Marino 	}
19333ff40c12SJohn Marino 
19343ff40c12SJohn Marino 	return 0;
19353ff40c12SJohn Marino }
19363ff40c12SJohn Marino 
19373ff40c12SJohn Marino 
wps_validate_upnp_set_selected_registrar(const struct wpabuf * tlvs)19383ff40c12SJohn Marino int wps_validate_upnp_set_selected_registrar(const struct wpabuf *tlvs)
19393ff40c12SJohn Marino {
19403ff40c12SJohn Marino 	struct wps_parse_attr attr;
19413ff40c12SJohn Marino 	int wps2;
19423ff40c12SJohn Marino 	int sel_reg;
19433ff40c12SJohn Marino 
19443ff40c12SJohn Marino 	if (tlvs == NULL) {
19453ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in "
19463ff40c12SJohn Marino 			   "SetSelectedRegistrar");
19473ff40c12SJohn Marino 		return -1;
19483ff40c12SJohn Marino 	}
19493ff40c12SJohn Marino 	if (wps_parse_msg(tlvs, &attr) < 0) {
19503ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
19513ff40c12SJohn Marino 			   "in SetSelectedRegistrar");
19523ff40c12SJohn Marino 		return -1;
19533ff40c12SJohn Marino 	}
19543ff40c12SJohn Marino 
19553ff40c12SJohn Marino 	wps2 = attr.version2 != NULL;
19563ff40c12SJohn Marino 	sel_reg = attr.selected_registrar != NULL &&
19573ff40c12SJohn Marino 		*attr.selected_registrar != 0;
19583ff40c12SJohn Marino 	if (wps_validate_version(attr.version, 1) ||
19593ff40c12SJohn Marino 	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
19603ff40c12SJohn Marino 	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
19613ff40c12SJohn Marino 						wps2, sel_reg) ||
19623ff40c12SJohn Marino 	    wps_validate_version2(attr.version2, wps2) ||
19633ff40c12SJohn Marino 	    wps_validate_authorized_macs(attr.authorized_macs,
19643ff40c12SJohn Marino 					 attr.authorized_macs_len, wps2) ||
19653ff40c12SJohn Marino 	    wps_validate_uuid_r(attr.uuid_r, wps2)) {
19663ff40c12SJohn Marino 		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid "
19673ff40c12SJohn Marino 			   "SetSelectedRegistrar");
19683ff40c12SJohn Marino #ifdef WPS_STRICT_WPS2
19693ff40c12SJohn Marino 		if (wps2)
19703ff40c12SJohn Marino 			return -1;
19713ff40c12SJohn Marino #else /* WPS_STRICT_WPS2 */
19723ff40c12SJohn Marino 		return -1;
19733ff40c12SJohn Marino #endif /* WPS_STRICT_WPS2 */
19743ff40c12SJohn Marino 	}
19753ff40c12SJohn Marino 
19763ff40c12SJohn Marino 	return 0;
19773ff40c12SJohn Marino }
1978