Home | History | Annotate | Download | only in wps
      1 /*
      2  * Wi-Fi Protected Setup - Enrollee
      3  * Copyright (c) 2008, 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/sha256.h"
     19 #include "wps_i.h"
     20 #include "wps_dev_attr.h"
     21 
     22 
     23 static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
     24 {
     25 	wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
     26 	wpabuf_put_be16(msg, ATTR_MAC_ADDR);
     27 	wpabuf_put_be16(msg, ETH_ALEN);
     28 	wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
     29 	return 0;
     30 }
     31 
     32 
     33 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
     34 {
     35 	u8 state;
     36 	if (wps->wps->ap)
     37 		state = wps->wps->wps_state;
     38 	else
     39 		state = WPS_STATE_NOT_CONFIGURED;
     40 	wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
     41 		   state);
     42 	wpabuf_put_be16(msg, ATTR_WPS_STATE);
     43 	wpabuf_put_be16(msg, 1);
     44 	wpabuf_put_u8(msg, state);
     45 	return 0;
     46 }
     47 
     48 
     49 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
     50 {
     51 	u8 *hash;
     52 	const u8 *addr[4];
     53 	size_t len[4];
     54 
     55 	if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
     56 		return -1;
     57 	wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
     58 	wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
     59 		    wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
     60 
     61 	if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
     62 		wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
     63 			   "E-Hash derivation");
     64 		return -1;
     65 	}
     66 
     67 	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
     68 	wpabuf_put_be16(msg, ATTR_E_HASH1);
     69 	wpabuf_put_be16(msg, SHA256_MAC_LEN);
     70 	hash = wpabuf_put(msg, SHA256_MAC_LEN);
     71 	/* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
     72 	addr[0] = wps->snonce;
     73 	len[0] = WPS_SECRET_NONCE_LEN;
     74 	addr[1] = wps->psk1;
     75 	len[1] = WPS_PSK_LEN;
     76 	addr[2] = wpabuf_head(wps->dh_pubkey_e);
     77 	len[2] = wpabuf_len(wps->dh_pubkey_e);
     78 	addr[3] = wpabuf_head(wps->dh_pubkey_r);
     79 	len[3] = wpabuf_len(wps->dh_pubkey_r);
     80 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
     81 	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
     82 
     83 	wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
     84 	wpabuf_put_be16(msg, ATTR_E_HASH2);
     85 	wpabuf_put_be16(msg, SHA256_MAC_LEN);
     86 	hash = wpabuf_put(msg, SHA256_MAC_LEN);
     87 	/* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
     88 	addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
     89 	addr[1] = wps->psk2;
     90 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
     91 	wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
     92 
     93 	return 0;
     94 }
     95 
     96 
     97 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
     98 {
     99 	wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
    100 	wpabuf_put_be16(msg, ATTR_E_SNONCE1);
    101 	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
    102 	wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
    103 	return 0;
    104 }
    105 
    106 
    107 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
    108 {
    109 	wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
    110 	wpabuf_put_be16(msg, ATTR_E_SNONCE2);
    111 	wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
    112 	wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
    113 			WPS_SECRET_NONCE_LEN);
    114 	return 0;
    115 }
    116 
    117 
    118 static struct wpabuf * wps_build_m1(struct wps_data *wps)
    119 {
    120 	struct wpabuf *msg;
    121 	u16 methods;
    122 
    123 	if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
    124 		return NULL;
    125 	wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
    126 		    wps->nonce_e, WPS_NONCE_LEN);
    127 
    128 	wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
    129 	msg = wpabuf_alloc(1000);
    130 	if (msg == NULL)
    131 		return NULL;
    132 
    133 	methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD;
    134 	if (wps->pbc)
    135 		methods |= WPS_CONFIG_PUSHBUTTON;
    136 
    137 	if (wps_build_version(msg) ||
    138 	    wps_build_msg_type(msg, WPS_M1) ||
    139 	    wps_build_uuid_e(msg, wps->uuid_e) ||
    140 	    wps_build_mac_addr(wps, msg) ||
    141 	    wps_build_enrollee_nonce(wps, msg) ||
    142 	    wps_build_public_key(wps, msg) ||
    143 	    wps_build_auth_type_flags(wps, msg) ||
    144 	    wps_build_encr_type_flags(wps, msg) ||
    145 	    wps_build_conn_type_flags(wps, msg) ||
    146 	    wps_build_config_methods(msg, methods) ||
    147 	    wps_build_wps_state(wps, msg) ||
    148 	    wps_build_device_attrs(&wps->wps->dev, msg) ||
    149 	    wps_build_rf_bands(&wps->wps->dev, msg) ||
    150 	    wps_build_assoc_state(wps, msg) ||
    151 	    wps_build_dev_password_id(msg, wps->dev_pw_id) ||
    152 	    wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
    153 	    wps_build_os_version(&wps->wps->dev, msg)) {
    154 		wpabuf_free(msg);
    155 		return NULL;
    156 	}
    157 
    158 	wps->state = RECV_M2;
    159 	return msg;
    160 }
    161 
    162 
    163 static struct wpabuf * wps_build_m3(struct wps_data *wps)
    164 {
    165 	struct wpabuf *msg;
    166 
    167 	wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
    168 
    169 	if (wps->dev_password == NULL) {
    170 		wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
    171 		return NULL;
    172 	}
    173 	wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
    174 
    175 	msg = wpabuf_alloc(1000);
    176 	if (msg == NULL)
    177 		return NULL;
    178 
    179 	if (wps_build_version(msg) ||
    180 	    wps_build_msg_type(msg, WPS_M3) ||
    181 	    wps_build_registrar_nonce(wps, msg) ||
    182 	    wps_build_e_hash(wps, msg) ||
    183 	    wps_build_authenticator(wps, msg)) {
    184 		wpabuf_free(msg);
    185 		return NULL;
    186 	}
    187 
    188 	wps->state = RECV_M4;
    189 	return msg;
    190 }
    191 
    192 
    193 static struct wpabuf * wps_build_m5(struct wps_data *wps)
    194 {
    195 	struct wpabuf *msg, *plain;
    196 
    197 	wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
    198 
    199 	plain = wpabuf_alloc(200);
    200 	if (plain == NULL)
    201 		return NULL;
    202 
    203 	msg = wpabuf_alloc(1000);
    204 	if (msg == NULL) {
    205 		wpabuf_free(plain);
    206 		return NULL;
    207 	}
    208 
    209 	if (wps_build_version(msg) ||
    210 	    wps_build_msg_type(msg, WPS_M5) ||
    211 	    wps_build_registrar_nonce(wps, msg) ||
    212 	    wps_build_e_snonce1(wps, plain) ||
    213 	    wps_build_key_wrap_auth(wps, plain) ||
    214 	    wps_build_encr_settings(wps, msg, plain) ||
    215 	    wps_build_authenticator(wps, msg)) {
    216 		wpabuf_free(plain);
    217 		wpabuf_free(msg);
    218 		return NULL;
    219 	}
    220 	wpabuf_free(plain);
    221 
    222 	wps->state = RECV_M6;
    223 	return msg;
    224 }
    225 
    226 
    227 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
    228 {
    229 	wpa_printf(MSG_DEBUG, "WPS:  * SSID");
    230 	wpabuf_put_be16(msg, ATTR_SSID);
    231 	wpabuf_put_be16(msg, wps->wps->ssid_len);
    232 	wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
    233 	return 0;
    234 }
    235 
    236 
    237 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
    238 {
    239 	wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");
    240 	wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
    241 	wpabuf_put_be16(msg, 2);
    242 	wpabuf_put_be16(msg, wps->wps->auth_types);
    243 	return 0;
    244 }
    245 
    246 
    247 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
    248 {
    249 	wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");
    250 	wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
    251 	wpabuf_put_be16(msg, 2);
    252 	wpabuf_put_be16(msg, wps->wps->encr_types);
    253 	return 0;
    254 }
    255 
    256 
    257 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
    258 {
    259 	wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
    260 	wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
    261 	wpabuf_put_be16(msg, wps->wps->network_key_len);
    262 	wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
    263 	return 0;
    264 }
    265 
    266 
    267 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
    268 {
    269 	wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
    270 	wpabuf_put_be16(msg, ATTR_MAC_ADDR);
    271 	wpabuf_put_be16(msg, ETH_ALEN);
    272 	wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
    273 	return 0;
    274 }
    275 
    276 
    277 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
    278 {
    279 	if (wps->wps->ap_settings) {
    280 		wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");
    281 		wpabuf_put_data(plain, wps->wps->ap_settings,
    282 				wps->wps->ap_settings_len);
    283 		return 0;
    284 	}
    285 
    286 	return wps_build_cred_ssid(wps, plain) ||
    287 		wps_build_cred_mac_addr(wps, plain) ||
    288 		wps_build_cred_auth_type(wps, plain) ||
    289 		wps_build_cred_encr_type(wps, plain) ||
    290 		wps_build_cred_network_key(wps, plain);
    291 }
    292 
    293 
    294 static struct wpabuf * wps_build_m7(struct wps_data *wps)
    295 {
    296 	struct wpabuf *msg, *plain;
    297 
    298 	wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
    299 
    300 	plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
    301 	if (plain == NULL)
    302 		return NULL;
    303 
    304 	msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
    305 	if (msg == NULL) {
    306 		wpabuf_free(plain);
    307 		return NULL;
    308 	}
    309 
    310 	if (wps_build_version(msg) ||
    311 	    wps_build_msg_type(msg, WPS_M7) ||
    312 	    wps_build_registrar_nonce(wps, msg) ||
    313 	    wps_build_e_snonce2(wps, plain) ||
    314 	    (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
    315 	    wps_build_key_wrap_auth(wps, plain) ||
    316 	    wps_build_encr_settings(wps, msg, plain) ||
    317 	    wps_build_authenticator(wps, msg)) {
    318 		wpabuf_free(plain);
    319 		wpabuf_free(msg);
    320 		return NULL;
    321 	}
    322 	wpabuf_free(plain);
    323 
    324 	wps->state = RECV_M8;
    325 	return msg;
    326 }
    327 
    328 
    329 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
    330 {
    331 	struct wpabuf *msg;
    332 
    333 	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
    334 
    335 	msg = wpabuf_alloc(1000);
    336 	if (msg == NULL)
    337 		return NULL;
    338 
    339 	if (wps_build_version(msg) ||
    340 	    wps_build_msg_type(msg, WPS_WSC_DONE) ||
    341 	    wps_build_enrollee_nonce(wps, msg) ||
    342 	    wps_build_registrar_nonce(wps, msg)) {
    343 		wpabuf_free(msg);
    344 		return NULL;
    345 	}
    346 
    347 	if (wps->wps->ap)
    348 		wps->state = RECV_ACK;
    349 	else {
    350 		wps_success_event(wps->wps);
    351 		wps->state = WPS_FINISHED;
    352 	}
    353 	return msg;
    354 }
    355 
    356 
    357 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
    358 {
    359 	struct wpabuf *msg;
    360 
    361 	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
    362 
    363 	msg = wpabuf_alloc(1000);
    364 	if (msg == NULL)
    365 		return NULL;
    366 
    367 	if (wps_build_version(msg) ||
    368 	    wps_build_msg_type(msg, WPS_WSC_ACK) ||
    369 	    wps_build_enrollee_nonce(wps, msg) ||
    370 	    wps_build_registrar_nonce(wps, msg)) {
    371 		wpabuf_free(msg);
    372 		return NULL;
    373 	}
    374 
    375 	return msg;
    376 }
    377 
    378 
    379 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
    380 {
    381 	struct wpabuf *msg;
    382 
    383 	wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
    384 
    385 	msg = wpabuf_alloc(1000);
    386 	if (msg == NULL)
    387 		return NULL;
    388 
    389 	if (wps_build_version(msg) ||
    390 	    wps_build_msg_type(msg, WPS_WSC_NACK) ||
    391 	    wps_build_enrollee_nonce(wps, msg) ||
    392 	    wps_build_registrar_nonce(wps, msg) ||
    393 	    wps_build_config_error(msg, wps->config_error)) {
    394 		wpabuf_free(msg);
    395 		return NULL;
    396 	}
    397 
    398 	return msg;
    399 }
    400 
    401 
    402 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
    403 				     enum wsc_op_code *op_code)
    404 {
    405 	struct wpabuf *msg;
    406 
    407 	switch (wps->state) {
    408 	case SEND_M1:
    409 		msg = wps_build_m1(wps);
    410 		*op_code = WSC_MSG;
    411 		break;
    412 	case SEND_M3:
    413 		msg = wps_build_m3(wps);
    414 		*op_code = WSC_MSG;
    415 		break;
    416 	case SEND_M5:
    417 		msg = wps_build_m5(wps);
    418 		*op_code = WSC_MSG;
    419 		break;
    420 	case SEND_M7:
    421 		msg = wps_build_m7(wps);
    422 		*op_code = WSC_MSG;
    423 		break;
    424 	case RECEIVED_M2D:
    425 		if (wps->wps->ap) {
    426 			msg = wps_build_wsc_nack(wps);
    427 			*op_code = WSC_NACK;
    428 			break;
    429 		}
    430 		msg = wps_build_wsc_ack(wps);
    431 		*op_code = WSC_ACK;
    432 		if (msg) {
    433 			/* Another M2/M2D may be received */
    434 			wps->state = RECV_M2;
    435 		}
    436 		break;
    437 	case SEND_WSC_NACK:
    438 		msg = wps_build_wsc_nack(wps);
    439 		*op_code = WSC_NACK;
    440 		break;
    441 	case WPS_MSG_DONE:
    442 		msg = wps_build_wsc_done(wps);
    443 		*op_code = WSC_Done;
    444 		break;
    445 	default:
    446 		wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
    447 			   "a message", wps->state);
    448 		msg = NULL;
    449 		break;
    450 	}
    451 
    452 	if (*op_code == WSC_MSG && msg) {
    453 		/* Save a copy of the last message for Authenticator derivation
    454 		 */
    455 		wpabuf_free(wps->last_msg);
    456 		wps->last_msg = wpabuf_dup(msg);
    457 	}
    458 
    459 	return msg;
    460 }
    461 
    462 
    463 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
    464 {
    465 	if (r_nonce == NULL) {
    466 		wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
    467 		return -1;
    468 	}
    469 
    470 	os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
    471 	wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
    472 		    wps->nonce_r, WPS_NONCE_LEN);
    473 
    474 	return 0;
    475 }
    476 
    477 
    478 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
    479 {
    480 	if (e_nonce == NULL) {
    481 		wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
    482 		return -1;
    483 	}
    484 
    485 	if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
    486 		wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
    487 		return -1;
    488 	}
    489 
    490 	return 0;
    491 }
    492 
    493 
    494 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
    495 {
    496 	if (uuid_r == NULL) {
    497 		wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
    498 		return -1;
    499 	}
    500 
    501 	os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
    502 	wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
    503 
    504 	return 0;
    505 }
    506 
    507 
    508 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
    509 			      size_t pk_len)
    510 {
    511 	if (pk == NULL || pk_len == 0) {
    512 		wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
    513 		return -1;
    514 	}
    515 
    516 	wpabuf_free(wps->dh_pubkey_r);
    517 	wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
    518 	if (wps->dh_pubkey_r == NULL)
    519 		return -1;
    520 
    521 	if (wps_derive_keys(wps) < 0)
    522 		return -1;
    523 
    524 	return 0;
    525 }
    526 
    527 
    528 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
    529 {
    530 	if (r_hash1 == NULL) {
    531 		wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
    532 		return -1;
    533 	}
    534 
    535 	os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
    536 	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
    537 
    538 	return 0;
    539 }
    540 
    541 
    542 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
    543 {
    544 	if (r_hash2 == NULL) {
    545 		wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
    546 		return -1;
    547 	}
    548 
    549 	os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
    550 	wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
    551 
    552 	return 0;
    553 }
    554 
    555 
    556 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
    557 {
    558 	u8 hash[SHA256_MAC_LEN];
    559 	const u8 *addr[4];
    560 	size_t len[4];
    561 
    562 	if (r_snonce1 == NULL) {
    563 		wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
    564 		return -1;
    565 	}
    566 
    567 	wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
    568 			WPS_SECRET_NONCE_LEN);
    569 
    570 	/* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
    571 	addr[0] = r_snonce1;
    572 	len[0] = WPS_SECRET_NONCE_LEN;
    573 	addr[1] = wps->psk1;
    574 	len[1] = WPS_PSK_LEN;
    575 	addr[2] = wpabuf_head(wps->dh_pubkey_e);
    576 	len[2] = wpabuf_len(wps->dh_pubkey_e);
    577 	addr[3] = wpabuf_head(wps->dh_pubkey_r);
    578 	len[3] = wpabuf_len(wps->dh_pubkey_r);
    579 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    580 
    581 	if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
    582 		wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
    583 			   "not match with the pre-committed value");
    584 		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
    585 		wps_pwd_auth_fail_event(wps->wps, 1, 1);
    586 		return -1;
    587 	}
    588 
    589 	wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
    590 		   "half of the device password");
    591 
    592 	return 0;
    593 }
    594 
    595 
    596 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
    597 {
    598 	u8 hash[SHA256_MAC_LEN];
    599 	const u8 *addr[4];
    600 	size_t len[4];
    601 
    602 	if (r_snonce2 == NULL) {
    603 		wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
    604 		return -1;
    605 	}
    606 
    607 	wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
    608 			WPS_SECRET_NONCE_LEN);
    609 
    610 	/* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
    611 	addr[0] = r_snonce2;
    612 	len[0] = WPS_SECRET_NONCE_LEN;
    613 	addr[1] = wps->psk2;
    614 	len[1] = WPS_PSK_LEN;
    615 	addr[2] = wpabuf_head(wps->dh_pubkey_e);
    616 	len[2] = wpabuf_len(wps->dh_pubkey_e);
    617 	addr[3] = wpabuf_head(wps->dh_pubkey_r);
    618 	len[3] = wpabuf_len(wps->dh_pubkey_r);
    619 	hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    620 
    621 	if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
    622 		wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
    623 			   "not match with the pre-committed value");
    624 		wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
    625 		wps_pwd_auth_fail_event(wps->wps, 1, 2);
    626 		return -1;
    627 	}
    628 
    629 	wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
    630 		   "half of the device password");
    631 
    632 	return 0;
    633 }
    634 
    635 
    636 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
    637 			      size_t cred_len)
    638 {
    639 	struct wps_parse_attr attr;
    640 	struct wpabuf msg;
    641 
    642 	wpa_printf(MSG_DEBUG, "WPS: Received Credential");
    643 	os_memset(&wps->cred, 0, sizeof(wps->cred));
    644 	wpabuf_set(&msg, cred, cred_len);
    645 	if (wps_parse_msg(&msg, &attr) < 0 ||
    646 	    wps_process_cred(&attr, &wps->cred))
    647 		return -1;
    648 
    649 	if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
    650 	    0) {
    651 		wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
    652 			   MACSTR ") does not match with own address (" MACSTR
    653 			   ")", MAC2STR(wps->cred.mac_addr),
    654 			   MAC2STR(wps->wps->dev.mac_addr));
    655 		/*
    656 		 * In theory, this could be consider fatal error, but there are
    657 		 * number of deployed implementations using other address here
    658 		 * due to unclarity in the specification. For interoperability
    659 		 * reasons, allow this to be processed since we do not really
    660 		 * use the MAC Address information for anything.
    661 		 */
    662 	}
    663 
    664 	if (wps->wps->cred_cb) {
    665 		wps->cred.cred_attr = cred - 4;
    666 		wps->cred.cred_attr_len = cred_len + 4;
    667 		wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
    668 		wps->cred.cred_attr = NULL;
    669 		wps->cred.cred_attr_len = 0;
    670 	}
    671 
    672 	return 0;
    673 }
    674 
    675 
    676 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
    677 			     size_t cred_len[], size_t num_cred)
    678 {
    679 	size_t i;
    680 
    681 	if (wps->wps->ap)
    682 		return 0;
    683 
    684 	if (num_cred == 0) {
    685 		wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
    686 			   "received");
    687 		return -1;
    688 	}
    689 
    690 	for (i = 0; i < num_cred; i++) {
    691 		if (wps_process_cred_e(wps, cred[i], cred_len[i]))
    692 			return -1;
    693 	}
    694 
    695 	return 0;
    696 }
    697 
    698 
    699 static int wps_process_ap_settings_e(struct wps_data *wps,
    700 				     struct wps_parse_attr *attr,
    701 				     struct wpabuf *attrs)
    702 {
    703 	struct wps_credential cred;
    704 
    705 	if (!wps->wps->ap)
    706 		return 0;
    707 
    708 	if (wps_process_ap_settings(attr, &cred) < 0)
    709 		return -1;
    710 
    711 	wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
    712 		   "Registrar");
    713 
    714 	if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
    715 	    0) {
    716 		wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
    717 			   MACSTR ") does not match with own address (" MACSTR
    718 			   ")", MAC2STR(cred.mac_addr),
    719 			   MAC2STR(wps->wps->dev.mac_addr));
    720 		/*
    721 		 * In theory, this could be consider fatal error, but there are
    722 		 * number of deployed implementations using other address here
    723 		 * due to unclarity in the specification. For interoperability
    724 		 * reasons, allow this to be processed since we do not really
    725 		 * use the MAC Address information for anything.
    726 		 */
    727 	}
    728 
    729 	if (wps->wps->cred_cb) {
    730 		cred.cred_attr = wpabuf_head(attrs);
    731 		cred.cred_attr_len = wpabuf_len(attrs);
    732 		wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
    733 	}
    734 
    735 	return 0;
    736 }
    737 
    738 
    739 static enum wps_process_res wps_process_m2(struct wps_data *wps,
    740 					   const struct wpabuf *msg,
    741 					   struct wps_parse_attr *attr)
    742 {
    743 	wpa_printf(MSG_DEBUG, "WPS: Received M2");
    744 
    745 	if (wps->state != RECV_M2) {
    746 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    747 			   "receiving M2", wps->state);
    748 		wps->state = SEND_WSC_NACK;
    749 		return WPS_CONTINUE;
    750 	}
    751 
    752 	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
    753 	    wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
    754 	    wps_process_uuid_r(wps, attr->uuid_r) ||
    755 	    wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
    756 	    wps_process_authenticator(wps, attr->authenticator, msg)) {
    757 		wps->state = SEND_WSC_NACK;
    758 		return WPS_CONTINUE;
    759 	}
    760 
    761 	if (wps->wps->ap && wps->wps->ap_setup_locked) {
    762 		wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
    763 			   "registration of a new Registrar");
    764 		wps->config_error = WPS_CFG_SETUP_LOCKED;
    765 		wps->state = SEND_WSC_NACK;
    766 		return WPS_CONTINUE;
    767 	}
    768 
    769 	wps->state = SEND_M3;
    770 	return WPS_CONTINUE;
    771 }
    772 
    773 
    774 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
    775 					    struct wps_parse_attr *attr)
    776 {
    777 	wpa_printf(MSG_DEBUG, "WPS: Received M2D");
    778 
    779 	if (wps->state != RECV_M2) {
    780 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    781 			   "receiving M2D", wps->state);
    782 		wps->state = SEND_WSC_NACK;
    783 		return WPS_CONTINUE;
    784 	}
    785 
    786 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
    787 			  attr->manufacturer, attr->manufacturer_len);
    788 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
    789 			  attr->model_name, attr->model_name_len);
    790 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
    791 			  attr->model_number, attr->model_number_len);
    792 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
    793 			  attr->serial_number, attr->serial_number_len);
    794 	wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
    795 			  attr->dev_name, attr->dev_name_len);
    796 
    797 	if (wps->wps->event_cb) {
    798 		union wps_event_data data;
    799 		struct wps_event_m2d *m2d = &data.m2d;
    800 		os_memset(&data, 0, sizeof(data));
    801 		if (attr->config_methods)
    802 			m2d->config_methods =
    803 				WPA_GET_BE16(attr->config_methods);
    804 		m2d->manufacturer = attr->manufacturer;
    805 		m2d->manufacturer_len = attr->manufacturer_len;
    806 		m2d->model_name = attr->model_name;
    807 		m2d->model_name_len = attr->model_name_len;
    808 		m2d->model_number = attr->model_number;
    809 		m2d->model_number_len = attr->model_number_len;
    810 		m2d->serial_number = attr->serial_number;
    811 		m2d->serial_number_len = attr->serial_number_len;
    812 		m2d->dev_name = attr->dev_name;
    813 		m2d->dev_name_len = attr->dev_name_len;
    814 		m2d->primary_dev_type = attr->primary_dev_type;
    815 		if (attr->config_error)
    816 			m2d->config_error =
    817 				WPA_GET_BE16(attr->config_error);
    818 		if (attr->dev_password_id)
    819 			m2d->dev_password_id =
    820 				WPA_GET_BE16(attr->dev_password_id);
    821 		wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
    822 	}
    823 
    824 	wps->state = RECEIVED_M2D;
    825 	return WPS_CONTINUE;
    826 }
    827 
    828 
    829 static enum wps_process_res wps_process_m4(struct wps_data *wps,
    830 					   const struct wpabuf *msg,
    831 					   struct wps_parse_attr *attr)
    832 {
    833 	struct wpabuf *decrypted;
    834 	struct wps_parse_attr eattr;
    835 
    836 	wpa_printf(MSG_DEBUG, "WPS: Received M4");
    837 
    838 	if (wps->state != RECV_M4) {
    839 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    840 			   "receiving M4", wps->state);
    841 		wps->state = SEND_WSC_NACK;
    842 		return WPS_CONTINUE;
    843 	}
    844 
    845 	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
    846 	    wps_process_authenticator(wps, attr->authenticator, msg) ||
    847 	    wps_process_r_hash1(wps, attr->r_hash1) ||
    848 	    wps_process_r_hash2(wps, attr->r_hash2)) {
    849 		wps->state = SEND_WSC_NACK;
    850 		return WPS_CONTINUE;
    851 	}
    852 
    853 	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
    854 					      attr->encr_settings_len);
    855 	if (decrypted == NULL) {
    856 		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
    857 			   "Settings attribute");
    858 		wps->state = SEND_WSC_NACK;
    859 		return WPS_CONTINUE;
    860 	}
    861 
    862 	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
    863 		   "attribute");
    864 	if (wps_parse_msg(decrypted, &eattr) < 0 ||
    865 	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
    866 	    wps_process_r_snonce1(wps, eattr.r_snonce1)) {
    867 		wpabuf_free(decrypted);
    868 		wps->state = SEND_WSC_NACK;
    869 		return WPS_CONTINUE;
    870 	}
    871 	wpabuf_free(decrypted);
    872 
    873 	wps->state = SEND_M5;
    874 	return WPS_CONTINUE;
    875 }
    876 
    877 
    878 static enum wps_process_res wps_process_m6(struct wps_data *wps,
    879 					   const struct wpabuf *msg,
    880 					   struct wps_parse_attr *attr)
    881 {
    882 	struct wpabuf *decrypted;
    883 	struct wps_parse_attr eattr;
    884 
    885 	wpa_printf(MSG_DEBUG, "WPS: Received M6");
    886 
    887 	if (wps->state != RECV_M6) {
    888 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    889 			   "receiving M6", wps->state);
    890 		wps->state = SEND_WSC_NACK;
    891 		return WPS_CONTINUE;
    892 	}
    893 
    894 	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
    895 	    wps_process_authenticator(wps, attr->authenticator, msg)) {
    896 		wps->state = SEND_WSC_NACK;
    897 		return WPS_CONTINUE;
    898 	}
    899 
    900 	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
    901 					      attr->encr_settings_len);
    902 	if (decrypted == NULL) {
    903 		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
    904 			   "Settings attribute");
    905 		wps->state = SEND_WSC_NACK;
    906 		return WPS_CONTINUE;
    907 	}
    908 
    909 	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
    910 		   "attribute");
    911 	if (wps_parse_msg(decrypted, &eattr) < 0 ||
    912 	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
    913 	    wps_process_r_snonce2(wps, eattr.r_snonce2)) {
    914 		wpabuf_free(decrypted);
    915 		wps->state = SEND_WSC_NACK;
    916 		return WPS_CONTINUE;
    917 	}
    918 	wpabuf_free(decrypted);
    919 
    920 	wps->state = SEND_M7;
    921 	return WPS_CONTINUE;
    922 }
    923 
    924 
    925 static enum wps_process_res wps_process_m8(struct wps_data *wps,
    926 					   const struct wpabuf *msg,
    927 					   struct wps_parse_attr *attr)
    928 {
    929 	struct wpabuf *decrypted;
    930 	struct wps_parse_attr eattr;
    931 
    932 	wpa_printf(MSG_DEBUG, "WPS: Received M8");
    933 
    934 	if (wps->state != RECV_M8) {
    935 		wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    936 			   "receiving M8", wps->state);
    937 		wps->state = SEND_WSC_NACK;
    938 		return WPS_CONTINUE;
    939 	}
    940 
    941 	if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
    942 	    wps_process_authenticator(wps, attr->authenticator, msg)) {
    943 		wps->state = SEND_WSC_NACK;
    944 		return WPS_CONTINUE;
    945 	}
    946 
    947 	decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
    948 					      attr->encr_settings_len);
    949 	if (decrypted == NULL) {
    950 		wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
    951 			   "Settings attribute");
    952 		wps->state = SEND_WSC_NACK;
    953 		return WPS_CONTINUE;
    954 	}
    955 
    956 	wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
    957 		   "attribute");
    958 	if (wps_parse_msg(decrypted, &eattr) < 0 ||
    959 	    wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
    960 	    wps_process_creds(wps, eattr.cred, eattr.cred_len,
    961 			      eattr.num_cred) ||
    962 	    wps_process_ap_settings_e(wps, &eattr, decrypted)) {
    963 		wpabuf_free(decrypted);
    964 		wps->state = SEND_WSC_NACK;
    965 		return WPS_CONTINUE;
    966 	}
    967 	wpabuf_free(decrypted);
    968 
    969 	wps->state = WPS_MSG_DONE;
    970 	return WPS_CONTINUE;
    971 }
    972 
    973 
    974 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
    975 						const struct wpabuf *msg)
    976 {
    977 	struct wps_parse_attr attr;
    978 	enum wps_process_res ret = WPS_CONTINUE;
    979 
    980 	wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
    981 
    982 	if (wps_parse_msg(msg, &attr) < 0)
    983 		return WPS_FAILURE;
    984 
    985 	if (!wps_version_supported(attr.version)) {
    986 		wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
    987 			   attr.version ? *attr.version : 0);
    988 		return WPS_FAILURE;
    989 	}
    990 
    991 	if (attr.enrollee_nonce == NULL ||
    992 	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
    993 		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
    994 		return WPS_FAILURE;
    995 	}
    996 
    997 	if (attr.msg_type == NULL) {
    998 		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
    999 		return WPS_FAILURE;
   1000 	}
   1001 
   1002 	switch (*attr.msg_type) {
   1003 	case WPS_M2:
   1004 		ret = wps_process_m2(wps, msg, &attr);
   1005 		break;
   1006 	case WPS_M2D:
   1007 		ret = wps_process_m2d(wps, &attr);
   1008 		break;
   1009 	case WPS_M4:
   1010 		ret = wps_process_m4(wps, msg, &attr);
   1011 		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
   1012 			wps_fail_event(wps->wps, WPS_M4);
   1013 		break;
   1014 	case WPS_M6:
   1015 		ret = wps_process_m6(wps, msg, &attr);
   1016 		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
   1017 			wps_fail_event(wps->wps, WPS_M6);
   1018 		break;
   1019 	case WPS_M8:
   1020 		ret = wps_process_m8(wps, msg, &attr);
   1021 		if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
   1022 			wps_fail_event(wps->wps, WPS_M8);
   1023 		break;
   1024 	default:
   1025 		wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
   1026 			   *attr.msg_type);
   1027 		return WPS_FAILURE;
   1028 	}
   1029 
   1030 	/*
   1031 	 * Save a copy of the last message for Authenticator derivation if we
   1032 	 * are continuing. However, skip M2D since it is not authenticated and
   1033 	 * neither is the ACK/NACK response frame. This allows the possibly
   1034 	 * following M2 to be processed correctly by using the previously sent
   1035 	 * M1 in Authenticator derivation.
   1036 	 */
   1037 	if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
   1038 		/* Save a copy of the last message for Authenticator derivation
   1039 		 */
   1040 		wpabuf_free(wps->last_msg);
   1041 		wps->last_msg = wpabuf_dup(msg);
   1042 	}
   1043 
   1044 	return ret;
   1045 }
   1046 
   1047 
   1048 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
   1049 						const struct wpabuf *msg)
   1050 {
   1051 	struct wps_parse_attr attr;
   1052 
   1053 	wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
   1054 
   1055 	if (wps_parse_msg(msg, &attr) < 0)
   1056 		return WPS_FAILURE;
   1057 
   1058 	if (!wps_version_supported(attr.version)) {
   1059 		wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
   1060 			   attr.version ? *attr.version : 0);
   1061 		return WPS_FAILURE;
   1062 	}
   1063 
   1064 	if (attr.msg_type == NULL) {
   1065 		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
   1066 		return WPS_FAILURE;
   1067 	}
   1068 
   1069 	if (*attr.msg_type != WPS_WSC_ACK) {
   1070 		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
   1071 			   *attr.msg_type);
   1072 		return WPS_FAILURE;
   1073 	}
   1074 
   1075 	if (attr.registrar_nonce == NULL ||
   1076 	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
   1077 	{
   1078 		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
   1079 		return WPS_FAILURE;
   1080 	}
   1081 
   1082 	if (attr.enrollee_nonce == NULL ||
   1083 	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
   1084 		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
   1085 		return WPS_FAILURE;
   1086 	}
   1087 
   1088 	if (wps->state == RECV_ACK && wps->wps->ap) {
   1089 		wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
   1090 			   "completed successfully");
   1091 		wps_success_event(wps->wps);
   1092 		wps->state = WPS_FINISHED;
   1093 		return WPS_DONE;
   1094 	}
   1095 
   1096 	return WPS_FAILURE;
   1097 }
   1098 
   1099 
   1100 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
   1101 						 const struct wpabuf *msg)
   1102 {
   1103 	struct wps_parse_attr attr;
   1104 
   1105 	wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
   1106 
   1107 	if (wps_parse_msg(msg, &attr) < 0)
   1108 		return WPS_FAILURE;
   1109 
   1110 	if (!wps_version_supported(attr.version)) {
   1111 		wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
   1112 			   attr.version ? *attr.version : 0);
   1113 		return WPS_FAILURE;
   1114 	}
   1115 
   1116 	if (attr.msg_type == NULL) {
   1117 		wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
   1118 		return WPS_FAILURE;
   1119 	}
   1120 
   1121 	if (*attr.msg_type != WPS_WSC_NACK) {
   1122 		wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
   1123 			   *attr.msg_type);
   1124 		return WPS_FAILURE;
   1125 	}
   1126 
   1127 	if (attr.registrar_nonce == NULL ||
   1128 	    os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
   1129 	{
   1130 		wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
   1131 		wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
   1132 			    attr.registrar_nonce, WPS_NONCE_LEN);
   1133 		wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
   1134 			    wps->nonce_r, WPS_NONCE_LEN);
   1135 		return WPS_FAILURE;
   1136 	}
   1137 
   1138 	if (attr.enrollee_nonce == NULL ||
   1139 	    os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
   1140 		wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
   1141 		wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
   1142 			    attr.enrollee_nonce, WPS_NONCE_LEN);
   1143 		wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
   1144 			    wps->nonce_e, WPS_NONCE_LEN);
   1145 		return WPS_FAILURE;
   1146 	}
   1147 
   1148 	if (attr.config_error == NULL) {
   1149 		wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
   1150 			   "in WSC_NACK");
   1151 		return WPS_FAILURE;
   1152 	}
   1153 
   1154 	wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
   1155 		   "Configuration Error %d", WPA_GET_BE16(attr.config_error));
   1156 
   1157 	switch (wps->state) {
   1158 	case RECV_M4:
   1159 		wps_fail_event(wps->wps, WPS_M3);
   1160 		break;
   1161 	case RECV_M6:
   1162 		wps_fail_event(wps->wps, WPS_M5);
   1163 		break;
   1164 	case RECV_M8:
   1165 		wps_fail_event(wps->wps, WPS_M7);
   1166 		break;
   1167 	default:
   1168 		break;
   1169 	}
   1170 
   1171 	/* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
   1172 	 * Enrollee is Authenticator */
   1173 	wps->state = SEND_WSC_NACK;
   1174 
   1175 	return WPS_FAILURE;
   1176 }
   1177 
   1178 
   1179 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
   1180 					      enum wsc_op_code op_code,
   1181 					      const struct wpabuf *msg)
   1182 {
   1183 
   1184 	wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
   1185 		   "op_code=%d)",
   1186 		   (unsigned long) wpabuf_len(msg), op_code);
   1187 
   1188 	if (op_code == WSC_UPnP) {
   1189 		/* Determine the OpCode based on message type attribute */
   1190 		struct wps_parse_attr attr;
   1191 		if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
   1192 			if (*attr.msg_type == WPS_WSC_ACK)
   1193 				op_code = WSC_ACK;
   1194 			else if (*attr.msg_type == WPS_WSC_NACK)
   1195 				op_code = WSC_NACK;
   1196 		}
   1197 	}
   1198 
   1199 	switch (op_code) {
   1200 	case WSC_MSG:
   1201 	case WSC_UPnP:
   1202 		return wps_process_wsc_msg(wps, msg);
   1203 	case WSC_ACK:
   1204 		return wps_process_wsc_ack(wps, msg);
   1205 	case WSC_NACK:
   1206 		return wps_process_wsc_nack(wps, msg);
   1207 	default:
   1208 		wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
   1209 		return WPS_FAILURE;
   1210 	}
   1211 }
   1212