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 21static 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 40static 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 59static 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 78static 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 97static 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 128static 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 152static 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 173static 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 187static 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 201static 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 216static 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 238static 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 259static 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 281static 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 304static 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 324static 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 344static 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 364static 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 385static 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 405static 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 425static 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 440static 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 460static 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 480static 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 500static 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 525static 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 545static 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 564static 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 583static 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 597static 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 612static 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 632static 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 641static 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 663static 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 687static 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 709static 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 732static 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 752static 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 766static 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 780static 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 794static 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 808static 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 822static 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 836static 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 856static 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 870static 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 884static 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 898static 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 912static 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 926static 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 940static 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 959static 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 973static 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 987static 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 1009static 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 1028static 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 1060static 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 1083int 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 1121int 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 1180int 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 1227int 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 1256int 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 1285int 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 1341int 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 1396int 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 1448int 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 1484int 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 1522int 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 1553int 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 1589int 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 1620int 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 1656int 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 1687int 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 1724int 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 1762int 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 1798int 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 1835int 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 1869int 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 1904int 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 1938int 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