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