Home | History | Annotate | Download | only in wps
      1 /*
      2  * Wi-Fi Protected Setup - common functionality
      3  * Copyright (c) 2008-2009, Jouni Malinen <j (at) w1.fi>
      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 "includes.h"
     16 
     17 #include "common.h"
     18 #include "crypto/aes_wrap.h"
     19 #include "crypto/crypto.h"
     20 #include "crypto/dh_group5.h"
     21 #include "crypto/sha1.h"
     22 #include "crypto/sha256.h"
     23 #include "crypto/random.h"
     24 #include "wps_i.h"
     25 #include "wps_dev_attr.h"
     26 
     27 
     28 void wps_kdf(const u8 *key, const u8 *label_prefix, size_t label_prefix_len,
     29 	     const char *label, u8 *res, size_t res_len)
     30 {
     31 	u8 i_buf[4], key_bits[4];
     32 	const u8 *addr[4];
     33 	size_t len[4];
     34 	int i, iter;
     35 	u8 hash[SHA256_MAC_LEN], *opos;
     36 	size_t left;
     37 
     38 	WPA_PUT_BE32(key_bits, res_len * 8);
     39 
     40 	addr[0] = i_buf;
     41 	len[0] = sizeof(i_buf);
     42 	addr[1] = label_prefix;
     43 	len[1] = label_prefix_len;
     44 	addr[2] = (const u8 *) label;
     45 	len[2] = os_strlen(label);
     46 	addr[3] = key_bits;
     47 	len[3] = sizeof(key_bits);
     48 
     49 	iter = (res_len + SHA256_MAC_LEN - 1) / SHA256_MAC_LEN;
     50 	opos = res;
     51 	left = res_len;
     52 
     53 	for (i = 1; i <= iter; i++) {
     54 		WPA_PUT_BE32(i_buf, i);
     55 		hmac_sha256_vector(key, SHA256_MAC_LEN, 4, addr, len, hash);
     56 		if (i < iter) {
     57 			os_memcpy(opos, hash, SHA256_MAC_LEN);
     58 			opos += SHA256_MAC_LEN;
     59 			left -= SHA256_MAC_LEN;
     60 		} else
     61 			os_memcpy(opos, hash, left);
     62 	}
     63 }
     64 
     65 
     66 int wps_derive_keys(struct wps_data *wps)
     67 {
     68 	struct wpabuf *pubkey, *dh_shared;
     69 	u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN];
     70 	const u8 *addr[3];
     71 	size_t len[3];
     72 	u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN];
     73 
     74 	if (wps->dh_privkey == NULL) {
     75 		wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available");
     76 		return -1;
     77 	}
     78 
     79 	pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r;
     80 	if (pubkey == NULL) {
     81 		wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available");
     82 		return -1;
     83 	}
     84 
     85 	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey);
     86 	wpa_hexdump_buf(MSG_DEBUG, "WPS: DH peer Public Key", pubkey);
     87 	dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey);
     88 	dh5_free(wps->dh_ctx);
     89 	wps->dh_ctx = NULL;
     90 	dh_shared = wpabuf_zeropad(dh_shared, 192);
     91 	if (dh_shared == NULL) {
     92 		wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key");
     93 		return -1;
     94 	}
     95 
     96 	/* Own DH private key is not needed anymore */
     97 	wpabuf_free(wps->dh_privkey);
     98 	wps->dh_privkey = NULL;
     99 
    100 	wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared);
    101 
    102 	/* DHKey = SHA-256(g^AB mod p) */
    103 	addr[0] = wpabuf_head(dh_shared);
    104 	len[0] = wpabuf_len(dh_shared);
    105 	sha256_vector(1, addr, len, dhkey);
    106 	wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey));
    107 	wpabuf_free(dh_shared);
    108 
    109 	/* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */
    110 	addr[0] = wps->nonce_e;
    111 	len[0] = WPS_NONCE_LEN;
    112 	addr[1] = wps->mac_addr_e;
    113 	len[1] = ETH_ALEN;
    114 	addr[2] = wps->nonce_r;
    115 	len[2] = WPS_NONCE_LEN;
    116 	hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk);
    117 	wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk));
    118 
    119 	wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation",
    120 		keys, sizeof(keys));
    121 	os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN);
    122 	os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN);
    123 	os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN,
    124 		  WPS_EMSK_LEN);
    125 
    126 	wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey",
    127 			wps->authkey, WPS_AUTHKEY_LEN);
    128 	wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey",
    129 			wps->keywrapkey, WPS_KEYWRAPKEY_LEN);
    130 	wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN);
    131 
    132 	return 0;
    133 }
    134 
    135 
    136 void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
    137 		    size_t dev_passwd_len)
    138 {
    139 	u8 hash[SHA256_MAC_LEN];
    140 
    141 	hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, dev_passwd,
    142 		    (dev_passwd_len + 1) / 2, hash);
    143 	os_memcpy(wps->psk1, hash, WPS_PSK_LEN);
    144 	hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN,
    145 		    dev_passwd + (dev_passwd_len + 1) / 2,
    146 		    dev_passwd_len / 2, hash);
    147 	os_memcpy(wps->psk2, hash, WPS_PSK_LEN);
    148 
    149 	wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Device Password",
    150 			      dev_passwd, dev_passwd_len);
    151 	wpa_hexdump_key(MSG_DEBUG, "WPS: PSK1", wps->psk1, WPS_PSK_LEN);
    152 	wpa_hexdump_key(MSG_DEBUG, "WPS: PSK2", wps->psk2, WPS_PSK_LEN);
    153 }
    154 
    155 
    156 struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
    157 					  size_t encr_len)
    158 {
    159 	struct wpabuf *decrypted;
    160 	const size_t block_size = 16;
    161 	size_t i;
    162 	u8 pad;
    163 	const u8 *pos;
    164 
    165 	/* AES-128-CBC */
    166 	if (encr == NULL || encr_len < 2 * block_size || encr_len % block_size)
    167 	{
    168 		wpa_printf(MSG_DEBUG, "WPS: No Encrypted Settings received");
    169 		return NULL;
    170 	}
    171 
    172 	decrypted = wpabuf_alloc(encr_len - block_size);
    173 	if (decrypted == NULL)
    174 		return NULL;
    175 
    176 	wpa_hexdump(MSG_MSGDUMP, "WPS: Encrypted Settings", encr, encr_len);
    177 	wpabuf_put_data(decrypted, encr + block_size, encr_len - block_size);
    178 	if (aes_128_cbc_decrypt(wps->keywrapkey, encr, wpabuf_mhead(decrypted),
    179 				wpabuf_len(decrypted))) {
    180 		wpabuf_free(decrypted);
    181 		return NULL;
    182 	}
    183 
    184 	wpa_hexdump_buf_key(MSG_MSGDUMP, "WPS: Decrypted Encrypted Settings",
    185 			    decrypted);
    186 
    187 	pos = wpabuf_head_u8(decrypted) + wpabuf_len(decrypted) - 1;
    188 	pad = *pos;
    189 	if (pad > wpabuf_len(decrypted)) {
    190 		wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad value");
    191 		wpabuf_free(decrypted);
    192 		return NULL;
    193 	}
    194 	for (i = 0; i < pad; i++) {
    195 		if (*pos-- != pad) {
    196 			wpa_printf(MSG_DEBUG, "WPS: Invalid PKCS#5 v2.0 pad "
    197 				   "string");
    198 			wpabuf_free(decrypted);
    199 			return NULL;
    200 		}
    201 	}
    202 	decrypted->used -= pad;
    203 
    204 	return decrypted;
    205 }
    206 
    207 
    208 /**
    209  * wps_pin_checksum - Compute PIN checksum
    210  * @pin: Seven digit PIN (i.e., eight digit PIN without the checksum digit)
    211  * Returns: Checksum digit
    212  */
    213 unsigned int wps_pin_checksum(unsigned int pin)
    214 {
    215 	unsigned int accum = 0;
    216 	while (pin) {
    217 		accum += 3 * (pin % 10);
    218 		pin /= 10;
    219 		accum += pin % 10;
    220 		pin /= 10;
    221 	}
    222 
    223 	return (10 - accum % 10) % 10;
    224 }
    225 
    226 
    227 /**
    228  * wps_pin_valid - Check whether a PIN has a valid checksum
    229  * @pin: Eight digit PIN (i.e., including the checksum digit)
    230  * Returns: 1 if checksum digit is valid, or 0 if not
    231  */
    232 unsigned int wps_pin_valid(unsigned int pin)
    233 {
    234 	return wps_pin_checksum(pin / 10) == (pin % 10);
    235 }
    236 
    237 
    238 /**
    239  * wps_generate_pin - Generate a random PIN
    240  * Returns: Eight digit PIN (i.e., including the checksum digit)
    241  */
    242 unsigned int wps_generate_pin(void)
    243 {
    244 	unsigned int val;
    245 
    246 	/* Generate seven random digits for the PIN */
    247 	if (random_get_bytes((unsigned char *) &val, sizeof(val)) < 0) {
    248 		struct os_time now;
    249 		os_get_time(&now);
    250 		val = os_random() ^ now.sec ^ now.usec;
    251 	}
    252 	val %= 10000000;
    253 
    254 	/* Append checksum digit */
    255 	return val * 10 + wps_pin_checksum(val);
    256 }
    257 
    258 
    259 void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
    260 		    u16 config_error, u16 error_indication)
    261 {
    262 	union wps_event_data data;
    263 
    264 	if (wps->event_cb == NULL)
    265 		return;
    266 
    267 	os_memset(&data, 0, sizeof(data));
    268 	data.fail.msg = msg;
    269 	data.fail.config_error = config_error;
    270 	data.fail.error_indication = error_indication;
    271 	wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
    272 }
    273 
    274 
    275 void wps_success_event(struct wps_context *wps)
    276 {
    277 	if (wps->event_cb == NULL)
    278 		return;
    279 
    280 	wps->event_cb(wps->cb_ctx, WPS_EV_SUCCESS, NULL);
    281 }
    282 
    283 
    284 void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part)
    285 {
    286 	union wps_event_data data;
    287 
    288 	if (wps->event_cb == NULL)
    289 		return;
    290 
    291 	os_memset(&data, 0, sizeof(data));
    292 	data.pwd_auth_fail.enrollee = enrollee;
    293 	data.pwd_auth_fail.part = part;
    294 	wps->event_cb(wps->cb_ctx, WPS_EV_PWD_AUTH_FAIL, &data);
    295 }
    296 
    297 
    298 void wps_pbc_overlap_event(struct wps_context *wps)
    299 {
    300 	if (wps->event_cb == NULL)
    301 		return;
    302 
    303 	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_OVERLAP, NULL);
    304 }
    305 
    306 
    307 void wps_pbc_timeout_event(struct wps_context *wps)
    308 {
    309 	if (wps->event_cb == NULL)
    310 		return;
    311 
    312 	wps->event_cb(wps->cb_ctx, WPS_EV_PBC_TIMEOUT, NULL);
    313 }
    314 
    315 
    316 #ifdef CONFIG_WPS_OOB
    317 
    318 static struct wpabuf * wps_get_oob_cred(struct wps_context *wps)
    319 {
    320 	struct wps_data data;
    321 	struct wpabuf *plain;
    322 
    323 	plain = wpabuf_alloc(500);
    324 	if (plain == NULL) {
    325 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
    326 			   "credential");
    327 		return NULL;
    328 	}
    329 
    330 	os_memset(&data, 0, sizeof(data));
    331 	data.wps = wps;
    332 	data.auth_type = wps->auth_types;
    333 	data.encr_type = wps->encr_types;
    334 	if (wps_build_version(plain) ||
    335 	    wps_build_cred(&data, plain) ||
    336 	    wps_build_wfa_ext(plain, 0, NULL, 0)) {
    337 		wpabuf_free(plain);
    338 		return NULL;
    339 	}
    340 
    341 	return plain;
    342 }
    343 
    344 
    345 static struct wpabuf * wps_get_oob_dev_pwd(struct wps_context *wps)
    346 {
    347 	struct wpabuf *data;
    348 
    349 	data = wpabuf_alloc(9 + WPS_OOB_DEVICE_PASSWORD_ATTR_LEN);
    350 	if (data == NULL) {
    351 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
    352 			   "device password attribute");
    353 		return NULL;
    354 	}
    355 
    356 	wpabuf_free(wps->oob_conf.dev_password);
    357 	wps->oob_conf.dev_password =
    358 		wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1);
    359 	if (wps->oob_conf.dev_password == NULL) {
    360 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
    361 			   "device password");
    362 		wpabuf_free(data);
    363 		return NULL;
    364 	}
    365 
    366 	if (wps_build_version(data) ||
    367 	    wps_build_oob_dev_password(data, wps) ||
    368 	    wps_build_wfa_ext(data, 0, NULL, 0)) {
    369 		wpa_printf(MSG_ERROR, "WPS: Build OOB device password "
    370 			   "attribute error");
    371 		wpabuf_free(data);
    372 		return NULL;
    373 	}
    374 
    375 	return data;
    376 }
    377 
    378 
    379 static int wps_parse_oob_dev_pwd(struct wps_context *wps,
    380 				 struct wpabuf *data)
    381 {
    382 	struct oob_conf_data *oob_conf = &wps->oob_conf;
    383 	struct wps_parse_attr attr;
    384 	const u8 *pos;
    385 
    386 	if (wps_parse_msg(data, &attr) < 0 ||
    387 	    attr.oob_dev_password == NULL) {
    388 		wpa_printf(MSG_ERROR, "WPS: OOB device password not found");
    389 		return -1;
    390 	}
    391 
    392 	pos = attr.oob_dev_password;
    393 
    394 	oob_conf->pubkey_hash =
    395 		wpabuf_alloc_copy(pos, WPS_OOB_PUBKEY_HASH_LEN);
    396 	if (oob_conf->pubkey_hash == NULL) {
    397 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
    398 			   "public key hash");
    399 		return -1;
    400 	}
    401 	pos += WPS_OOB_PUBKEY_HASH_LEN;
    402 
    403 	wps->oob_dev_pw_id = WPA_GET_BE16(pos);
    404 	pos += sizeof(wps->oob_dev_pw_id);
    405 
    406 	oob_conf->dev_password =
    407 		wpabuf_alloc(WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1);
    408 	if (oob_conf->dev_password == NULL) {
    409 		wpa_printf(MSG_ERROR, "WPS: Failed to allocate memory for OOB "
    410 			   "device password");
    411 		return -1;
    412 	}
    413 	wpa_snprintf_hex_uppercase(wpabuf_put(oob_conf->dev_password,
    414 				   wpabuf_size(oob_conf->dev_password)),
    415 				   wpabuf_size(oob_conf->dev_password), pos,
    416 				   WPS_OOB_DEVICE_PASSWORD_LEN);
    417 
    418 	return 0;
    419 }
    420 
    421 
    422 static int wps_parse_oob_cred(struct wps_context *wps, struct wpabuf *data)
    423 {
    424 	struct wpabuf msg;
    425 	struct wps_parse_attr attr;
    426 	size_t i;
    427 
    428 	if (wps_parse_msg(data, &attr) < 0 || attr.num_cred <= 0) {
    429 		wpa_printf(MSG_ERROR, "WPS: OOB credential not found");
    430 		return -1;
    431 	}
    432 
    433 	for (i = 0; i < attr.num_cred; i++) {
    434 		struct wps_credential local_cred;
    435 		struct wps_parse_attr cattr;
    436 
    437 		os_memset(&local_cred, 0, sizeof(local_cred));
    438 		wpabuf_set(&msg, attr.cred[i], attr.cred_len[i]);
    439 		if (wps_parse_msg(&msg, &cattr) < 0 ||
    440 		    wps_process_cred(&cattr, &local_cred)) {
    441 			wpa_printf(MSG_ERROR, "WPS: Failed to parse OOB "
    442 				   "credential");
    443 			return -1;
    444 		}
    445 		wps->cred_cb(wps->cb_ctx, &local_cred);
    446 	}
    447 
    448 	return 0;
    449 }
    450 
    451 
    452 int wps_process_oob(struct wps_context *wps, struct oob_device_data *oob_dev,
    453 		    int registrar)
    454 {
    455 	struct wpabuf *data;
    456 	int ret, write_f, oob_method = wps->oob_conf.oob_method;
    457 	void *oob_priv;
    458 
    459 	write_f = oob_method == OOB_METHOD_DEV_PWD_E ? !registrar : registrar;
    460 
    461 	oob_priv = oob_dev->init_func(wps, oob_dev, registrar);
    462 	if (oob_priv == NULL) {
    463 		wpa_printf(MSG_ERROR, "WPS: Failed to initialize OOB device");
    464 		return -1;
    465 	}
    466 
    467 	if (write_f) {
    468 		if (oob_method == OOB_METHOD_CRED)
    469 			data = wps_get_oob_cred(wps);
    470 		else
    471 			data = wps_get_oob_dev_pwd(wps);
    472 
    473 		ret = 0;
    474 		if (data == NULL || oob_dev->write_func(oob_priv, data) < 0)
    475 			ret = -1;
    476 	} else {
    477 		data = oob_dev->read_func(oob_priv);
    478 		if (data == NULL)
    479 			ret = -1;
    480 		else {
    481 			if (oob_method == OOB_METHOD_CRED)
    482 				ret = wps_parse_oob_cred(wps, data);
    483 			else
    484 				ret = wps_parse_oob_dev_pwd(wps, data);
    485 		}
    486 	}
    487 	wpabuf_free(data);
    488 	oob_dev->deinit_func(oob_priv);
    489 
    490 	if (ret < 0) {
    491 		wpa_printf(MSG_ERROR, "WPS: Failed to process OOB data");
    492 		return -1;
    493 	}
    494 
    495 	return 0;
    496 }
    497 
    498 
    499 struct oob_device_data * wps_get_oob_device(char *device_type)
    500 {
    501 #ifdef CONFIG_WPS_UFD
    502 	if (os_strstr(device_type, "ufd") != NULL)
    503 		return &oob_ufd_device_data;
    504 #endif /* CONFIG_WPS_UFD */
    505 #ifdef CONFIG_WPS_NFC
    506 	if (os_strstr(device_type, "nfc") != NULL)
    507 		return &oob_nfc_device_data;
    508 #endif /* CONFIG_WPS_NFC */
    509 
    510 	return NULL;
    511 }
    512 
    513 
    514 #ifdef CONFIG_WPS_NFC
    515 struct oob_nfc_device_data * wps_get_oob_nfc_device(char *device_name)
    516 {
    517 	if (device_name == NULL)
    518 		return NULL;
    519 #ifdef CONFIG_WPS_NFC_PN531
    520 	if (os_strstr(device_name, "pn531") != NULL)
    521 		return &oob_nfc_pn531_device_data;
    522 #endif /* CONFIG_WPS_NFC_PN531 */
    523 
    524 	return NULL;
    525 }
    526 #endif /* CONFIG_WPS_NFC */
    527 
    528 
    529 int wps_get_oob_method(char *method)
    530 {
    531 	if (os_strstr(method, "pin-e") != NULL)
    532 		return OOB_METHOD_DEV_PWD_E;
    533 	if (os_strstr(method, "pin-r") != NULL)
    534 		return OOB_METHOD_DEV_PWD_R;
    535 	if (os_strstr(method, "cred") != NULL)
    536 		return OOB_METHOD_CRED;
    537 	return OOB_METHOD_UNKNOWN;
    538 }
    539 
    540 #endif /* CONFIG_WPS_OOB */
    541 
    542 
    543 int wps_dev_type_str2bin(const char *str, u8 dev_type[WPS_DEV_TYPE_LEN])
    544 {
    545 	const char *pos;
    546 
    547 	/* <categ>-<OUI>-<subcateg> */
    548 	WPA_PUT_BE16(dev_type, atoi(str));
    549 	pos = os_strchr(str, '-');
    550 	if (pos == NULL)
    551 		return -1;
    552 	pos++;
    553 	if (hexstr2bin(pos, &dev_type[2], 4))
    554 		return -1;
    555 	pos = os_strchr(pos, '-');
    556 	if (pos == NULL)
    557 		return -1;
    558 	pos++;
    559 	WPA_PUT_BE16(&dev_type[6], atoi(pos));
    560 
    561 
    562 	return 0;
    563 }
    564 
    565 
    566 char * wps_dev_type_bin2str(const u8 dev_type[WPS_DEV_TYPE_LEN], char *buf,
    567 			    size_t buf_len)
    568 {
    569 	int ret;
    570 
    571 	ret = os_snprintf(buf, buf_len, "%u-%08X-%u",
    572 			  WPA_GET_BE16(dev_type), WPA_GET_BE32(&dev_type[2]),
    573 			  WPA_GET_BE16(&dev_type[6]));
    574 	if (ret < 0 || (unsigned int) ret >= buf_len)
    575 		return NULL;
    576 
    577 	return buf;
    578 }
    579 
    580 
    581 void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid)
    582 {
    583 	const u8 *addr[2];
    584 	size_t len[2];
    585 	u8 hash[SHA1_MAC_LEN];
    586 	u8 nsid[16] = {
    587 		0x52, 0x64, 0x80, 0xf8,
    588 		0xc9, 0x9b,
    589 		0x4b, 0xe5,
    590 		0xa6, 0x55,
    591 		0x58, 0xed, 0x5f, 0x5d, 0x60, 0x84
    592 	};
    593 
    594 	addr[0] = nsid;
    595 	len[0] = sizeof(nsid);
    596 	addr[1] = mac_addr;
    597 	len[1] = 6;
    598 	sha1_vector(2, addr, len, hash);
    599 	os_memcpy(uuid, hash, 16);
    600 
    601 	/* Version: 5 = named-based version using SHA-1 */
    602 	uuid[6] = (5 << 4) | (uuid[6] & 0x0f);
    603 
    604 	/* Variant specified in RFC 4122 */
    605 	uuid[8] = 0x80 | (uuid[8] & 0x3f);
    606 }
    607 
    608 
    609 u16 wps_config_methods_str2bin(const char *str)
    610 {
    611 	u16 methods = 0;
    612 
    613 	if (str == NULL) {
    614 		/* Default to enabling methods based on build configuration */
    615 		methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
    616 #ifdef CONFIG_WPS2
    617 		methods |= WPS_CONFIG_VIRT_DISPLAY;
    618 #endif /* CONFIG_WPS2 */
    619 #ifdef CONFIG_WPS_UFD
    620 		methods |= WPS_CONFIG_USBA;
    621 #endif /* CONFIG_WPS_UFD */
    622 #ifdef CONFIG_WPS_NFC
    623 		methods |= WPS_CONFIG_NFC_INTERFACE;
    624 #endif /* CONFIG_WPS_NFC */
    625 	} else {
    626 		if (os_strstr(str, "usba"))
    627 			methods |= WPS_CONFIG_USBA;
    628 		if (os_strstr(str, "ethernet"))
    629 			methods |= WPS_CONFIG_ETHERNET;
    630 		if (os_strstr(str, "label"))
    631 			methods |= WPS_CONFIG_LABEL;
    632 		if (os_strstr(str, "display"))
    633 			methods |= WPS_CONFIG_DISPLAY;
    634 		if (os_strstr(str, "ext_nfc_token"))
    635 			methods |= WPS_CONFIG_EXT_NFC_TOKEN;
    636 		if (os_strstr(str, "int_nfc_token"))
    637 			methods |= WPS_CONFIG_INT_NFC_TOKEN;
    638 		if (os_strstr(str, "nfc_interface"))
    639 			methods |= WPS_CONFIG_NFC_INTERFACE;
    640 		if (os_strstr(str, "push_button"))
    641 			methods |= WPS_CONFIG_PUSHBUTTON;
    642 		if (os_strstr(str, "keypad"))
    643 			methods |= WPS_CONFIG_KEYPAD;
    644 #ifdef CONFIG_WPS2
    645 		if (os_strstr(str, "virtual_display"))
    646 			methods |= WPS_CONFIG_VIRT_DISPLAY;
    647 		if (os_strstr(str, "physical_display"))
    648 			methods |= WPS_CONFIG_PHY_DISPLAY;
    649 		if (os_strstr(str, "virtual_push_button"))
    650 			methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
    651 		if (os_strstr(str, "physical_push_button"))
    652 			methods |= WPS_CONFIG_PHY_PUSHBUTTON;
    653 #endif /* CONFIG_WPS2 */
    654 	}
    655 
    656 	return methods;
    657 }
    658 
    659 
    660 struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
    661 {
    662 	struct wpabuf *msg;
    663 
    664 	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
    665 
    666 	msg = wpabuf_alloc(1000);
    667 	if (msg == NULL)
    668 		return NULL;
    669 
    670 	if (wps_build_version(msg) ||
    671 	    wps_build_msg_type(msg, WPS_WSC_ACK) ||
    672 	    wps_build_enrollee_nonce(wps, msg) ||
    673 	    wps_build_registrar_nonce(wps, msg) ||
    674 	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
    675 		wpabuf_free(msg);
    676 		return NULL;
    677 	}
    678 
    679 	return msg;
    680 }
    681 
    682 
    683 struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
    684 {
    685 	struct wpabuf *msg;
    686 
    687 	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
    688 
    689 	msg = wpabuf_alloc(1000);
    690 	if (msg == NULL)
    691 		return NULL;
    692 
    693 	if (wps_build_version(msg) ||
    694 	    wps_build_msg_type(msg, WPS_WSC_NACK) ||
    695 	    wps_build_enrollee_nonce(wps, msg) ||
    696 	    wps_build_registrar_nonce(wps, msg) ||
    697 	    wps_build_config_error(msg, wps->config_error) ||
    698 	    wps_build_wfa_ext(msg, 0, NULL, 0)) {
    699 		wpabuf_free(msg);
    700 		return NULL;
    701 	}
    702 
    703 	return msg;
    704 }
    705