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