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