wps_enrollee.c
Go to the documentation of this file.
00001 /*
00002  * Wi-Fi Protected Setup - Enrollee
00003  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "crypto/crypto.h"
00019 #include "crypto/sha256.h"
00020 #include "wps_i.h"
00021 #include "wps_dev_attr.h"
00022 
00023 
00024 static int wps_build_mac_addr(struct wps_data *wps, struct wpabuf *msg)
00025 {
00026         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
00027         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
00028         wpabuf_put_be16(msg, ETH_ALEN);
00029         wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
00030         return 0;
00031 }
00032 
00033 
00034 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
00035 {
00036         u8 state;
00037         if (wps->wps->ap)
00038                 state = wps->wps->wps_state;
00039         else
00040                 state = WPS_STATE_NOT_CONFIGURED;
00041         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
00042                    state);
00043         wpabuf_put_be16(msg, ATTR_WPS_STATE);
00044         wpabuf_put_be16(msg, 1);
00045         wpabuf_put_u8(msg, state);
00046         return 0;
00047 }
00048 
00049 
00050 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
00051 {
00052         u8 *hash;
00053         const u8 *addr[4];
00054         size_t len[4];
00055 
00056         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
00057                 return -1;
00058         wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
00059         wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
00060                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
00061 
00062         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
00063                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
00064                            "E-Hash derivation");
00065                 return -1;
00066         }
00067 
00068         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
00069         wpabuf_put_be16(msg, ATTR_E_HASH1);
00070         wpabuf_put_be16(msg, SHA256_MAC_LEN);
00071         hash = wpabuf_put(msg, SHA256_MAC_LEN);
00072         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
00073         addr[0] = wps->snonce;
00074         len[0] = WPS_SECRET_NONCE_LEN;
00075         addr[1] = wps->psk1;
00076         len[1] = WPS_PSK_LEN;
00077         addr[2] = wpabuf_head(wps->dh_pubkey_e);
00078         len[2] = wpabuf_len(wps->dh_pubkey_e);
00079         addr[3] = wpabuf_head(wps->dh_pubkey_r);
00080         len[3] = wpabuf_len(wps->dh_pubkey_r);
00081         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
00082         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
00083 
00084         wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
00085         wpabuf_put_be16(msg, ATTR_E_HASH2);
00086         wpabuf_put_be16(msg, SHA256_MAC_LEN);
00087         hash = wpabuf_put(msg, SHA256_MAC_LEN);
00088         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
00089         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
00090         addr[1] = wps->psk2;
00091         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
00092         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
00093 
00094         return 0;
00095 }
00096 
00097 
00098 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
00099 {
00100         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
00101         wpabuf_put_be16(msg, ATTR_E_SNONCE1);
00102         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
00103         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
00104         return 0;
00105 }
00106 
00107 
00108 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
00109 {
00110         wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
00111         wpabuf_put_be16(msg, ATTR_E_SNONCE2);
00112         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
00113         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
00114                         WPS_SECRET_NONCE_LEN);
00115         return 0;
00116 }
00117 
00118 
00119 static struct wpabuf * wps_build_m1(struct wps_data *wps)
00120 {
00121         struct wpabuf *msg;
00122 
00123         if (os_get_random(wps->nonce_e, WPS_NONCE_LEN) < 0)
00124                 return NULL;
00125         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
00126                     wps->nonce_e, WPS_NONCE_LEN);
00127 
00128         wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
00129         msg = wpabuf_alloc(1000);
00130         if (msg == NULL)
00131                 return NULL;
00132 
00133         if (wps_build_version(msg) ||
00134             wps_build_msg_type(msg, WPS_M1) ||
00135             wps_build_uuid_e(msg, wps->uuid_e) ||
00136             wps_build_mac_addr(wps, msg) ||
00137             wps_build_enrollee_nonce(wps, msg) ||
00138             wps_build_public_key(wps, msg) ||
00139             wps_build_auth_type_flags(wps, msg) ||
00140             wps_build_encr_type_flags(wps, msg) ||
00141             wps_build_conn_type_flags(wps, msg) ||
00142             wps_build_config_methods(msg, wps->wps->config_methods) ||
00143             wps_build_wps_state(wps, msg) ||
00144             wps_build_device_attrs(&wps->wps->dev, msg) ||
00145             wps_build_rf_bands(&wps->wps->dev, msg) ||
00146             wps_build_assoc_state(wps, msg) ||
00147             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
00148             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
00149             wps_build_os_version(&wps->wps->dev, msg)) {
00150                 wpabuf_free(msg);
00151                 return NULL;
00152         }
00153 
00154         wps->state = RECV_M2;
00155         return msg;
00156 }
00157 
00158 
00159 static struct wpabuf * wps_build_m3(struct wps_data *wps)
00160 {
00161         struct wpabuf *msg;
00162 
00163         wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
00164 
00165         if (wps->dev_password == NULL) {
00166                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
00167                 return NULL;
00168         }
00169         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
00170 
00171         msg = wpabuf_alloc(1000);
00172         if (msg == NULL)
00173                 return NULL;
00174 
00175         if (wps_build_version(msg) ||
00176             wps_build_msg_type(msg, WPS_M3) ||
00177             wps_build_registrar_nonce(wps, msg) ||
00178             wps_build_e_hash(wps, msg) ||
00179             wps_build_authenticator(wps, msg)) {
00180                 wpabuf_free(msg);
00181                 return NULL;
00182         }
00183 
00184         wps->state = RECV_M4;
00185         return msg;
00186 }
00187 
00188 
00189 static struct wpabuf * wps_build_m5(struct wps_data *wps)
00190 {
00191         struct wpabuf *msg, *plain;
00192 
00193         wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
00194 
00195         plain = wpabuf_alloc(200);
00196         if (plain == NULL)
00197                 return NULL;
00198 
00199         msg = wpabuf_alloc(1000);
00200         if (msg == NULL) {
00201                 wpabuf_free(plain);
00202                 return NULL;
00203         }
00204 
00205         if (wps_build_version(msg) ||
00206             wps_build_msg_type(msg, WPS_M5) ||
00207             wps_build_registrar_nonce(wps, msg) ||
00208             wps_build_e_snonce1(wps, plain) ||
00209             wps_build_key_wrap_auth(wps, plain) ||
00210             wps_build_encr_settings(wps, msg, plain) ||
00211             wps_build_authenticator(wps, msg)) {
00212                 wpabuf_free(plain);
00213                 wpabuf_free(msg);
00214                 return NULL;
00215         }
00216         wpabuf_free(plain);
00217 
00218         wps->state = RECV_M6;
00219         return msg;
00220 }
00221 
00222 
00223 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
00224 {
00225         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
00226         wpabuf_put_be16(msg, ATTR_SSID);
00227         wpabuf_put_be16(msg, wps->wps->ssid_len);
00228         wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
00229         return 0;
00230 }
00231 
00232 
00233 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
00234 {
00235         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type");
00236         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
00237         wpabuf_put_be16(msg, 2);
00238         wpabuf_put_be16(msg, wps->wps->auth_types);
00239         return 0;
00240 }
00241 
00242 
00243 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
00244 {
00245         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type");
00246         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
00247         wpabuf_put_be16(msg, 2);
00248         wpabuf_put_be16(msg, wps->wps->encr_types);
00249         return 0;
00250 }
00251 
00252 
00253 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
00254 {
00255         wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
00256         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
00257         wpabuf_put_be16(msg, wps->wps->network_key_len);
00258         wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
00259         return 0;
00260 }
00261 
00262 
00263 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
00264 {
00265         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
00266         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
00267         wpabuf_put_be16(msg, ETH_ALEN);
00268         wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
00269         return 0;
00270 }
00271 
00272 
00273 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
00274 {
00275         if (wps->wps->ap_settings) {
00276                 wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");
00277                 wpabuf_put_data(plain, wps->wps->ap_settings,
00278                                 wps->wps->ap_settings_len);
00279                 return 0;
00280         }
00281 
00282         return wps_build_cred_ssid(wps, plain) ||
00283                 wps_build_cred_mac_addr(wps, plain) ||
00284                 wps_build_cred_auth_type(wps, plain) ||
00285                 wps_build_cred_encr_type(wps, plain) ||
00286                 wps_build_cred_network_key(wps, plain);
00287 }
00288 
00289 
00290 static struct wpabuf * wps_build_m7(struct wps_data *wps)
00291 {
00292         struct wpabuf *msg, *plain;
00293 
00294         wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
00295 
00296         plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
00297         if (plain == NULL)
00298                 return NULL;
00299 
00300         msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
00301         if (msg == NULL) {
00302                 wpabuf_free(plain);
00303                 return NULL;
00304         }
00305 
00306         if (wps_build_version(msg) ||
00307             wps_build_msg_type(msg, WPS_M7) ||
00308             wps_build_registrar_nonce(wps, msg) ||
00309             wps_build_e_snonce2(wps, plain) ||
00310             (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
00311             wps_build_key_wrap_auth(wps, plain) ||
00312             wps_build_encr_settings(wps, msg, plain) ||
00313             wps_build_authenticator(wps, msg)) {
00314                 wpabuf_free(plain);
00315                 wpabuf_free(msg);
00316                 return NULL;
00317         }
00318         wpabuf_free(plain);
00319 
00320         if (wps->wps->ap && wps->wps->registrar) {
00321                 /*
00322                  * If the Registrar is only learning our current configuration,
00323                  * it may not continue protocol run to successful completion.
00324                  * Store information here to make sure it remains available.
00325                  */
00326                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
00327                                  wps->uuid_r);
00328         }
00329 
00330         wps->state = RECV_M8;
00331         return msg;
00332 }
00333 
00334 
00335 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
00336 {
00337         struct wpabuf *msg;
00338 
00339         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
00340 
00341         msg = wpabuf_alloc(1000);
00342         if (msg == NULL)
00343                 return NULL;
00344 
00345         if (wps_build_version(msg) ||
00346             wps_build_msg_type(msg, WPS_WSC_DONE) ||
00347             wps_build_enrollee_nonce(wps, msg) ||
00348             wps_build_registrar_nonce(wps, msg)) {
00349                 wpabuf_free(msg);
00350                 return NULL;
00351         }
00352 
00353         if (wps->wps->ap)
00354                 wps->state = RECV_ACK;
00355         else {
00356                 wps_success_event(wps->wps);
00357                 wps->state = WPS_FINISHED;
00358         }
00359         return msg;
00360 }
00361 
00362 
00363 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
00364 {
00365         struct wpabuf *msg;
00366 
00367         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
00368 
00369         msg = wpabuf_alloc(1000);
00370         if (msg == NULL)
00371                 return NULL;
00372 
00373         if (wps_build_version(msg) ||
00374             wps_build_msg_type(msg, WPS_WSC_ACK) ||
00375             wps_build_enrollee_nonce(wps, msg) ||
00376             wps_build_registrar_nonce(wps, msg)) {
00377                 wpabuf_free(msg);
00378                 return NULL;
00379         }
00380 
00381         return msg;
00382 }
00383 
00384 
00385 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
00386 {
00387         struct wpabuf *msg;
00388 
00389         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
00390 
00391         msg = wpabuf_alloc(1000);
00392         if (msg == NULL)
00393                 return NULL;
00394 
00395         if (wps_build_version(msg) ||
00396             wps_build_msg_type(msg, WPS_WSC_NACK) ||
00397             wps_build_enrollee_nonce(wps, msg) ||
00398             wps_build_registrar_nonce(wps, msg) ||
00399             wps_build_config_error(msg, wps->config_error)) {
00400                 wpabuf_free(msg);
00401                 return NULL;
00402         }
00403 
00404         return msg;
00405 }
00406 
00407 
00408 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
00409                                      enum wsc_op_code *op_code)
00410 {
00411         struct wpabuf *msg;
00412 
00413         switch (wps->state) {
00414         case SEND_M1:
00415                 msg = wps_build_m1(wps);
00416                 *op_code = WSC_MSG;
00417                 break;
00418         case SEND_M3:
00419                 msg = wps_build_m3(wps);
00420                 *op_code = WSC_MSG;
00421                 break;
00422         case SEND_M5:
00423                 msg = wps_build_m5(wps);
00424                 *op_code = WSC_MSG;
00425                 break;
00426         case SEND_M7:
00427                 msg = wps_build_m7(wps);
00428                 *op_code = WSC_MSG;
00429                 break;
00430         case RECEIVED_M2D:
00431                 if (wps->wps->ap) {
00432                         msg = wps_build_wsc_nack(wps);
00433                         *op_code = WSC_NACK;
00434                         break;
00435                 }
00436                 msg = wps_build_wsc_ack(wps);
00437                 *op_code = WSC_ACK;
00438                 if (msg) {
00439                         /* Another M2/M2D may be received */
00440                         wps->state = RECV_M2;
00441                 }
00442                 break;
00443         case SEND_WSC_NACK:
00444                 msg = wps_build_wsc_nack(wps);
00445                 *op_code = WSC_NACK;
00446                 break;
00447         case WPS_MSG_DONE:
00448                 msg = wps_build_wsc_done(wps);
00449                 *op_code = WSC_Done;
00450                 break;
00451         default:
00452                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
00453                            "a message", wps->state);
00454                 msg = NULL;
00455                 break;
00456         }
00457 
00458         if (*op_code == WSC_MSG && msg) {
00459                 /* Save a copy of the last message for Authenticator derivation
00460                  */
00461                 wpabuf_free(wps->last_msg);
00462                 wps->last_msg = wpabuf_dup(msg);
00463         }
00464 
00465         return msg;
00466 }
00467 
00468 
00469 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
00470 {
00471         if (r_nonce == NULL) {
00472                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
00473                 return -1;
00474         }
00475 
00476         os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
00477         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
00478                     wps->nonce_r, WPS_NONCE_LEN);
00479 
00480         return 0;
00481 }
00482 
00483 
00484 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
00485 {
00486         if (e_nonce == NULL) {
00487                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
00488                 return -1;
00489         }
00490 
00491         if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
00492                 wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
00493                 return -1;
00494         }
00495 
00496         return 0;
00497 }
00498 
00499 
00500 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
00501 {
00502         if (uuid_r == NULL) {
00503                 wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
00504                 return -1;
00505         }
00506 
00507         os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
00508         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
00509 
00510         return 0;
00511 }
00512 
00513 
00514 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
00515                               size_t pk_len)
00516 {
00517         if (pk == NULL || pk_len == 0) {
00518                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
00519                 return -1;
00520         }
00521 
00522 #ifdef CONFIG_WPS_OOB
00523         if (wps->dev_pw_id != DEV_PW_DEFAULT &&
00524             wps->wps->oob_conf.pubkey_hash) {
00525                 const u8 *addr[1];
00526                 u8 hash[WPS_HASH_LEN];
00527 
00528                 addr[0] = pk;
00529                 sha256_vector(1, addr, &pk_len, hash);
00530                 if (os_memcmp(hash,
00531                               wpabuf_head(wps->wps->oob_conf.pubkey_hash),
00532                               WPS_OOB_PUBKEY_HASH_LEN) != 0) {
00533                         wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
00534                         return -1;
00535                 }
00536         }
00537 #endif /* CONFIG_WPS_OOB */
00538 
00539         wpabuf_free(wps->dh_pubkey_r);
00540         wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
00541         if (wps->dh_pubkey_r == NULL)
00542                 return -1;
00543 
00544         if (wps_derive_keys(wps) < 0)
00545                 return -1;
00546 
00547         return 0;
00548 }
00549 
00550 
00551 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
00552 {
00553         if (r_hash1 == NULL) {
00554                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
00555                 return -1;
00556         }
00557 
00558         os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
00559         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
00560 
00561         return 0;
00562 }
00563 
00564 
00565 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
00566 {
00567         if (r_hash2 == NULL) {
00568                 wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
00569                 return -1;
00570         }
00571 
00572         os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
00573         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
00574 
00575         return 0;
00576 }
00577 
00578 
00579 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
00580 {
00581         u8 hash[SHA256_MAC_LEN];
00582         const u8 *addr[4];
00583         size_t len[4];
00584 
00585         if (r_snonce1 == NULL) {
00586                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
00587                 return -1;
00588         }
00589 
00590         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
00591                         WPS_SECRET_NONCE_LEN);
00592 
00593         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
00594         addr[0] = r_snonce1;
00595         len[0] = WPS_SECRET_NONCE_LEN;
00596         addr[1] = wps->psk1;
00597         len[1] = WPS_PSK_LEN;
00598         addr[2] = wpabuf_head(wps->dh_pubkey_e);
00599         len[2] = wpabuf_len(wps->dh_pubkey_e);
00600         addr[3] = wpabuf_head(wps->dh_pubkey_r);
00601         len[3] = wpabuf_len(wps->dh_pubkey_r);
00602         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
00603 
00604         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
00605                 wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
00606                            "not match with the pre-committed value");
00607                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
00608                 wps_pwd_auth_fail_event(wps->wps, 1, 1);
00609                 return -1;
00610         }
00611 
00612         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
00613                    "half of the device password");
00614 
00615         return 0;
00616 }
00617 
00618 
00619 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
00620 {
00621         u8 hash[SHA256_MAC_LEN];
00622         const u8 *addr[4];
00623         size_t len[4];
00624 
00625         if (r_snonce2 == NULL) {
00626                 wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
00627                 return -1;
00628         }
00629 
00630         wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
00631                         WPS_SECRET_NONCE_LEN);
00632 
00633         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
00634         addr[0] = r_snonce2;
00635         len[0] = WPS_SECRET_NONCE_LEN;
00636         addr[1] = wps->psk2;
00637         len[1] = WPS_PSK_LEN;
00638         addr[2] = wpabuf_head(wps->dh_pubkey_e);
00639         len[2] = wpabuf_len(wps->dh_pubkey_e);
00640         addr[3] = wpabuf_head(wps->dh_pubkey_r);
00641         len[3] = wpabuf_len(wps->dh_pubkey_r);
00642         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
00643 
00644         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
00645                 wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
00646                            "not match with the pre-committed value");
00647                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
00648                 wps_pwd_auth_fail_event(wps->wps, 1, 2);
00649                 return -1;
00650         }
00651 
00652         wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
00653                    "half of the device password");
00654 
00655         return 0;
00656 }
00657 
00658 
00659 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
00660                               size_t cred_len)
00661 {
00662         struct wps_parse_attr attr;
00663         struct wpabuf msg;
00664 
00665         wpa_printf(MSG_DEBUG, "WPS: Received Credential");
00666         os_memset(&wps->cred, 0, sizeof(wps->cred));
00667         wpabuf_set(&msg, cred, cred_len);
00668         if (wps_parse_msg(&msg, &attr) < 0 ||
00669             wps_process_cred(&attr, &wps->cred))
00670                 return -1;
00671 
00672         if (os_memcmp(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
00673             0) {
00674                 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
00675                            MACSTR ") does not match with own address (" MACSTR
00676                            ")", MAC2STR(wps->cred.mac_addr),
00677                            MAC2STR(wps->wps->dev.mac_addr));
00678                 /*
00679                  * In theory, this could be consider fatal error, but there are
00680                  * number of deployed implementations using other address here
00681                  * due to unclarity in the specification. For interoperability
00682                  * reasons, allow this to be processed since we do not really
00683                  * use the MAC Address information for anything.
00684                  */
00685         }
00686 
00687         if (wps->wps->cred_cb) {
00688                 wps->cred.cred_attr = cred - 4;
00689                 wps->cred.cred_attr_len = cred_len + 4;
00690                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
00691                 wps->cred.cred_attr = NULL;
00692                 wps->cred.cred_attr_len = 0;
00693         }
00694 
00695         return 0;
00696 }
00697 
00698 
00699 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
00700                              size_t cred_len[], size_t num_cred)
00701 {
00702         size_t i;
00703 
00704         if (wps->wps->ap)
00705                 return 0;
00706 
00707         if (num_cred == 0) {
00708                 wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
00709                            "received");
00710                 return -1;
00711         }
00712 
00713         for (i = 0; i < num_cred; i++) {
00714                 if (wps_process_cred_e(wps, cred[i], cred_len[i]))
00715                         return -1;
00716         }
00717 
00718         return 0;
00719 }
00720 
00721 
00722 static int wps_process_ap_settings_e(struct wps_data *wps,
00723                                      struct wps_parse_attr *attr,
00724                                      struct wpabuf *attrs)
00725 {
00726         struct wps_credential cred;
00727 
00728         if (!wps->wps->ap)
00729                 return 0;
00730 
00731         if (wps_process_ap_settings(attr, &cred) < 0)
00732                 return -1;
00733 
00734         wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
00735                    "Registrar");
00736 
00737         if (os_memcmp(cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN) !=
00738             0) {
00739                 wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
00740                            MACSTR ") does not match with own address (" MACSTR
00741                            ")", MAC2STR(cred.mac_addr),
00742                            MAC2STR(wps->wps->dev.mac_addr));
00743                 /*
00744                  * In theory, this could be consider fatal error, but there are
00745                  * number of deployed implementations using other address here
00746                  * due to unclarity in the specification. For interoperability
00747                  * reasons, allow this to be processed since we do not really
00748                  * use the MAC Address information for anything.
00749                  */
00750         }
00751 
00752         if (wps->wps->cred_cb) {
00753                 cred.cred_attr = wpabuf_head(attrs);
00754                 cred.cred_attr_len = wpabuf_len(attrs);
00755                 wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
00756         }
00757 
00758         return 0;
00759 }
00760 
00761 
00762 static enum wps_process_res wps_process_m2(struct wps_data *wps,
00763                                            const struct wpabuf *msg,
00764                                            struct wps_parse_attr *attr)
00765 {
00766         wpa_printf(MSG_DEBUG, "WPS: Received M2");
00767 
00768         if (wps->state != RECV_M2) {
00769                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
00770                            "receiving M2", wps->state);
00771                 wps->state = SEND_WSC_NACK;
00772                 return WPS_CONTINUE;
00773         }
00774 
00775         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
00776             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
00777             wps_process_uuid_r(wps, attr->uuid_r) ||
00778             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
00779             wps_process_authenticator(wps, attr->authenticator, msg) ||
00780             wps_process_device_attrs(&wps->peer_dev, attr)) {
00781                 wps->state = SEND_WSC_NACK;
00782                 return WPS_CONTINUE;
00783         }
00784 
00785         if (wps->wps->ap && wps->wps->ap_setup_locked) {
00786                 wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
00787                            "registration of a new Registrar");
00788                 wps->config_error = WPS_CFG_SETUP_LOCKED;
00789                 wps->state = SEND_WSC_NACK;
00790                 return WPS_CONTINUE;
00791         }
00792 
00793         wps->state = SEND_M3;
00794         return WPS_CONTINUE;
00795 }
00796 
00797 
00798 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
00799                                             struct wps_parse_attr *attr)
00800 {
00801         wpa_printf(MSG_DEBUG, "WPS: Received M2D");
00802 
00803         if (wps->state != RECV_M2) {
00804                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
00805                            "receiving M2D", wps->state);
00806                 wps->state = SEND_WSC_NACK;
00807                 return WPS_CONTINUE;
00808         }
00809 
00810         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
00811                           attr->manufacturer, attr->manufacturer_len);
00812         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
00813                           attr->model_name, attr->model_name_len);
00814         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
00815                           attr->model_number, attr->model_number_len);
00816         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
00817                           attr->serial_number, attr->serial_number_len);
00818         wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
00819                           attr->dev_name, attr->dev_name_len);
00820 
00821         if (wps->wps->event_cb) {
00822                 union wps_event_data data;
00823                 struct wps_event_m2d *m2d = &data.m2d;
00824                 os_memset(&data, 0, sizeof(data));
00825                 if (attr->config_methods)
00826                         m2d->config_methods =
00827                                 WPA_GET_BE16(attr->config_methods);
00828                 m2d->manufacturer = attr->manufacturer;
00829                 m2d->manufacturer_len = attr->manufacturer_len;
00830                 m2d->model_name = attr->model_name;
00831                 m2d->model_name_len = attr->model_name_len;
00832                 m2d->model_number = attr->model_number;
00833                 m2d->model_number_len = attr->model_number_len;
00834                 m2d->serial_number = attr->serial_number;
00835                 m2d->serial_number_len = attr->serial_number_len;
00836                 m2d->dev_name = attr->dev_name;
00837                 m2d->dev_name_len = attr->dev_name_len;
00838                 m2d->primary_dev_type = attr->primary_dev_type;
00839                 if (attr->config_error)
00840                         m2d->config_error =
00841                                 WPA_GET_BE16(attr->config_error);
00842                 if (attr->dev_password_id)
00843                         m2d->dev_password_id =
00844                                 WPA_GET_BE16(attr->dev_password_id);
00845                 wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
00846         }
00847 
00848         wps->state = RECEIVED_M2D;
00849         return WPS_CONTINUE;
00850 }
00851 
00852 
00853 static enum wps_process_res wps_process_m4(struct wps_data *wps,
00854                                            const struct wpabuf *msg,
00855                                            struct wps_parse_attr *attr)
00856 {
00857         struct wpabuf *decrypted;
00858         struct wps_parse_attr eattr;
00859 
00860         wpa_printf(MSG_DEBUG, "WPS: Received M4");
00861 
00862         if (wps->state != RECV_M4) {
00863                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
00864                            "receiving M4", wps->state);
00865                 wps->state = SEND_WSC_NACK;
00866                 return WPS_CONTINUE;
00867         }
00868 
00869         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
00870             wps_process_authenticator(wps, attr->authenticator, msg) ||
00871             wps_process_r_hash1(wps, attr->r_hash1) ||
00872             wps_process_r_hash2(wps, attr->r_hash2)) {
00873                 wps->state = SEND_WSC_NACK;
00874                 return WPS_CONTINUE;
00875         }
00876 
00877         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
00878                                               attr->encr_settings_len);
00879         if (decrypted == NULL) {
00880                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
00881                            "Settings attribute");
00882                 wps->state = SEND_WSC_NACK;
00883                 return WPS_CONTINUE;
00884         }
00885 
00886         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
00887                    "attribute");
00888         if (wps_parse_msg(decrypted, &eattr) < 0 ||
00889             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
00890             wps_process_r_snonce1(wps, eattr.r_snonce1)) {
00891                 wpabuf_free(decrypted);
00892                 wps->state = SEND_WSC_NACK;
00893                 return WPS_CONTINUE;
00894         }
00895         wpabuf_free(decrypted);
00896 
00897         wps->state = SEND_M5;
00898         return WPS_CONTINUE;
00899 }
00900 
00901 
00902 static enum wps_process_res wps_process_m6(struct wps_data *wps,
00903                                            const struct wpabuf *msg,
00904                                            struct wps_parse_attr *attr)
00905 {
00906         struct wpabuf *decrypted;
00907         struct wps_parse_attr eattr;
00908 
00909         wpa_printf(MSG_DEBUG, "WPS: Received M6");
00910 
00911         if (wps->state != RECV_M6) {
00912                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
00913                            "receiving M6", wps->state);
00914                 wps->state = SEND_WSC_NACK;
00915                 return WPS_CONTINUE;
00916         }
00917 
00918         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
00919             wps_process_authenticator(wps, attr->authenticator, msg)) {
00920                 wps->state = SEND_WSC_NACK;
00921                 return WPS_CONTINUE;
00922         }
00923 
00924         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
00925                                               attr->encr_settings_len);
00926         if (decrypted == NULL) {
00927                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
00928                            "Settings attribute");
00929                 wps->state = SEND_WSC_NACK;
00930                 return WPS_CONTINUE;
00931         }
00932 
00933         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
00934                    "attribute");
00935         if (wps_parse_msg(decrypted, &eattr) < 0 ||
00936             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
00937             wps_process_r_snonce2(wps, eattr.r_snonce2)) {
00938                 wpabuf_free(decrypted);
00939                 wps->state = SEND_WSC_NACK;
00940                 return WPS_CONTINUE;
00941         }
00942         wpabuf_free(decrypted);
00943 
00944         wps->state = SEND_M7;
00945         return WPS_CONTINUE;
00946 }
00947 
00948 
00949 static enum wps_process_res wps_process_m8(struct wps_data *wps,
00950                                            const struct wpabuf *msg,
00951                                            struct wps_parse_attr *attr)
00952 {
00953         struct wpabuf *decrypted;
00954         struct wps_parse_attr eattr;
00955 
00956         wpa_printf(MSG_DEBUG, "WPS: Received M8");
00957 
00958         if (wps->state != RECV_M8) {
00959                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
00960                            "receiving M8", wps->state);
00961                 wps->state = SEND_WSC_NACK;
00962                 return WPS_CONTINUE;
00963         }
00964 
00965         if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
00966             wps_process_authenticator(wps, attr->authenticator, msg)) {
00967                 wps->state = SEND_WSC_NACK;
00968                 return WPS_CONTINUE;
00969         }
00970 
00971         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
00972                                               attr->encr_settings_len);
00973         if (decrypted == NULL) {
00974                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
00975                            "Settings attribute");
00976                 wps->state = SEND_WSC_NACK;
00977                 return WPS_CONTINUE;
00978         }
00979 
00980         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
00981                    "attribute");
00982         if (wps_parse_msg(decrypted, &eattr) < 0 ||
00983             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
00984             wps_process_creds(wps, eattr.cred, eattr.cred_len,
00985                               eattr.num_cred) ||
00986             wps_process_ap_settings_e(wps, &eattr, decrypted)) {
00987                 wpabuf_free(decrypted);
00988                 wps->state = SEND_WSC_NACK;
00989                 return WPS_CONTINUE;
00990         }
00991         wpabuf_free(decrypted);
00992 
00993         wps->state = WPS_MSG_DONE;
00994         return WPS_CONTINUE;
00995 }
00996 
00997 
00998 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
00999                                                 const struct wpabuf *msg)
01000 {
01001         struct wps_parse_attr attr;
01002         enum wps_process_res ret = WPS_CONTINUE;
01003 
01004         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
01005 
01006         if (wps_parse_msg(msg, &attr) < 0)
01007                 return WPS_FAILURE;
01008 
01009         if (!wps_version_supported(attr.version)) {
01010                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
01011                            attr.version ? *attr.version : 0);
01012                 return WPS_FAILURE;
01013         }
01014 
01015         if (attr.enrollee_nonce == NULL ||
01016             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
01017                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
01018                 return WPS_FAILURE;
01019         }
01020 
01021         if (attr.msg_type == NULL) {
01022                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
01023                 return WPS_FAILURE;
01024         }
01025 
01026         switch (*attr.msg_type) {
01027         case WPS_M2:
01028                 ret = wps_process_m2(wps, msg, &attr);
01029                 break;
01030         case WPS_M2D:
01031                 ret = wps_process_m2d(wps, &attr);
01032                 break;
01033         case WPS_M4:
01034                 ret = wps_process_m4(wps, msg, &attr);
01035                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
01036                         wps_fail_event(wps->wps, WPS_M4);
01037                 break;
01038         case WPS_M6:
01039                 ret = wps_process_m6(wps, msg, &attr);
01040                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
01041                         wps_fail_event(wps->wps, WPS_M6);
01042                 break;
01043         case WPS_M8:
01044                 ret = wps_process_m8(wps, msg, &attr);
01045                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
01046                         wps_fail_event(wps->wps, WPS_M8);
01047                 break;
01048         default:
01049                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
01050                            *attr.msg_type);
01051                 return WPS_FAILURE;
01052         }
01053 
01054         /*
01055          * Save a copy of the last message for Authenticator derivation if we
01056          * are continuing. However, skip M2D since it is not authenticated and
01057          * neither is the ACK/NACK response frame. This allows the possibly
01058          * following M2 to be processed correctly by using the previously sent
01059          * M1 in Authenticator derivation.
01060          */
01061         if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
01062                 /* Save a copy of the last message for Authenticator derivation
01063                  */
01064                 wpabuf_free(wps->last_msg);
01065                 wps->last_msg = wpabuf_dup(msg);
01066         }
01067 
01068         return ret;
01069 }
01070 
01071 
01072 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
01073                                                 const struct wpabuf *msg)
01074 {
01075         struct wps_parse_attr attr;
01076 
01077         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
01078 
01079         if (wps_parse_msg(msg, &attr) < 0)
01080                 return WPS_FAILURE;
01081 
01082         if (!wps_version_supported(attr.version)) {
01083                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
01084                            attr.version ? *attr.version : 0);
01085                 return WPS_FAILURE;
01086         }
01087 
01088         if (attr.msg_type == NULL) {
01089                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
01090                 return WPS_FAILURE;
01091         }
01092 
01093         if (*attr.msg_type != WPS_WSC_ACK) {
01094                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
01095                            *attr.msg_type);
01096                 return WPS_FAILURE;
01097         }
01098 
01099         if (attr.registrar_nonce == NULL ||
01100             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
01101         {
01102                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
01103                 return WPS_FAILURE;
01104         }
01105 
01106         if (attr.enrollee_nonce == NULL ||
01107             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
01108                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
01109                 return WPS_FAILURE;
01110         }
01111 
01112         if (wps->state == RECV_ACK && wps->wps->ap) {
01113                 wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
01114                            "completed successfully");
01115                 wps_success_event(wps->wps);
01116                 wps->state = WPS_FINISHED;
01117                 return WPS_DONE;
01118         }
01119 
01120         return WPS_FAILURE;
01121 }
01122 
01123 
01124 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
01125                                                  const struct wpabuf *msg)
01126 {
01127         struct wps_parse_attr attr;
01128 
01129         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
01130 
01131         if (wps_parse_msg(msg, &attr) < 0)
01132                 return WPS_FAILURE;
01133 
01134         if (!wps_version_supported(attr.version)) {
01135                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
01136                            attr.version ? *attr.version : 0);
01137                 return WPS_FAILURE;
01138         }
01139 
01140         if (attr.msg_type == NULL) {
01141                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
01142                 return WPS_FAILURE;
01143         }
01144 
01145         if (*attr.msg_type != WPS_WSC_NACK) {
01146                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
01147                            *attr.msg_type);
01148                 return WPS_FAILURE;
01149         }
01150 
01151         if (attr.registrar_nonce == NULL ||
01152             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
01153         {
01154                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
01155                 wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
01156                             attr.registrar_nonce, WPS_NONCE_LEN);
01157                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
01158                             wps->nonce_r, WPS_NONCE_LEN);
01159                 return WPS_FAILURE;
01160         }
01161 
01162         if (attr.enrollee_nonce == NULL ||
01163             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
01164                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
01165                 wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
01166                             attr.enrollee_nonce, WPS_NONCE_LEN);
01167                 wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
01168                             wps->nonce_e, WPS_NONCE_LEN);
01169                 return WPS_FAILURE;
01170         }
01171 
01172         if (attr.config_error == NULL) {
01173                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
01174                            "in WSC_NACK");
01175                 return WPS_FAILURE;
01176         }
01177 
01178         wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
01179                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
01180 
01181         switch (wps->state) {
01182         case RECV_M4:
01183                 wps_fail_event(wps->wps, WPS_M3);
01184                 break;
01185         case RECV_M6:
01186                 wps_fail_event(wps->wps, WPS_M5);
01187                 break;
01188         case RECV_M8:
01189                 wps_fail_event(wps->wps, WPS_M7);
01190                 break;
01191         default:
01192                 break;
01193         }
01194 
01195         /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
01196          * Enrollee is Authenticator */
01197         wps->state = SEND_WSC_NACK;
01198 
01199         return WPS_FAILURE;
01200 }
01201 
01202 
01203 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
01204                                               enum wsc_op_code op_code,
01205                                               const struct wpabuf *msg)
01206 {
01207 
01208         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
01209                    "op_code=%d)",
01210                    (unsigned long) wpabuf_len(msg), op_code);
01211 
01212         if (op_code == WSC_UPnP) {
01213                 /* Determine the OpCode based on message type attribute */
01214                 struct wps_parse_attr attr;
01215                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
01216                         if (*attr.msg_type == WPS_WSC_ACK)
01217                                 op_code = WSC_ACK;
01218                         else if (*attr.msg_type == WPS_WSC_NACK)
01219                                 op_code = WSC_NACK;
01220                 }
01221         }
01222 
01223         switch (op_code) {
01224         case WSC_MSG:
01225         case WSC_UPnP:
01226                 return wps_process_wsc_msg(wps, msg);
01227         case WSC_ACK:
01228                 return wps_process_wsc_ack(wps, msg);
01229         case WSC_NACK:
01230                 return wps_process_wsc_nack(wps, msg);
01231         default:
01232                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
01233                 return WPS_FAILURE;
01234         }
01235 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Jan 2 2014 11:26:39