18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Wi-Fi Protected Setup - Strict protocol validation routines
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2010, Atheros Communications, Inc.
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_i.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef WPS_STRICT_ALL
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WPS_STRICT_WPS2
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_ALL */
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_version(const u8 *version, int mandatory)
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (version == NULL) {
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Version attribute "
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "missing");
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*version != 0x10) {
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version attribute "
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "value 0x%x", *version);
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_version2(const u8 *version2, int mandatory)
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (version2 == NULL) {
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Version2 attribute "
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "missing");
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*version2 < 0x20) {
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Version2 attribute "
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "value 0x%x", *version2);
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_request_type(const u8 *request_type, int mandatory)
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (request_type == NULL) {
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Request Type "
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*request_type > 0x03) {
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request Type "
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *request_type);
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_response_type(const u8 *response_type, int mandatory)
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (response_type == NULL) {
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Response Type "
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*response_type > 0x03) {
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Response Type "
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *response_type);
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int valid_config_methods(u16 val, int wps2)
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps2) {
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((val & 0x6000) && !(val & WPS_CONFIG_DISPLAY)) {
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Display flag without old Display flag "
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "set");
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(val & 0x6000) && (val & WPS_CONFIG_DISPLAY)) {
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Display flag "
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "without Physical/Virtual Display flag");
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((val & 0x0600) && !(val & WPS_CONFIG_PUSHBUTTON)) {
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Physical/Virtual "
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "PushButton flag without old PushButton "
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "flag set");
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(val & 0x0600) && (val & WPS_CONFIG_PUSHBUTTON)) {
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: PushButton flag "
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "without Physical/Virtual PushButton flag");
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return 0;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 1;
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_config_methods(const u8 *config_methods, int wps2,
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       int mandatory)
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods == NULL) {
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration "
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Methods attribute missing");
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(config_methods);
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!valid_config_methods(val, wps2)) {
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Methods attribute value 0x%04x", val);
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_ap_config_methods(const u8 *config_methods, int wps2,
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  int mandatory)
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_config_methods(config_methods, wps2, mandatory) < 0)
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods == NULL)
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(config_methods);
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val & WPS_CONFIG_PUSHBUTTON) {
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration "
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Methods attribute value 0x%04x in AP info "
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(PushButton not allowed for registering new ER)",
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   val);
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_uuid_e(const u8 *uuid_e, int mandatory)
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (uuid_e == NULL) {
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-E "
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_uuid_r(const u8 *uuid_r, int mandatory)
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (uuid_r == NULL) {
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: UUID-R "
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_primary_dev_type(const u8 *primary_dev_type,
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 int mandatory)
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (primary_dev_type == NULL) {
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Primary Device Type "
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_rf_bands(const u8 *rf_bands, int mandatory)
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (rf_bands == NULL) {
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: RF Bands "
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*rf_bands != WPS_RF_24GHZ && *rf_bands != WPS_RF_50GHZ &&
2271d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt	    *rf_bands != WPS_RF_60GHZ &&
2281d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ | WPS_RF_60GHZ) &&
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    *rf_bands != (WPS_RF_24GHZ | WPS_RF_50GHZ)) {
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Rf Bands "
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *rf_bands);
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_assoc_state(const u8 *assoc_state, int mandatory)
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (assoc_state == NULL) {
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Association State "
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(assoc_state);
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val > 4) {
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Association State "
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%04x", val);
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_config_error(const u8 *config_error, int mandatory)
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_error == NULL) {
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Configuration Error "
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(config_error);
272cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (val > 20) {
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Configuration Error "
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%04x", val);
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_dev_password_id(const u8 *dev_password_id,
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int mandatory)
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev_password_id == NULL) {
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Device Password ID "
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(dev_password_id);
295cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (val >= 0x0008 && val <= 0x000f) {
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Device Password ID "
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%04x", val);
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_manufacturer(const u8 *manufacturer, size_t len,
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int mandatory)
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (manufacturer == NULL) {
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Manufacturer "
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 0 && manufacturer[len - 1] == 0) {
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Manufacturer "
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value", manufacturer, len);
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_model_name(const u8 *model_name, size_t len,
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int mandatory)
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (model_name == NULL) {
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Model Name "
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 0 && model_name[len - 1] == 0) {
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Name "
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value", model_name, len);
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_model_number(const u8 *model_number, size_t len,
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int mandatory)
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (model_number == NULL) {
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Model Number "
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 0 && model_number[len - 1] == 0) {
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Model Number "
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value", model_number, len);
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_serial_number(const u8 *serial_number, size_t len,
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      int mandatory)
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (serial_number == NULL) {
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Serial Number "
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 0 && serial_number[len - 1] == 0) {
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Serial "
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  "Number attribute value",
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  serial_number, len);
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_dev_name(const u8 *dev_name, size_t len,
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 int mandatory)
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (dev_name == NULL) {
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Device Name "
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 0 && dev_name[len - 1] == 0) {
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid Device Name "
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value", dev_name, len);
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_request_to_enroll(const u8 *request_to_enroll,
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  int mandatory)
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (request_to_enroll == NULL) {
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Request to Enroll "
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*request_to_enroll > 0x01) {
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Request to Enroll "
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *request_to_enroll);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_req_dev_type(const u8 *req_dev_type[], size_t num,
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int mandatory)
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num == 0) {
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Requested Device "
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Type attribute missing");
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_wps_state(const u8 *wps_state, int mandatory)
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_state == NULL) {
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Wi-Fi Protected "
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Setup State attribute missing");
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*wps_state != WPS_STATE_NOT_CONFIGURED &&
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    *wps_state != WPS_STATE_CONFIGURED) {
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Wi-Fi Protected "
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Setup State attribute value 0x%x", *wps_state);
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_ap_setup_locked(const u8 *ap_setup_locked,
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int mandatory)
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ap_setup_locked == NULL) {
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: AP Setup Locked "
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*ap_setup_locked > 1) {
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid AP Setup Locked "
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *ap_setup_locked);
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_selected_registrar(const u8 *selected_registrar,
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   int mandatory)
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (selected_registrar == NULL) {
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*selected_registrar > 1) {
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *selected_registrar);
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_sel_reg_config_methods(const u8 *config_methods,
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					       int wps2, int mandatory)
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (config_methods == NULL) {
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Selected Registrar "
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Configuration Methods attribute missing");
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(config_methods);
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!valid_config_methods(val, wps2)) {
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Selected Registrar "
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Configuration Methods attribute value 0x%04x",
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   val);
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_authorized_macs(const u8 *authorized_macs, size_t len,
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int mandatory)
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (authorized_macs == NULL) {
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Authorized MACs "
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len > 30 && (len % ETH_ALEN) != 0) {
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump(MSG_INFO, "WPS-STRICT: Invalid Authorized "
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    "MACs attribute value", authorized_macs, len);
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_msg_type(const u8 *msg_type, int mandatory)
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (msg_type == NULL) {
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Message Type "
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*msg_type < WPS_Beacon || *msg_type > WPS_WSC_DONE) {
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Message Type "
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%x", *msg_type);
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_mac_addr(const u8 *mac_addr, int mandatory)
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (mac_addr == NULL) {
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: MAC Address "
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (mac_addr[0] & 0x01) {
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid MAC Address "
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value " MACSTR, MAC2STR(mac_addr));
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_enrollee_nonce(const u8 *enrollee_nonce, int mandatory)
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (enrollee_nonce == NULL) {
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Enrollee Nonce "
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_registrar_nonce(const u8 *registrar_nonce,
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					int mandatory)
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (registrar_nonce == NULL) {
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Registrar Nonce "
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_public_key(const u8 *public_key, size_t len,
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int mandatory)
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (public_key == NULL) {
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Public Key "
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len != 192) {
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Public Key "
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute length %d", (int) len);
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int num_bits_set(u16 val)
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int c;
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (c = 0; val; c++)
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		val &= val - 1;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return c;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_auth_type_flags(const u8 *flags, int mandatory)
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags == NULL) {
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Flags attribute missing");
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(flags);
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((val & ~WPS_AUTH_TYPES) || !(val & WPS_AUTH_WPA2PSK)) {
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Flags attribute value 0x%04x", val);
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_auth_type(const u8 *type, int mandatory)
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (type == NULL) {
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Authentication Type "
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(type);
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((val & ~WPS_AUTH_TYPES) || val == 0 ||
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (num_bits_set(val) > 1 &&
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     val != (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK))) {
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Authentication Type "
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%04x", val);
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_encr_type_flags(const u8 *flags, int mandatory)
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags == NULL) {
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Flags attribute missing");
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(flags);
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((val & ~WPS_ENCR_TYPES) || !(val & WPS_ENCR_AES)) {
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Flags attribute value 0x%04x", val);
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_encr_type(const u8 *type, int mandatory)
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 val;
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (type == NULL) {
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Encryption Type "
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	val = WPA_GET_BE16(type);
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((val & ~WPS_ENCR_TYPES) || val == 0 ||
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (num_bits_set(val) > 1 && val != (WPS_ENCR_TKIP | WPS_ENCR_AES))) {
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encryption Type "
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute value 0x%04x", val);
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_conn_type_flags(const u8 *flags, int mandatory)
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags == NULL) {
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Connection Type "
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Flags attribute missing");
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((*flags & ~(WPS_CONN_ESS | WPS_CONN_IBSS)) ||
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(*flags & WPS_CONN_ESS)) {
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Connection Type "
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Flags attribute value 0x%02x", *flags);
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_os_version(const u8 *os_version, int mandatory)
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_version == NULL) {
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: OS Version "
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_authenticator(const u8 *authenticator, int mandatory)
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (authenticator == NULL) {
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Authenticator "
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_e_hash1(const u8 *hash, int mandatory)
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hash == NULL) {
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash1 "
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_e_hash2(const u8 *hash, int mandatory)
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hash == NULL) {
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: E-Hash2 "
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_r_hash1(const u8 *hash, int mandatory)
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hash == NULL) {
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash1 "
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_r_hash2(const u8 *hash, int mandatory)
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hash == NULL) {
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: R-Hash2 "
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_encr_settings(const u8 *encr_settings, size_t len,
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int mandatory)
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (encr_settings == NULL) {
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Encrypted Settings "
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (len < 16) {
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Encrypted Settings "
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "attribute length %d", (int) len);
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_settings_delay_time(const u8 *delay, int mandatory)
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (delay == NULL) {
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Settings Delay Time "
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_r_snonce1(const u8 *nonce, int mandatory)
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (nonce == NULL) {
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce1 "
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_r_snonce2(const u8 *nonce, int mandatory)
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (nonce == NULL) {
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: R-SNonce2 "
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_e_snonce1(const u8 *nonce, int mandatory)
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (nonce == NULL) {
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce1 "
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_e_snonce2(const u8 *nonce, int mandatory)
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (nonce == NULL) {
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: E-SNonce2 "
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_key_wrap_auth(const u8 *auth, int mandatory)
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (auth == NULL) {
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Key Wrap "
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Authenticator attribute missing");
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_ssid(const u8 *ssid, size_t ssid_len, int mandatory)
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: SSID "
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid_len == 0 || ssid[ssid_len - 1] == 0) {
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii(MSG_INFO, "WPS-STRICT: Invalid SSID "
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  "attribute value", ssid, ssid_len);
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_network_key_index(const u8 *idx, int mandatory)
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (idx == NULL) {
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key Index "
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_network_idx(const u8 *idx, int mandatory)
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (idx == NULL) {
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Network Index "
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_network_key(const u8 *key, size_t key_len,
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    const u8 *encr_type, int mandatory)
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (key == NULL) {
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (((encr_type == NULL || WPA_GET_BE16(encr_type) != WPS_ENCR_WEP) &&
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     key_len > 8 && key_len < 64 && key[key_len - 1] == 0) ||
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    key_len > 64) {
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_ascii_key(MSG_INFO, "WPS-STRICT: Invalid Network "
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      "Key attribute value", key, key_len);
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_network_key_shareable(const u8 *val, int mandatory)
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (val == NULL) {
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Network Key "
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "Shareable attribute missing");
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (*val > 1) {
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Network Key "
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Shareable attribute value 0x%x", *val);
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_cred(const u8 *cred, size_t len)
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpabuf buf;
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (cred == NULL)
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_set(&buf, cred, len);
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(&buf, &attr) < 0) {
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse Credential");
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_network_idx(attr.network_idx, 1) ||
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_ssid(attr.ssid, attr.ssid_len, 1) ||
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type(attr.auth_type, 1) ||
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type(attr.encr_type, 1) ||
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key(attr.network_key, attr.network_key_len,
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     attr.encr_type, 1) ||
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_mac_addr(attr.mac_addr, 1) ||
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key_shareable(attr.network_key_shareable, 0))
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	{
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Credential");
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wps_validate_credential(const u8 *cred[], size_t len[], size_t num,
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int mandatory)
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num == 0) {
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (mandatory) {
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_INFO, "WPS-STRICT: Credential "
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "attribute missing");
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < num; i++) {
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps_validate_cred(cred[i], len[i]) < 0)
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_beacon(const struct wpabuf *wps_ie)
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2, sel_reg;
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in Beacon frame");
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(wps_ie, &attr) < 0) {
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Beacon frame");
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel_reg = attr.selected_registrar != NULL &&
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*attr.selected_registrar != 0;
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_wps_state(attr.wps_state, 1) ||
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						wps2, sel_reg) ||
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_e(attr.uuid_e, 0) ||
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 0) ||
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authorized_macs(attr.authorized_macs,
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 attr.authorized_macs_len, 0)) {
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Beacon frame");
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_beacon_probe_resp(const struct wpabuf *wps_ie, int probe,
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   const u8 *addr)
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2, sel_reg;
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%sProbe Response frame", probe ? "" : "Beacon/");
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(wps_ie, &attr) < 0) {
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "%sProbe Response frame", probe ? "" : "Beacon/");
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel_reg = attr.selected_registrar != NULL &&
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*attr.selected_registrar != 0;
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_wps_state(attr.wps_state, 1) ||
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_ap_setup_locked(attr.ap_setup_locked, 0) ||
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_selected_registrar(attr.selected_registrar, 0) ||
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						wps2, sel_reg) ||
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_response_type(attr.response_type, probe) ||
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_e(attr.uuid_e, probe) ||
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      probe) ||
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_name(attr.model_name, attr.model_name_len,
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    probe) ||
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_number(attr.model_number, attr.model_number_len,
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      probe) ||
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_serial_number(attr.serial_number,
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.serial_number_len, probe) ||
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_primary_dev_type(attr.primary_dev_type, probe) ||
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, probe) ||
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_ap_config_methods(attr.config_methods, wps2, probe) ||
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 0) ||
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authorized_macs(attr.authorized_macs,
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 attr.authorized_macs_len, 0)) {
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid %sProbe Response "
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "frame from " MACSTR, probe ? "" : "Beacon/",
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(addr));
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_probe_req(const struct wpabuf *wps_ie, const u8 *addr)
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Probe Request frame");
11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(wps_ie, &attr) < 0) {
11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Probe Request frame");
11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_request_type(attr.request_type, 1) ||
11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_e(attr.uuid_e, attr.uuid_r == NULL) ||
12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_r(attr.uuid_r, attr.uuid_e == NULL) ||
12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 1) ||
12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_assoc_state(attr.assoc_state, 1) ||
12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_error(attr.config_error, 1) ||
12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      wps2) ||
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_name(attr.model_name, attr.model_name_len,
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    wps2) ||
12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_number(attr.model_number, attr.model_number_len,
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      wps2) ||
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, wps2) ||
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_request_to_enroll(attr.request_to_enroll, 0) ||
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_req_dev_type(attr.req_dev_type, attr.num_req_dev_type,
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      0)) {
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid Probe Request "
12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "frame from " MACSTR, MAC2STR(addr));
12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_assoc_req(const struct wpabuf *wps_ie)
12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(Re)Association Request frame");
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(wps_ie, &attr) < 0) {
12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(Re)Association Request frame");
12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_request_type(attr.request_type, 1) ||
12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Request frame");
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_assoc_resp(const struct wpabuf *wps_ie)
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_ie == NULL) {
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No WPS IE in "
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(Re)Association Response frame");
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(wps_ie, &attr) < 0) {
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse WPS IE in "
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "(Re)Association Response frame");
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_response_type(attr.response_type, 1) ||
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid (Re)Association "
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Response frame");
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m1(const struct wpabuf *tlvs)
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M1");
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M1");
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_e(attr.uuid_e, 1) ||
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_mac_addr(attr.mac_addr, 1) ||
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_wps_state(attr.wps_state, 1) ||
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_number(attr.model_number, attr.model_number_len,
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_serial_number(attr.serial_number,
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.serial_number_len, 1) ||
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 1) ||
13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_assoc_state(attr.assoc_state, 1) ||
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_error(attr.config_error, 1) ||
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_os_version(attr.os_version, 1) ||
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_request_to_enroll(attr.request_to_enroll, 0)) {
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M1");
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m2(const struct wpabuf *tlvs)
13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2");
13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M2");
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_r(attr.uuid_r, 1) ||
13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_public_key(attr.public_key, attr.public_key_len, 1) ||
13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_number(attr.model_number, attr.model_number_len,
13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_serial_number(attr.serial_number,
13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.serial_number_len, 1) ||
13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 1) ||
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_assoc_state(attr.assoc_state, 1) ||
13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_error(attr.config_error, 1) ||
13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, 1) ||
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_os_version(attr.os_version, 1) ||
13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2");
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m2d(const struct wpabuf *tlvs)
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M2D");
14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M2D");
14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_r(attr.uuid_r, 1) ||
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type_flags(attr.auth_type_flags, 1) ||
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type_flags(attr.encr_type_flags, 1) ||
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_conn_type_flags(attr.conn_type_flags, 1) ||
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_methods(attr.config_methods, wps2, 1) ||
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_manufacturer(attr.manufacturer, attr.manufacturer_len,
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_name(attr.model_name, attr.model_name_len, 1) ||
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_model_number(attr.model_number, attr.model_number_len,
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      1) ||
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_serial_number(attr.serial_number,
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.serial_number_len, 1) ||
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_primary_dev_type(attr.primary_dev_type, 1) ||
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_name(attr.dev_name, attr.dev_name_len, 1) ||
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_rf_bands(attr.rf_bands, 1) ||
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_assoc_state(attr.assoc_state, 1) ||
14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_error(attr.config_error, 1) ||
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_os_version(attr.os_version, 1) ||
14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M2D");
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m3(const struct wpabuf *tlvs)
14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M3");
14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M3");
14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_e_hash1(attr.e_hash1, 1) ||
14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_e_hash2(attr.e_hash2, 1) ||
14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M3");
14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m4(const struct wpabuf *tlvs)
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4");
14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M4");
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_r_hash1(attr.r_hash1, 1) ||
15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_r_hash2(attr.r_hash2, 1) ||
15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_settings(attr.encr_settings,
15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.encr_settings_len, 1) ||
15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4");
15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m4_encr(const struct wpabuf *tlvs, int wps2)
15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M4 encrypted "
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M4 encrypted settings");
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_r_snonce1(attr.r_snonce1, 1) ||
15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M4 encrypted "
15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m5(const struct wpabuf *tlvs)
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5");
15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M5");
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_settings(attr.encr_settings,
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.encr_settings_len, 1) ||
15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5");
15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m5_encr(const struct wpabuf *tlvs, int wps2)
15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M5 encrypted "
15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M5 encrypted settings");
16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_e_snonce1(attr.e_snonce1, 1) ||
16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M5 encrypted "
16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m6(const struct wpabuf *tlvs)
16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6");
16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M6");
16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_settings(attr.encr_settings,
16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.encr_settings_len, 1) ||
16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6");
16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m6_encr(const struct wpabuf *tlvs, int wps2)
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M6 encrypted "
16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M6 encrypted settings");
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_r_snonce2(attr.r_snonce2, 1) ||
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M6 encrypted "
16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m7(const struct wpabuf *tlvs)
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7");
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M7");
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_settings(attr.encr_settings,
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.encr_settings_len, 1) ||
17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_settings_delay_time(attr.settings_delay_time, 0) ||
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7");
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m7_encr(const struct wpabuf *tlvs, int ap, int wps2)
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M7 encrypted "
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M7 encrypted settings");
17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_e_snonce2(attr.e_snonce2, 1) ||
17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_ssid(attr.ssid, attr.ssid_len, !ap) ||
17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_mac_addr(attr.mac_addr, !ap) ||
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type(attr.auth_type, !ap) ||
17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type(attr.encr_type, !ap) ||
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key(attr.network_key, attr.network_key_len,
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     attr.encr_type, !ap) ||
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M7 encrypted "
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m8(const struct wpabuf *tlvs)
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8");
17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M8");
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_settings(attr.encr_settings,
17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       attr.encr_settings_len, 1) ||
17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authenticator(attr.authenticator, 1)) {
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8");
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_m8_encr(const struct wpabuf *tlvs, int ap, int wps2)
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in M8 encrypted "
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in M8 encrypted settings");
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_ssid(attr.ssid, attr.ssid_len, ap) ||
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_auth_type(attr.auth_type, ap) ||
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_encr_type(attr.encr_type, ap) ||
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_network_key_index(attr.network_key_idx, 0) ||
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_mac_addr(attr.mac_addr, ap) ||
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_credential(attr.cred, attr.cred_len, attr.num_cred,
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    !ap) ||
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_key_wrap_auth(attr.key_wrap_auth, 1)) {
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid M8 encrypted "
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "settings");
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_wsc_ack(const struct wpabuf *tlvs)
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_ACK");
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in WSC_ACK");
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_ACK");
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_wsc_nack(const struct wpabuf *tlvs)
18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_NACK");
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in WSC_NACK");
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_config_error(attr.config_error, 1) ||
18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_NACK");
18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_wsc_done(const struct wpabuf *tlvs)
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in WSC_Done");
19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in WSC_Done");
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_msg_type(attr.msg_type, 1) ||
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_enrollee_nonce(attr.enrollee_nonce, 1) ||
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_registrar_nonce(attr.registrar_nonce, 1) ||
19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2)) {
19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC_Done");
19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wps_validate_upnp_set_selected_registrar(const struct wpabuf *tlvs)
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_parse_attr attr;
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wps2;
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int sel_reg;
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlvs == NULL) {
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: No TLVs in "
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "SetSelectedRegistrar");
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_parse_msg(tlvs, &attr) < 0) {
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Failed to parse attributes "
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in SetSelectedRegistrar");
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps2 = attr.version2 != NULL;
19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel_reg = attr.selected_registrar != NULL &&
19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		*attr.selected_registrar != 0;
19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wps_validate_version(attr.version, 1) ||
19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_dev_password_id(attr.dev_password_id, sel_reg) ||
19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_sel_reg_config_methods(attr.sel_reg_config_methods,
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						wps2, sel_reg) ||
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_version2(attr.version2, wps2) ||
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_authorized_macs(attr.authorized_macs,
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 attr.authorized_macs_len, wps2) ||
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wps_validate_uuid_r(attr.uuid_r, wps2)) {
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_INFO, "WPS-STRICT: Invalid "
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "SetSelectedRegistrar");
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef WPS_STRICT_WPS2
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps2)
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* WPS_STRICT_WPS2 */
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* WPS_STRICT_WPS2 */
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1978