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