1 /* 2 * Wi-Fi Protected Setup - attribute building 3 * Copyright (c) 2008-2016, Jouni Malinen <j (at) w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "crypto/aes_wrap.h" 13 #include "crypto/crypto.h" 14 #include "crypto/dh_group5.h" 15 #include "crypto/sha256.h" 16 #include "crypto/random.h" 17 #include "common/ieee802_11_defs.h" 18 #include "wps_i.h" 19 20 21 int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg) 22 { 23 struct wpabuf *pubkey = NULL; 24 25 wpa_printf(MSG_DEBUG, "WPS: * Public Key"); 26 wpabuf_clear_free(wps->dh_privkey); 27 wps->dh_privkey = NULL; 28 if (wps->dev_pw_id != DEV_PW_DEFAULT && wps->wps->dh_privkey && 29 wps->wps->dh_ctx) { 30 wpa_printf(MSG_DEBUG, "WPS: Using pre-configured DH keys"); 31 if (wps->wps->dh_pubkey == NULL) { 32 wpa_printf(MSG_DEBUG, 33 "WPS: wps->wps->dh_pubkey == NULL"); 34 return -1; 35 } 36 wps->dh_privkey = wpabuf_dup(wps->wps->dh_privkey); 37 wps->dh_ctx = wps->wps->dh_ctx; 38 wps->wps->dh_ctx = NULL; 39 pubkey = wpabuf_dup(wps->wps->dh_pubkey); 40 #ifdef CONFIG_WPS_NFC 41 } else if ((wps->dev_pw_id >= 0x10 || 42 wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) && 43 (wps->wps->ap || 44 (wps->wps->ap_nfc_dh_pubkey && 45 wps->wps->ap_nfc_dev_pw_id == 46 DEV_PW_NFC_CONNECTION_HANDOVER && 47 wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)) && 48 (wps->dev_pw_id == wps->wps->ap_nfc_dev_pw_id || 49 wps->wps->ap_nfc_dh_pubkey)) { 50 wpa_printf(MSG_DEBUG, "WPS: Using NFC password token DH keys"); 51 if (wps->wps->ap_nfc_dh_privkey == NULL) { 52 wpa_printf(MSG_DEBUG, 53 "WPS: wps->wps->ap_nfc_dh_privkey == NULL"); 54 return -1; 55 } 56 if (wps->wps->ap_nfc_dh_pubkey == NULL) { 57 wpa_printf(MSG_DEBUG, 58 "WPS: wps->wps->ap_nfc_dh_pubkey == NULL"); 59 return -1; 60 } 61 wps->dh_privkey = wpabuf_dup(wps->wps->ap_nfc_dh_privkey); 62 pubkey = wpabuf_dup(wps->wps->ap_nfc_dh_pubkey); 63 if (wps->dh_privkey && pubkey) 64 wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, pubkey); 65 #endif /* CONFIG_WPS_NFC */ 66 } else { 67 wpa_printf(MSG_DEBUG, "WPS: Generate new DH keys"); 68 dh5_free(wps->dh_ctx); 69 wps->dh_ctx = dh5_init(&wps->dh_privkey, &pubkey); 70 pubkey = wpabuf_zeropad(pubkey, 192); 71 } 72 if (wps->dh_ctx == NULL || wps->dh_privkey == NULL || pubkey == NULL) { 73 wpa_printf(MSG_DEBUG, "WPS: Failed to initialize " 74 "Diffie-Hellman handshake"); 75 wpabuf_free(pubkey); 76 return -1; 77 } 78 wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey); 79 wpa_hexdump_buf(MSG_DEBUG, "WPS: DH own Public Key", pubkey); 80 81 wpabuf_put_be16(msg, ATTR_PUBLIC_KEY); 82 wpabuf_put_be16(msg, wpabuf_len(pubkey)); 83 wpabuf_put_buf(msg, pubkey); 84 85 if (wps->registrar) { 86 wpabuf_free(wps->dh_pubkey_r); 87 wps->dh_pubkey_r = pubkey; 88 } else { 89 wpabuf_free(wps->dh_pubkey_e); 90 wps->dh_pubkey_e = pubkey; 91 } 92 93 return 0; 94 } 95 96 97 int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type) 98 { 99 wpa_printf(MSG_DEBUG, "WPS: * Request Type"); 100 wpabuf_put_be16(msg, ATTR_REQUEST_TYPE); 101 wpabuf_put_be16(msg, 1); 102 wpabuf_put_u8(msg, type); 103 return 0; 104 } 105 106 107 int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type) 108 { 109 wpa_printf(MSG_DEBUG, "WPS: * Response Type (%d)", type); 110 wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE); 111 wpabuf_put_be16(msg, 1); 112 wpabuf_put_u8(msg, type); 113 return 0; 114 } 115 116 117 int wps_build_config_methods(struct wpabuf *msg, u16 methods) 118 { 119 wpa_printf(MSG_DEBUG, "WPS: * Config Methods (%x)", methods); 120 wpabuf_put_be16(msg, ATTR_CONFIG_METHODS); 121 wpabuf_put_be16(msg, 2); 122 wpabuf_put_be16(msg, methods); 123 return 0; 124 } 125 126 127 int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid) 128 { 129 if (wpabuf_tailroom(msg) < 4 + WPS_UUID_LEN) 130 return -1; 131 wpa_printf(MSG_DEBUG, "WPS: * UUID-E"); 132 wpabuf_put_be16(msg, ATTR_UUID_E); 133 wpabuf_put_be16(msg, WPS_UUID_LEN); 134 wpabuf_put_data(msg, uuid, WPS_UUID_LEN); 135 return 0; 136 } 137 138 139 int wps_build_dev_password_id(struct wpabuf *msg, u16 id) 140 { 141 wpa_printf(MSG_DEBUG, "WPS: * Device Password ID (%d)", id); 142 wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID); 143 wpabuf_put_be16(msg, 2); 144 wpabuf_put_be16(msg, id); 145 return 0; 146 } 147 148 149 int wps_build_config_error(struct wpabuf *msg, u16 err) 150 { 151 wpa_printf(MSG_DEBUG, "WPS: * Configuration Error (%d)", err); 152 wpabuf_put_be16(msg, ATTR_CONFIG_ERROR); 153 wpabuf_put_be16(msg, 2); 154 wpabuf_put_be16(msg, err); 155 return 0; 156 } 157 158 159 int wps_build_authenticator(struct wps_data *wps, struct wpabuf *msg) 160 { 161 u8 hash[SHA256_MAC_LEN]; 162 const u8 *addr[2]; 163 size_t len[2]; 164 165 if (wps->last_msg == NULL) { 166 wpa_printf(MSG_DEBUG, "WPS: Last message not available for " 167 "building authenticator"); 168 return -1; 169 } 170 171 /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*) 172 * (M_curr* is M_curr without the Authenticator attribute) 173 */ 174 addr[0] = wpabuf_head(wps->last_msg); 175 len[0] = wpabuf_len(wps->last_msg); 176 addr[1] = wpabuf_head(msg); 177 len[1] = wpabuf_len(msg); 178 hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash); 179 180 wpa_printf(MSG_DEBUG, "WPS: * Authenticator"); 181 wpabuf_put_be16(msg, ATTR_AUTHENTICATOR); 182 wpabuf_put_be16(msg, WPS_AUTHENTICATOR_LEN); 183 wpabuf_put_data(msg, hash, WPS_AUTHENTICATOR_LEN); 184 185 return 0; 186 } 187 188 189 int wps_build_version(struct wpabuf *msg) 190 { 191 /* 192 * Note: This attribute is deprecated and set to hardcoded 0x10 for 193 * backwards compatibility reasons. The real version negotiation is 194 * done with Version2. 195 */ 196 if (wpabuf_tailroom(msg) < 5) 197 return -1; 198 wpa_printf(MSG_DEBUG, "WPS: * Version (hardcoded 0x10)"); 199 wpabuf_put_be16(msg, ATTR_VERSION); 200 wpabuf_put_be16(msg, 1); 201 wpabuf_put_u8(msg, 0x10); 202 return 0; 203 } 204 205 206 int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll, 207 const u8 *auth_macs, size_t auth_macs_count, 208 u8 multi_ap_subelem) 209 { 210 u8 *len; 211 212 #ifdef CONFIG_WPS_TESTING 213 if (WPS_VERSION == 0x10) 214 return 0; 215 #endif /* CONFIG_WPS_TESTING */ 216 217 if (wpabuf_tailroom(msg) < 218 7 + 3 + (req_to_enroll ? 3 : 0) + 219 (auth_macs ? 2 + auth_macs_count * ETH_ALEN : 0)) 220 return -1; 221 wpabuf_put_be16(msg, ATTR_VENDOR_EXT); 222 len = wpabuf_put(msg, 2); /* to be filled */ 223 wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA); 224 225 wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); 226 wpabuf_put_u8(msg, WFA_ELEM_VERSION2); 227 wpabuf_put_u8(msg, 1); 228 wpabuf_put_u8(msg, WPS_VERSION); 229 230 if (req_to_enroll) { 231 wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)"); 232 wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL); 233 wpabuf_put_u8(msg, 1); 234 wpabuf_put_u8(msg, 1); 235 } 236 237 if (auth_macs && auth_macs_count) { 238 size_t i; 239 wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", 240 (int) auth_macs_count); 241 wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS); 242 wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN); 243 wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN); 244 for (i = 0; i < auth_macs_count; i++) 245 wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR, 246 MAC2STR(&auth_macs[i * ETH_ALEN])); 247 } 248 249 if (multi_ap_subelem) { 250 wpa_printf(MSG_DEBUG, "WPS: * Multi-AP (0x%x)", 251 multi_ap_subelem); 252 wpabuf_put_u8(msg, WFA_ELEM_MULTI_AP); 253 wpabuf_put_u8(msg, 1); /* length */ 254 wpabuf_put_u8(msg, multi_ap_subelem); 255 } 256 257 WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2); 258 259 #ifdef CONFIG_WPS_TESTING 260 if (WPS_VERSION > 0x20) { 261 if (wpabuf_tailroom(msg) < 5) 262 return -1; 263 wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " 264 "attribute"); 265 wpabuf_put_be16(msg, ATTR_EXTENSIBILITY_TEST); 266 wpabuf_put_be16(msg, 1); 267 wpabuf_put_u8(msg, 42); 268 } 269 #endif /* CONFIG_WPS_TESTING */ 270 return 0; 271 } 272 273 274 int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type) 275 { 276 wpa_printf(MSG_DEBUG, "WPS: * Message Type (%d)", msg_type); 277 wpabuf_put_be16(msg, ATTR_MSG_TYPE); 278 wpabuf_put_be16(msg, 1); 279 wpabuf_put_u8(msg, msg_type); 280 return 0; 281 } 282 283 284 int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg) 285 { 286 wpa_printf(MSG_DEBUG, "WPS: * Enrollee Nonce"); 287 wpabuf_put_be16(msg, ATTR_ENROLLEE_NONCE); 288 wpabuf_put_be16(msg, WPS_NONCE_LEN); 289 wpabuf_put_data(msg, wps->nonce_e, WPS_NONCE_LEN); 290 return 0; 291 } 292 293 294 int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg) 295 { 296 wpa_printf(MSG_DEBUG, "WPS: * Registrar Nonce"); 297 wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE); 298 wpabuf_put_be16(msg, WPS_NONCE_LEN); 299 wpabuf_put_data(msg, wps->nonce_r, WPS_NONCE_LEN); 300 return 0; 301 } 302 303 304 int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg) 305 { 306 u16 auth_types = WPS_AUTH_TYPES; 307 /* WPA/WPA2-Enterprise enrollment not supported through WPS */ 308 auth_types &= ~WPS_AUTH_WPA; 309 auth_types &= ~WPS_AUTH_WPA2; 310 auth_types &= ~WPS_AUTH_SHARED; 311 #ifdef CONFIG_WPS_TESTING 312 if (wps_force_auth_types_in_use) { 313 wpa_printf(MSG_DEBUG, 314 "WPS: Testing - replace auth type 0x%x with 0x%x", 315 auth_types, wps_force_auth_types); 316 auth_types = wps_force_auth_types; 317 } 318 #endif /* CONFIG_WPS_TESTING */ 319 wpa_printf(MSG_DEBUG, "WPS: * Authentication Type Flags (0x%x)", 320 auth_types); 321 wpabuf_put_be16(msg, ATTR_AUTH_TYPE_FLAGS); 322 wpabuf_put_be16(msg, 2); 323 wpabuf_put_be16(msg, auth_types); 324 return 0; 325 } 326 327 328 int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg) 329 { 330 u16 encr_types = WPS_ENCR_TYPES; 331 encr_types &= ~WPS_ENCR_WEP; 332 #ifdef CONFIG_WPS_TESTING 333 if (wps_force_encr_types_in_use) { 334 wpa_printf(MSG_DEBUG, 335 "WPS: Testing - replace encr type 0x%x with 0x%x", 336 encr_types, wps_force_encr_types); 337 encr_types = wps_force_encr_types; 338 } 339 #endif /* CONFIG_WPS_TESTING */ 340 wpa_printf(MSG_DEBUG, "WPS: * Encryption Type Flags (0x%x)", 341 encr_types); 342 wpabuf_put_be16(msg, ATTR_ENCR_TYPE_FLAGS); 343 wpabuf_put_be16(msg, 2); 344 wpabuf_put_be16(msg, encr_types); 345 return 0; 346 } 347 348 349 int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg) 350 { 351 wpa_printf(MSG_DEBUG, "WPS: * Connection Type Flags"); 352 wpabuf_put_be16(msg, ATTR_CONN_TYPE_FLAGS); 353 wpabuf_put_be16(msg, 1); 354 wpabuf_put_u8(msg, WPS_CONN_ESS); 355 return 0; 356 } 357 358 359 int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg) 360 { 361 wpa_printf(MSG_DEBUG, "WPS: * Association State"); 362 wpabuf_put_be16(msg, ATTR_ASSOC_STATE); 363 wpabuf_put_be16(msg, 2); 364 wpabuf_put_be16(msg, WPS_ASSOC_NOT_ASSOC); 365 return 0; 366 } 367 368 369 int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg) 370 { 371 u8 hash[SHA256_MAC_LEN]; 372 373 wpa_printf(MSG_DEBUG, "WPS: * Key Wrap Authenticator"); 374 hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, wpabuf_head(msg), 375 wpabuf_len(msg), hash); 376 377 wpabuf_put_be16(msg, ATTR_KEY_WRAP_AUTH); 378 wpabuf_put_be16(msg, WPS_KWA_LEN); 379 wpabuf_put_data(msg, hash, WPS_KWA_LEN); 380 return 0; 381 } 382 383 384 int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg, 385 struct wpabuf *plain) 386 { 387 size_t pad_len; 388 const size_t block_size = 16; 389 u8 *iv, *data; 390 391 wpa_printf(MSG_DEBUG, "WPS: * Encrypted Settings"); 392 393 /* PKCS#5 v2.0 pad */ 394 pad_len = block_size - wpabuf_len(plain) % block_size; 395 os_memset(wpabuf_put(plain, pad_len), pad_len, pad_len); 396 397 wpabuf_put_be16(msg, ATTR_ENCR_SETTINGS); 398 wpabuf_put_be16(msg, block_size + wpabuf_len(plain)); 399 400 iv = wpabuf_put(msg, block_size); 401 if (random_get_bytes(iv, block_size) < 0) 402 return -1; 403 404 data = wpabuf_put(msg, 0); 405 wpabuf_put_buf(msg, plain); 406 if (aes_128_cbc_encrypt(wps->keywrapkey, iv, data, wpabuf_len(plain))) 407 return -1; 408 409 return 0; 410 } 411 412 413 #ifdef CONFIG_WPS_OOB 414 int wps_build_oob_dev_pw(struct wpabuf *msg, u16 dev_pw_id, 415 const struct wpabuf *pubkey, const u8 *dev_pw, 416 size_t dev_pw_len) 417 { 418 size_t hash_len; 419 const u8 *addr[1]; 420 u8 pubkey_hash[WPS_HASH_LEN]; 421 422 wpa_printf(MSG_DEBUG, "WPS: * OOB Device Password (dev_pw_id=%u)", 423 dev_pw_id); 424 addr[0] = wpabuf_head(pubkey); 425 hash_len = wpabuf_len(pubkey); 426 if (sha256_vector(1, addr, &hash_len, pubkey_hash) < 0) 427 return -1; 428 #ifdef CONFIG_WPS_TESTING 429 if (wps_corrupt_pkhash) { 430 wpa_hexdump(MSG_DEBUG, "WPS: Real Public Key Hash", 431 pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); 432 wpa_printf(MSG_INFO, "WPS: Testing - corrupt public key hash"); 433 pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN - 2]++; 434 } 435 #endif /* CONFIG_WPS_TESTING */ 436 437 wpabuf_put_be16(msg, ATTR_OOB_DEVICE_PASSWORD); 438 wpabuf_put_be16(msg, WPS_OOB_PUBKEY_HASH_LEN + 2 + dev_pw_len); 439 wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash", 440 pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); 441 wpabuf_put_data(msg, pubkey_hash, WPS_OOB_PUBKEY_HASH_LEN); 442 wpabuf_put_be16(msg, dev_pw_id); 443 if (dev_pw) { 444 wpa_hexdump_key(MSG_DEBUG, "WPS: OOB Device Password", 445 dev_pw, dev_pw_len); 446 wpabuf_put_data(msg, dev_pw, dev_pw_len); 447 } 448 449 return 0; 450 } 451 #endif /* CONFIG_WPS_OOB */ 452 453 454 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */ 455 struct wpabuf * wps_ie_encapsulate(struct wpabuf *data) 456 { 457 struct wpabuf *ie; 458 const u8 *pos, *end; 459 460 ie = wpabuf_alloc(wpabuf_len(data) + 100); 461 if (ie == NULL) { 462 wpabuf_free(data); 463 return NULL; 464 } 465 466 pos = wpabuf_head(data); 467 end = pos + wpabuf_len(data); 468 469 while (end > pos) { 470 size_t frag_len = end - pos; 471 if (frag_len > 251) 472 frag_len = 251; 473 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC); 474 wpabuf_put_u8(ie, 4 + frag_len); 475 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA); 476 wpabuf_put_data(ie, pos, frag_len); 477 pos += frag_len; 478 } 479 480 wpabuf_free(data); 481 482 return ie; 483 } 484 485 486 int wps_build_mac_addr(struct wpabuf *msg, const u8 *addr) 487 { 488 wpa_printf(MSG_DEBUG, "WPS: * MAC Address (" MACSTR ")", 489 MAC2STR(addr)); 490 wpabuf_put_be16(msg, ATTR_MAC_ADDR); 491 wpabuf_put_be16(msg, ETH_ALEN); 492 wpabuf_put_data(msg, addr, ETH_ALEN); 493 return 0; 494 } 495 496 497 int wps_build_rf_bands_attr(struct wpabuf *msg, u8 rf_bands) 498 { 499 wpa_printf(MSG_DEBUG, "WPS: * RF Bands (%x)", rf_bands); 500 wpabuf_put_be16(msg, ATTR_RF_BANDS); 501 wpabuf_put_be16(msg, 1); 502 wpabuf_put_u8(msg, rf_bands); 503 return 0; 504 } 505 506 507 int wps_build_ap_channel(struct wpabuf *msg, u16 ap_channel) 508 { 509 wpa_printf(MSG_DEBUG, "WPS: * AP Channel (%u)", ap_channel); 510 wpabuf_put_be16(msg, ATTR_AP_CHANNEL); 511 wpabuf_put_be16(msg, 2); 512 wpabuf_put_be16(msg, ap_channel); 513 return 0; 514 } 515