1 /*
2  * Wi-Fi Protected Setup - Enrollee
3  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "crypto/crypto.h"
13 #include "crypto/sha256.h"
14 #include "crypto/random.h"
15 #include "wps_i.h"
16 #include "wps_dev_attr.h"
17 
18 
wps_build_wps_state(struct wps_data * wps,struct wpabuf * msg)19 static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
20 {
21           u8 state;
22           if (wps->wps->ap)
23                     state = wps->wps->wps_state;
24           else
25                     state = WPS_STATE_NOT_CONFIGURED;
26           wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
27                        state);
28           wpabuf_put_be16(msg, ATTR_WPS_STATE);
29           wpabuf_put_be16(msg, 1);
30           wpabuf_put_u8(msg, state);
31           return 0;
32 }
33 
34 
wps_build_e_hash(struct wps_data * wps,struct wpabuf * msg)35 static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
36 {
37           u8 *hash;
38           const u8 *addr[4];
39           size_t len[4];
40 
41           if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
42                     return -1;
43           wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
44           wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
45                         wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
46 
47           if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
48                     wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
49                                  "E-Hash derivation");
50                     return -1;
51           }
52 
53           wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
54           wpabuf_put_be16(msg, ATTR_E_HASH1);
55           wpabuf_put_be16(msg, SHA256_MAC_LEN);
56           hash = wpabuf_put(msg, SHA256_MAC_LEN);
57           /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
58           addr[0] = wps->snonce;
59           len[0] = WPS_SECRET_NONCE_LEN;
60           addr[1] = wps->psk1;
61           len[1] = WPS_PSK_LEN;
62           addr[2] = wpabuf_head(wps->dh_pubkey_e);
63           len[2] = wpabuf_len(wps->dh_pubkey_e);
64           addr[3] = wpabuf_head(wps->dh_pubkey_r);
65           len[3] = wpabuf_len(wps->dh_pubkey_r);
66           hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
67           wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
68 
69           wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
70           wpabuf_put_be16(msg, ATTR_E_HASH2);
71           wpabuf_put_be16(msg, SHA256_MAC_LEN);
72           hash = wpabuf_put(msg, SHA256_MAC_LEN);
73           /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
74           addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
75           addr[1] = wps->psk2;
76           hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
77           wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
78 
79           return 0;
80 }
81 
82 
wps_build_e_snonce1(struct wps_data * wps,struct wpabuf * msg)83 static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
84 {
85           wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
86           wpabuf_put_be16(msg, ATTR_E_SNONCE1);
87           wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
88           wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
89           return 0;
90 }
91 
92 
wps_build_e_snonce2(struct wps_data * wps,struct wpabuf * msg)93 static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
94 {
95           wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
96           wpabuf_put_be16(msg, ATTR_E_SNONCE2);
97           wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
98           wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
99                               WPS_SECRET_NONCE_LEN);
100           return 0;
101 }
102 
103 
wps_build_m1(struct wps_data * wps)104 static struct wpabuf * wps_build_m1(struct wps_data *wps)
105 {
106           struct wpabuf *msg;
107           u16 config_methods;
108           u8 multi_ap_backhaul_sta = 0;
109 
110           if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
111                     return NULL;
112           wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
113                         wps->nonce_e, WPS_NONCE_LEN);
114 
115           wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
116           msg = wpabuf_alloc(1000);
117           if (msg == NULL)
118                     return NULL;
119 
120           config_methods = wps->wps->config_methods;
121           if (wps->wps->ap && !wps->pbc_in_m1 &&
122               (wps->dev_password_len != 0 ||
123                (config_methods & WPS_CONFIG_DISPLAY))) {
124                     /*
125                      * These are the methods that the AP supports as an Enrollee
126                      * for adding external Registrars, so remove PushButton.
127                      *
128                      * As a workaround for Windows 7 mechanism for probing WPS
129                      * capabilities from M1, leave PushButton option if no PIN
130                      * method is available or if WPS configuration enables PBC
131                      * workaround.
132                      */
133                     config_methods &= ~WPS_CONFIG_PUSHBUTTON;
134                     config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
135                                             WPS_CONFIG_PHY_PUSHBUTTON);
136           }
137 
138           if (wps->multi_ap_backhaul_sta)
139                     multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
140 
141           if (wps_build_version(msg) ||
142               wps_build_msg_type(msg, WPS_M1) ||
143               wps_build_uuid_e(msg, wps->uuid_e) ||
144               wps_build_mac_addr(msg, wps->mac_addr_e) ||
145               wps_build_enrollee_nonce(wps, msg) ||
146               wps_build_public_key(wps, msg) ||
147               wps_build_auth_type_flags(wps, msg) ||
148               wps_build_encr_type_flags(wps, msg) ||
149               wps_build_conn_type_flags(wps, msg) ||
150               wps_build_config_methods(msg, config_methods) ||
151               wps_build_wps_state(wps, msg) ||
152               wps_build_device_attrs(&wps->wps->dev, msg) ||
153               wps_build_rf_bands(&wps->wps->dev, msg,
154                                      wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
155               wps_build_assoc_state(wps, msg) ||
156               wps_build_dev_password_id(msg, wps->dev_pw_id) ||
157               wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
158               wps_build_os_version(&wps->wps->dev, msg) ||
159               wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
160               wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
161                     wpabuf_free(msg);
162                     return NULL;
163           }
164 
165           wps->state = RECV_M2;
166           return msg;
167 }
168 
169 
wps_build_m3(struct wps_data * wps)170 static struct wpabuf * wps_build_m3(struct wps_data *wps)
171 {
172           struct wpabuf *msg;
173 
174           wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
175 
176           if (wps->dev_password == NULL) {
177                     wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
178                     return NULL;
179           }
180           if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
181                     return NULL;
182 
183           if (wps->wps->ap && random_pool_ready() != 1) {
184                     wpa_printf(MSG_INFO,
185                                  "WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
186                     return NULL;
187           }
188 
189           msg = wpabuf_alloc(1000);
190           if (msg == NULL)
191                     return NULL;
192 
193           if (wps_build_version(msg) ||
194               wps_build_msg_type(msg, WPS_M3) ||
195               wps_build_registrar_nonce(wps, msg) ||
196               wps_build_e_hash(wps, msg) ||
197               wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
198               wps_build_authenticator(wps, msg)) {
199                     wpabuf_free(msg);
200                     return NULL;
201           }
202 
203           wps->state = RECV_M4;
204           return msg;
205 }
206 
207 
wps_build_m5(struct wps_data * wps)208 static struct wpabuf * wps_build_m5(struct wps_data *wps)
209 {
210           struct wpabuf *msg, *plain;
211 
212           wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
213 
214           plain = wpabuf_alloc(200);
215           if (plain == NULL)
216                     return NULL;
217 
218           msg = wpabuf_alloc(1000);
219           if (msg == NULL) {
220                     wpabuf_free(plain);
221                     return NULL;
222           }
223 
224           if (wps_build_version(msg) ||
225               wps_build_msg_type(msg, WPS_M5) ||
226               wps_build_registrar_nonce(wps, msg) ||
227               wps_build_e_snonce1(wps, plain) ||
228               wps_build_key_wrap_auth(wps, plain) ||
229               wps_build_encr_settings(wps, msg, plain) ||
230               wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
231               wps_build_authenticator(wps, msg)) {
232                     wpabuf_clear_free(plain);
233                     wpabuf_free(msg);
234                     return NULL;
235           }
236           wpabuf_clear_free(plain);
237 
238           wps->state = RECV_M6;
239           return msg;
240 }
241 
242 
wps_build_cred_ssid(struct wps_data * wps,struct wpabuf * msg)243 static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
244 {
245           wpa_printf(MSG_DEBUG, "WPS:  * SSID");
246           wpabuf_put_be16(msg, ATTR_SSID);
247           wpabuf_put_be16(msg, wps->wps->ssid_len);
248           wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
249           return 0;
250 }
251 
252 
wps_build_cred_auth_type(struct wps_data * wps,struct wpabuf * msg)253 static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
254 {
255           u16 auth_type = wps->wps->ap_auth_type;
256 
257           /*
258            * Work around issues with Windows 7 WPS implementation not liking
259            * multiple Authentication Type bits in M7 AP Settings attribute by
260            * showing only the most secure option from current configuration.
261            */
262           if (auth_type & WPS_AUTH_WPA2PSK)
263                     auth_type = WPS_AUTH_WPA2PSK;
264           else if (auth_type & WPS_AUTH_WPAPSK)
265                     auth_type = WPS_AUTH_WPAPSK;
266           else if (auth_type & WPS_AUTH_OPEN)
267                     auth_type = WPS_AUTH_OPEN;
268 
269           wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)", auth_type);
270           wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
271           wpabuf_put_be16(msg, 2);
272           wpabuf_put_be16(msg, auth_type);
273           return 0;
274 }
275 
276 
wps_build_cred_encr_type(struct wps_data * wps,struct wpabuf * msg)277 static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
278 {
279           u16 encr_type = wps->wps->ap_encr_type;
280 
281           /*
282            * Work around issues with Windows 7 WPS implementation not liking
283            * multiple Encryption Type bits in M7 AP Settings attribute by
284            * showing only the most secure option from current configuration.
285            */
286           if (wps->wps->ap_auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
287                     if (encr_type & WPS_ENCR_AES)
288                               encr_type = WPS_ENCR_AES;
289                     else if (encr_type & WPS_ENCR_TKIP)
290                               encr_type = WPS_ENCR_TKIP;
291           }
292 
293           wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)", encr_type);
294           wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
295           wpabuf_put_be16(msg, 2);
296           wpabuf_put_be16(msg, encr_type);
297           return 0;
298 }
299 
300 
wps_build_cred_network_key(struct wps_data * wps,struct wpabuf * msg)301 static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
302 {
303           if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
304               wps->wps->network_key_len == 0) {
305                     char hex[65];
306                     u8 psk[32];
307                     /* Generate a random per-device PSK */
308                     if (random_pool_ready() != 1 ||
309                         random_get_bytes(psk, sizeof(psk)) < 0) {
310                               wpa_printf(MSG_INFO,
311                                            "WPS: Could not generate random PSK");
312                               return -1;
313                     }
314                     wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
315                                         psk, sizeof(psk));
316                     wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
317                                  (unsigned int) wps->new_psk_len * 2);
318                     wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
319                     wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
320                     wpabuf_put_be16(msg, sizeof(psk) * 2);
321                     wpabuf_put_data(msg, hex, sizeof(psk) * 2);
322                     if (wps->wps->registrar) {
323                               wps_cb_new_psk(wps->wps->registrar,
324                                                wps->peer_dev.mac_addr,
325                                                wps->p2p_dev_addr, psk, sizeof(psk));
326                     }
327                     return 0;
328           }
329 
330           wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
331                        (unsigned int) wps->wps->network_key_len);
332           wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
333           wpabuf_put_be16(msg, wps->wps->network_key_len);
334           wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
335           return 0;
336 }
337 
338 
wps_build_cred_mac_addr(struct wps_data * wps,struct wpabuf * msg)339 static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
340 {
341           wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
342           wpabuf_put_be16(msg, ATTR_MAC_ADDR);
343           wpabuf_put_be16(msg, ETH_ALEN);
344           wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
345           return 0;
346 }
347 
348 
wps_build_ap_settings(struct wps_data * wps,struct wpabuf * plain)349 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
350 {
351           const u8 *start, *end;
352           int ret;
353 
354           if (wps->wps->ap_settings) {
355                     wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");
356                     wpabuf_put_data(plain, wps->wps->ap_settings,
357                                         wps->wps->ap_settings_len);
358                     return 0;
359           }
360 
361           wpa_printf(MSG_DEBUG, "WPS:  * AP Settings based on current configuration");
362           start = wpabuf_put(plain, 0);
363           ret = wps_build_cred_ssid(wps, plain) ||
364                     wps_build_cred_mac_addr(wps, plain) ||
365                     wps_build_cred_auth_type(wps, plain) ||
366                     wps_build_cred_encr_type(wps, plain) ||
367                     wps_build_cred_network_key(wps, plain);
368           end = wpabuf_put(plain, 0);
369 
370           wpa_hexdump_key(MSG_DEBUG, "WPS: Plaintext AP Settings",
371                               start, end - start);
372 
373           return ret;
374 }
375 
376 
wps_build_m7(struct wps_data * wps)377 static struct wpabuf * wps_build_m7(struct wps_data *wps)
378 {
379           struct wpabuf *msg, *plain;
380 
381           wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
382 
383           plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
384           if (plain == NULL)
385                     return NULL;
386 
387           msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
388           if (msg == NULL) {
389                     wpabuf_free(plain);
390                     return NULL;
391           }
392 
393           if (wps_build_version(msg) ||
394               wps_build_msg_type(msg, WPS_M7) ||
395               wps_build_registrar_nonce(wps, msg) ||
396               wps_build_e_snonce2(wps, plain) ||
397               (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
398               wps_build_key_wrap_auth(wps, plain) ||
399               wps_build_encr_settings(wps, msg, plain) ||
400               wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
401               wps_build_authenticator(wps, msg)) {
402                     wpabuf_clear_free(plain);
403                     wpabuf_free(msg);
404                     return NULL;
405           }
406           wpabuf_clear_free(plain);
407 
408           if (wps->wps->ap && wps->wps->registrar) {
409                     /*
410                      * If the Registrar is only learning our current configuration,
411                      * it may not continue protocol run to successful completion.
412                      * Store information here to make sure it remains available.
413                      */
414                     wps_device_store(wps->wps->registrar, &wps->peer_dev,
415                                          wps->uuid_r);
416           }
417 
418           wps->state = RECV_M8;
419           return msg;
420 }
421 
422 
wps_build_wsc_done(struct wps_data * wps)423 static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
424 {
425           struct wpabuf *msg;
426 
427           wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
428 
429           msg = wpabuf_alloc(1000);
430           if (msg == NULL)
431                     return NULL;
432 
433           if (wps_build_version(msg) ||
434               wps_build_msg_type(msg, WPS_WSC_DONE) ||
435               wps_build_enrollee_nonce(wps, msg) ||
436               wps_build_registrar_nonce(wps, msg) ||
437               wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
438                     wpabuf_free(msg);
439                     return NULL;
440           }
441 
442           if (wps->wps->ap)
443                     wps->state = RECV_ACK;
444           else {
445                     wps_success_event(wps->wps, wps->peer_dev.mac_addr);
446                     wps->state = WPS_FINISHED;
447           }
448           return msg;
449 }
450 
451 
wps_enrollee_get_msg(struct wps_data * wps,enum wsc_op_code * op_code)452 struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
453                                              enum wsc_op_code *op_code)
454 {
455           struct wpabuf *msg;
456 
457           switch (wps->state) {
458           case SEND_M1:
459                     msg = wps_build_m1(wps);
460                     *op_code = WSC_MSG;
461                     break;
462           case SEND_M3:
463                     msg = wps_build_m3(wps);
464                     *op_code = WSC_MSG;
465                     break;
466           case SEND_M5:
467                     msg = wps_build_m5(wps);
468                     *op_code = WSC_MSG;
469                     break;
470           case SEND_M7:
471                     msg = wps_build_m7(wps);
472                     *op_code = WSC_MSG;
473                     break;
474           case RECEIVED_M2D:
475                     if (wps->wps->ap) {
476                               msg = wps_build_wsc_nack(wps);
477                               *op_code = WSC_NACK;
478                               break;
479                     }
480                     msg = wps_build_wsc_ack(wps);
481                     *op_code = WSC_ACK;
482                     if (msg) {
483                               /* Another M2/M2D may be received */
484                               wps->state = RECV_M2;
485                     }
486                     break;
487           case SEND_WSC_NACK:
488                     msg = wps_build_wsc_nack(wps);
489                     *op_code = WSC_NACK;
490                     break;
491           case WPS_MSG_DONE:
492                     msg = wps_build_wsc_done(wps);
493                     *op_code = WSC_Done;
494                     break;
495           default:
496                     wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
497                                  "a message", wps->state);
498                     msg = NULL;
499                     break;
500           }
501 
502           if (*op_code == WSC_MSG && msg) {
503                     /* Save a copy of the last message for Authenticator derivation
504                      */
505                     wpabuf_free(wps->last_msg);
506                     wps->last_msg = wpabuf_dup(msg);
507           }
508 
509           return msg;
510 }
511 
512 
wps_process_registrar_nonce(struct wps_data * wps,const u8 * r_nonce)513 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
514 {
515           if (r_nonce == NULL) {
516                     wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
517                     return -1;
518           }
519 
520           os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
521           wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
522                         wps->nonce_r, WPS_NONCE_LEN);
523 
524           return 0;
525 }
526 
527 
wps_process_enrollee_nonce(struct wps_data * wps,const u8 * e_nonce)528 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
529 {
530           if (e_nonce == NULL) {
531                     wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
532                     return -1;
533           }
534 
535           if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
536                     wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
537                     return -1;
538           }
539 
540           return 0;
541 }
542 
543 
wps_process_uuid_r(struct wps_data * wps,const u8 * uuid_r)544 static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
545 {
546           if (uuid_r == NULL) {
547                     wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
548                     return -1;
549           }
550 
551           os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
552           wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
553 
554           return 0;
555 }
556 
557 
wps_process_pubkey(struct wps_data * wps,const u8 * pk,size_t pk_len)558 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
559                                     size_t pk_len)
560 {
561           if (pk == NULL || pk_len == 0) {
562                     wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
563                     return -1;
564           }
565 
566           if (wps->peer_pubkey_hash_set) {
567                     u8 hash[WPS_HASH_LEN];
568                     sha256_vector(1, &pk, &pk_len, hash);
569                     if (os_memcmp_const(hash, wps->peer_pubkey_hash,
570                                             WPS_OOB_PUBKEY_HASH_LEN) != 0) {
571                               wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
572                               wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
573                                             pk, pk_len);
574                               wpa_hexdump(MSG_DEBUG, "WPS: Calculated public key "
575                                             "hash", hash, WPS_OOB_PUBKEY_HASH_LEN);
576                               wpa_hexdump(MSG_DEBUG, "WPS: Expected public key hash",
577                                             wps->peer_pubkey_hash,
578                                             WPS_OOB_PUBKEY_HASH_LEN);
579                               wps->config_error = WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
580                               return -1;
581                     }
582           }
583 
584           wpabuf_free(wps->dh_pubkey_r);
585           wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
586           if (wps->dh_pubkey_r == NULL)
587                     return -1;
588 
589           if (wps_derive_keys(wps) < 0)
590                     return -1;
591 
592           return 0;
593 }
594 
595 
wps_process_r_hash1(struct wps_data * wps,const u8 * r_hash1)596 static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
597 {
598           if (r_hash1 == NULL) {
599                     wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
600                     return -1;
601           }
602 
603           os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
604           wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
605 
606           return 0;
607 }
608 
609 
wps_process_r_hash2(struct wps_data * wps,const u8 * r_hash2)610 static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
611 {
612           if (r_hash2 == NULL) {
613                     wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
614                     return -1;
615           }
616 
617           os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
618           wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
619 
620           return 0;
621 }
622 
623 
wps_process_r_snonce1(struct wps_data * wps,const u8 * r_snonce1)624 static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
625 {
626           u8 hash[SHA256_MAC_LEN];
627           const u8 *addr[4];
628           size_t len[4];
629 
630           if (r_snonce1 == NULL) {
631                     wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
632                     return -1;
633           }
634 
635           wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
636                               WPS_SECRET_NONCE_LEN);
637 
638           /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
639           addr[0] = r_snonce1;
640           len[0] = WPS_SECRET_NONCE_LEN;
641           addr[1] = wps->psk1;
642           len[1] = WPS_PSK_LEN;
643           addr[2] = wpabuf_head(wps->dh_pubkey_e);
644           len[2] = wpabuf_len(wps->dh_pubkey_e);
645           addr[3] = wpabuf_head(wps->dh_pubkey_r);
646           len[3] = wpabuf_len(wps->dh_pubkey_r);
647           hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
648 
649           if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
650                     wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
651                                  "not match with the pre-committed value");
652                     wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
653                     wps_pwd_auth_fail_event(wps->wps, 1, 1, wps->peer_dev.mac_addr);
654                     return -1;
655           }
656 
657           wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
658                        "half of the device password");
659 
660           return 0;
661 }
662 
663 
wps_process_r_snonce2(struct wps_data * wps,const u8 * r_snonce2)664 static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
665 {
666           u8 hash[SHA256_MAC_LEN];
667           const u8 *addr[4];
668           size_t len[4];
669 
670           if (r_snonce2 == NULL) {
671                     wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
672                     return -1;
673           }
674 
675           wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
676                               WPS_SECRET_NONCE_LEN);
677 
678           /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
679           addr[0] = r_snonce2;
680           len[0] = WPS_SECRET_NONCE_LEN;
681           addr[1] = wps->psk2;
682           len[1] = WPS_PSK_LEN;
683           addr[2] = wpabuf_head(wps->dh_pubkey_e);
684           len[2] = wpabuf_len(wps->dh_pubkey_e);
685           addr[3] = wpabuf_head(wps->dh_pubkey_r);
686           len[3] = wpabuf_len(wps->dh_pubkey_r);
687           hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
688 
689           if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
690                     wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
691                                  "not match with the pre-committed value");
692                     wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
693                     wps_pwd_auth_fail_event(wps->wps, 1, 2, wps->peer_dev.mac_addr);
694                     return -1;
695           }
696 
697           wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
698                        "half of the device password");
699 
700           return 0;
701 }
702 
703 
wps_process_cred_e(struct wps_data * wps,const u8 * cred,size_t cred_len,int wps2)704 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
705                                     size_t cred_len, int wps2)
706 {
707           struct wps_parse_attr attr;
708           struct wpabuf msg;
709           int ret = 0;
710 
711           wpa_printf(MSG_DEBUG, "WPS: Received Credential");
712           os_memset(&wps->cred, 0, sizeof(wps->cred));
713           wpabuf_set(&msg, cred, cred_len);
714           if (wps_parse_msg(&msg, &attr) < 0 ||
715               wps_process_cred(&attr, &wps->cred))
716                     return -1;
717 
718           if (!ether_addr_equal(wps->cred.mac_addr, wps->wps->dev.mac_addr)) {
719                     wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
720                                  MACSTR ") does not match with own address (" MACSTR
721                                  ")", MAC2STR(wps->cred.mac_addr),
722                                  MAC2STR(wps->wps->dev.mac_addr));
723                     /*
724                      * In theory, this could be consider fatal error, but there are
725                      * number of deployed implementations using other address here
726                      * due to unclarity in the specification. For interoperability
727                      * reasons, allow this to be processed since we do not really
728                      * use the MAC Address information for anything.
729                      */
730 #ifdef CONFIG_WPS_STRICT
731                     if (wps2) {
732                               wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
733                                            "MAC Address in AP Settings");
734                               return -1;
735                     }
736 #endif /* CONFIG_WPS_STRICT */
737           }
738 
739           if (!(wps->cred.encr_type &
740                 (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES))) {
741                     if (wps->cred.encr_type & WPS_ENCR_WEP) {
742                               wpa_printf(MSG_INFO, "WPS: Reject Credential "
743                                            "due to WEP configuration");
744                               wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
745                               return -2;
746                     }
747 
748                     wpa_printf(MSG_INFO, "WPS: Reject Credential due to "
749                                  "invalid encr_type 0x%x", wps->cred.encr_type);
750                     return -1;
751           }
752 
753           if (wps->wps->cred_cb) {
754                     wps->cred.cred_attr = cred - 4;
755                     wps->cred.cred_attr_len = cred_len + 4;
756                     ret = wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
757                     wps->cred.cred_attr = NULL;
758                     wps->cred.cred_attr_len = 0;
759           }
760 
761           return ret;
762 }
763 
764 
wps_process_creds(struct wps_data * wps,const u8 * cred[],u16 cred_len[],unsigned int num_cred,int wps2)765 static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
766                                    u16 cred_len[], unsigned int num_cred, int wps2)
767 {
768           size_t i;
769           int ok = 0;
770 
771           if (wps->wps->ap)
772                     return 0;
773 
774           if (num_cred == 0) {
775                     wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
776                                  "received");
777                     return -1;
778           }
779 
780           for (i = 0; i < num_cred; i++) {
781                     int res;
782                     res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
783                     if (res == 0)
784                               ok++;
785                     else if (res == -2)
786                               wpa_printf(MSG_DEBUG, "WPS: WEP credential skipped");
787                     else
788                               return -1;
789           }
790 
791           if (ok == 0) {
792                     wpa_printf(MSG_DEBUG, "WPS: No valid Credential attribute "
793                                  "received");
794                     return -1;
795           }
796 
797           return 0;
798 }
799 
800 
wps_process_ap_settings_e(struct wps_data * wps,struct wps_parse_attr * attr,struct wpabuf * attrs,int wps2)801 static int wps_process_ap_settings_e(struct wps_data *wps,
802                                              struct wps_parse_attr *attr,
803                                              struct wpabuf *attrs, int wps2)
804 {
805           struct wps_credential cred;
806           int ret = 0;
807 
808           if (!wps->wps->ap)
809                     return 0;
810 
811           if (wps_process_ap_settings(attr, &cred) < 0)
812                     return -1;
813 
814           wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
815                        "Registrar");
816 
817           if (!ether_addr_equal(cred.mac_addr, wps->wps->dev.mac_addr)) {
818                     wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
819                                  MACSTR ") does not match with own address (" MACSTR
820                                  ")", MAC2STR(cred.mac_addr),
821                                  MAC2STR(wps->wps->dev.mac_addr));
822                     /*
823                      * In theory, this could be consider fatal error, but there are
824                      * number of deployed implementations using other address here
825                      * due to unclarity in the specification. For interoperability
826                      * reasons, allow this to be processed since we do not really
827                      * use the MAC Address information for anything.
828                      */
829 #ifdef CONFIG_WPS_STRICT
830                     if (wps2) {
831                               wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
832                                            "MAC Address in AP Settings");
833                               return -1;
834                     }
835 #endif /* CONFIG_WPS_STRICT */
836           }
837 
838           if (!(cred.encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
839           {
840                     if (cred.encr_type & WPS_ENCR_WEP) {
841                               wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
842                                            "due to WEP configuration");
843                               wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
844                               return -1;
845                     }
846 
847                     wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
848                                  "invalid encr_type 0x%x", cred.encr_type);
849                     return -1;
850           }
851 
852 #ifdef CONFIG_WPS_STRICT
853           if (wps2) {
854                     if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
855                         WPS_ENCR_TKIP ||
856                         (cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
857                         WPS_AUTH_WPAPSK) {
858                               wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
859                                            "AP Settings: WPA-Personal/TKIP only");
860                               wps->error_indication =
861                                         WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
862                               return -1;
863                     }
864           }
865 #endif /* CONFIG_WPS_STRICT */
866 
867           if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
868           {
869                     wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
870                                  "TKIP+AES");
871                     cred.encr_type |= WPS_ENCR_AES;
872           }
873 
874           if ((cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
875               WPS_AUTH_WPAPSK) {
876                     wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
877                                  "WPAPSK+WPA2PSK");
878                     cred.auth_type |= WPS_AUTH_WPA2PSK;
879           }
880 
881 #ifdef CONFIG_NO_TKIP
882           if (cred.encr_type & WPS_ENCR_TKIP) {
883                     wpa_printf(MSG_DEBUG, "WPS: Disable encr_type TKIP");
884                     cred.encr_type &= ~WPS_ENCR_TKIP;
885           }
886           if (cred.auth_type & WPS_AUTH_WPAPSK) {
887                     wpa_printf(MSG_DEBUG, "WPS: Disable auth_type WPAPSK");
888                     cred.auth_type &= ~WPS_AUTH_WPAPSK;
889           }
890 #endif /* CONFIG_NO_TKIP */
891 
892           if (wps->wps->cred_cb) {
893                     cred.cred_attr = wpabuf_head(attrs);
894                     cred.cred_attr_len = wpabuf_len(attrs);
895                     ret = wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
896           }
897 
898           return ret;
899 }
900 
901 
wps_process_dev_pw_id(struct wps_data * wps,const u8 * dev_pw_id)902 static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id)
903 {
904           u16 id;
905 
906           if (dev_pw_id == NULL) {
907                     wpa_printf(MSG_DEBUG, "WPS: Device Password ID");
908                     return -1;
909           }
910 
911           id = WPA_GET_BE16(dev_pw_id);
912           if (wps->dev_pw_id == id) {
913                     wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id);
914                     return 0;
915           }
916 
917 #ifdef CONFIG_P2P
918           if ((id == DEV_PW_DEFAULT &&
919                wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) ||
920               (id == DEV_PW_REGISTRAR_SPECIFIED &&
921                wps->dev_pw_id == DEV_PW_DEFAULT)) {
922                     /*
923                      * Common P2P use cases indicate whether the PIN is from the
924                      * client or GO using Device Password Id in M1/M2 in a way that
925                      * does not look fully compliant with WSC specification. Anyway,
926                      * this is deployed and needs to be allowed, so ignore changes
927                      * between Registrar-Specified and Default PIN.
928                      */
929                     wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID "
930                                  "change");
931                     return 0;
932           }
933 #endif /* CONFIG_P2P */
934 
935           wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
936                        "ID from %u to %u", wps->dev_pw_id, id);
937 
938           if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) {
939                     wpa_printf(MSG_DEBUG,
940                                  "WPS: Workaround - ignore PBC-to-PIN change");
941                     return 0;
942           }
943 
944           if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
945                     wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
946                     bin_clear_free(wps->dev_password, wps->dev_password_len);
947                     wps->dev_pw_id = wps->alt_dev_pw_id;
948                     wps->dev_password = wps->alt_dev_password;
949                     wps->dev_password_len = wps->alt_dev_password_len;
950                     wps->alt_dev_password = NULL;
951                     wps->alt_dev_password_len = 0;
952                     return 0;
953           }
954 
955           return -1;
956 }
957 
958 
wps_process_m2(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)959 static enum wps_process_res wps_process_m2(struct wps_data *wps,
960                                                      const struct wpabuf *msg,
961                                                      struct wps_parse_attr *attr)
962 {
963           wpa_printf(MSG_DEBUG, "WPS: Received M2");
964 
965           if (wps->state != RECV_M2) {
966                     wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
967                                  "receiving M2", wps->state);
968                     wps->state = SEND_WSC_NACK;
969                     return WPS_CONTINUE;
970           }
971 
972           if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
973               wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
974               wps_process_uuid_r(wps, attr->uuid_r) ||
975               wps_process_dev_pw_id(wps, attr->dev_password_id)) {
976                     wps->state = SEND_WSC_NACK;
977                     return WPS_CONTINUE;
978           }
979 
980           /*
981            * Stop here on an AP as an Enrollee if AP Setup is locked unless the
982            * special locked mode is used to allow protocol run up to M7 in order
983            * to support external Registrars that only learn the current AP
984            * configuration without changing it.
985            */
986           if (wps->wps->ap &&
987               ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) ||
988                wps->dev_password == NULL)) {
989                     wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
990                                  "registration of a new Registrar");
991                     wps->config_error = WPS_CFG_SETUP_LOCKED;
992                     wps->state = SEND_WSC_NACK;
993                     return WPS_CONTINUE;
994           }
995 
996           if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
997               wps_process_authenticator(wps, attr->authenticator, msg) ||
998               wps_process_device_attrs(&wps->peer_dev, attr)) {
999                     wps->state = SEND_WSC_NACK;
1000                     return WPS_CONTINUE;
1001           }
1002 
1003 #ifdef CONFIG_WPS_NFC
1004           if (wps->peer_pubkey_hash_set) {
1005                     struct wpabuf *decrypted;
1006                     struct wps_parse_attr eattr;
1007 
1008                     decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1009                                                                   attr->encr_settings_len);
1010                     if (decrypted == NULL) {
1011                               wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt "
1012                                            "Encrypted Settings attribute");
1013                               wps->state = SEND_WSC_NACK;
1014                               return WPS_CONTINUE;
1015                     }
1016 
1017                     wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted "
1018                                  "Settings attribute");
1019                     if (wps_parse_msg(decrypted, &eattr) < 0 ||
1020                         wps_process_key_wrap_auth(wps, decrypted,
1021                                                         eattr.key_wrap_auth) ||
1022                         wps_process_creds(wps, eattr.cred, eattr.cred_len,
1023                                               eattr.num_cred, attr->version2 != NULL)) {
1024                               wpabuf_clear_free(decrypted);
1025                               wps->state = SEND_WSC_NACK;
1026                               return WPS_CONTINUE;
1027                     }
1028                     wpabuf_clear_free(decrypted);
1029 
1030                     wps->state = WPS_MSG_DONE;
1031                     return WPS_CONTINUE;
1032           }
1033 #endif /* CONFIG_WPS_NFC */
1034 
1035           wps->state = SEND_M3;
1036           return WPS_CONTINUE;
1037 }
1038 
1039 
wps_process_m2d(struct wps_data * wps,struct wps_parse_attr * attr)1040 static enum wps_process_res wps_process_m2d(struct wps_data *wps,
1041                                                       struct wps_parse_attr *attr)
1042 {
1043           wpa_printf(MSG_DEBUG, "WPS: Received M2D");
1044 
1045           if (wps->state != RECV_M2) {
1046                     wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1047                                  "receiving M2D", wps->state);
1048                     wps->state = SEND_WSC_NACK;
1049                     return WPS_CONTINUE;
1050           }
1051 
1052           wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
1053                                 attr->manufacturer, attr->manufacturer_len);
1054           wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
1055                                 attr->model_name, attr->model_name_len);
1056           wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
1057                                 attr->model_number, attr->model_number_len);
1058           wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
1059                                 attr->serial_number, attr->serial_number_len);
1060           wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
1061                                 attr->dev_name, attr->dev_name_len);
1062 
1063           if (wps->wps->event_cb) {
1064                     union wps_event_data data;
1065                     struct wps_event_m2d *m2d = &data.m2d;
1066                     os_memset(&data, 0, sizeof(data));
1067                     if (attr->config_methods)
1068                               m2d->config_methods =
1069                                         WPA_GET_BE16(attr->config_methods);
1070                     m2d->manufacturer = attr->manufacturer;
1071                     m2d->manufacturer_len = attr->manufacturer_len;
1072                     m2d->model_name = attr->model_name;
1073                     m2d->model_name_len = attr->model_name_len;
1074                     m2d->model_number = attr->model_number;
1075                     m2d->model_number_len = attr->model_number_len;
1076                     m2d->serial_number = attr->serial_number;
1077                     m2d->serial_number_len = attr->serial_number_len;
1078                     m2d->dev_name = attr->dev_name;
1079                     m2d->dev_name_len = attr->dev_name_len;
1080                     m2d->primary_dev_type = attr->primary_dev_type;
1081                     if (attr->config_error)
1082                               m2d->config_error =
1083                                         WPA_GET_BE16(attr->config_error);
1084                     if (attr->dev_password_id)
1085                               m2d->dev_password_id =
1086                                         WPA_GET_BE16(attr->dev_password_id);
1087                     wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
1088           }
1089 
1090           wps->state = RECEIVED_M2D;
1091           return WPS_CONTINUE;
1092 }
1093 
1094 
wps_process_m4(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1095 static enum wps_process_res wps_process_m4(struct wps_data *wps,
1096                                                      const struct wpabuf *msg,
1097                                                      struct wps_parse_attr *attr)
1098 {
1099           struct wpabuf *decrypted;
1100           struct wps_parse_attr eattr;
1101 
1102           wpa_printf(MSG_DEBUG, "WPS: Received M4");
1103 
1104           if (wps->state != RECV_M4) {
1105                     wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1106                                  "receiving M4", wps->state);
1107                     wps->state = SEND_WSC_NACK;
1108                     return WPS_CONTINUE;
1109           }
1110 
1111           if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1112               wps_process_authenticator(wps, attr->authenticator, msg) ||
1113               wps_process_r_hash1(wps, attr->r_hash1) ||
1114               wps_process_r_hash2(wps, attr->r_hash2)) {
1115                     wps->state = SEND_WSC_NACK;
1116                     return WPS_CONTINUE;
1117           }
1118 
1119           decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1120                                                         attr->encr_settings_len);
1121           if (decrypted == NULL) {
1122                     wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1123                                  "Settings attribute");
1124                     wps->state = SEND_WSC_NACK;
1125                     return WPS_CONTINUE;
1126           }
1127 
1128           if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
1129                     wpabuf_clear_free(decrypted);
1130                     wps->state = SEND_WSC_NACK;
1131                     return WPS_CONTINUE;
1132           }
1133 
1134           wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1135                        "attribute");
1136           if (wps_parse_msg(decrypted, &eattr) < 0 ||
1137               wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1138               wps_process_r_snonce1(wps, eattr.r_snonce1)) {
1139                     wpabuf_clear_free(decrypted);
1140                     wps->state = SEND_WSC_NACK;
1141                     return WPS_CONTINUE;
1142           }
1143           wpabuf_clear_free(decrypted);
1144 
1145           wps->state = SEND_M5;
1146           return WPS_CONTINUE;
1147 }
1148 
1149 
wps_process_m6(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1150 static enum wps_process_res wps_process_m6(struct wps_data *wps,
1151                                                      const struct wpabuf *msg,
1152                                                      struct wps_parse_attr *attr)
1153 {
1154           struct wpabuf *decrypted;
1155           struct wps_parse_attr eattr;
1156 
1157           wpa_printf(MSG_DEBUG, "WPS: Received M6");
1158 
1159           if (wps->state != RECV_M6) {
1160                     wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1161                                  "receiving M6", wps->state);
1162                     wps->state = SEND_WSC_NACK;
1163                     return WPS_CONTINUE;
1164           }
1165 
1166           if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1167               wps_process_authenticator(wps, attr->authenticator, msg)) {
1168                     wps->state = SEND_WSC_NACK;
1169                     return WPS_CONTINUE;
1170           }
1171 
1172           decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1173                                                         attr->encr_settings_len);
1174           if (decrypted == NULL) {
1175                     wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1176                                  "Settings attribute");
1177                     wps->state = SEND_WSC_NACK;
1178                     return WPS_CONTINUE;
1179           }
1180 
1181           if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
1182                     wpabuf_clear_free(decrypted);
1183                     wps->state = SEND_WSC_NACK;
1184                     return WPS_CONTINUE;
1185           }
1186 
1187           wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1188                        "attribute");
1189           if (wps_parse_msg(decrypted, &eattr) < 0 ||
1190               wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1191               wps_process_r_snonce2(wps, eattr.r_snonce2)) {
1192                     wpabuf_clear_free(decrypted);
1193                     wps->state = SEND_WSC_NACK;
1194                     return WPS_CONTINUE;
1195           }
1196           wpabuf_clear_free(decrypted);
1197 
1198           if (wps->wps->ap)
1199                     wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
1200                                            NULL);
1201 
1202           wps->state = SEND_M7;
1203           return WPS_CONTINUE;
1204 }
1205 
1206 
wps_process_m8(struct wps_data * wps,const struct wpabuf * msg,struct wps_parse_attr * attr)1207 static enum wps_process_res wps_process_m8(struct wps_data *wps,
1208                                                      const struct wpabuf *msg,
1209                                                      struct wps_parse_attr *attr)
1210 {
1211           struct wpabuf *decrypted;
1212           struct wps_parse_attr eattr;
1213 
1214           wpa_printf(MSG_DEBUG, "WPS: Received M8");
1215 
1216           if (wps->state != RECV_M8) {
1217                     wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1218                                  "receiving M8", wps->state);
1219                     wps->state = SEND_WSC_NACK;
1220                     return WPS_CONTINUE;
1221           }
1222 
1223           if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1224               wps_process_authenticator(wps, attr->authenticator, msg)) {
1225                     wps->state = SEND_WSC_NACK;
1226                     return WPS_CONTINUE;
1227           }
1228 
1229           if (wps->wps->ap && wps->wps->ap_setup_locked) {
1230                     /*
1231                      * Stop here if special ap_setup_locked == 2 mode allowed the
1232                      * protocol to continue beyond M2. This allows ER to learn the
1233                      * current AP settings without changing them.
1234                      */
1235                     wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1236                                  "registration of a new Registrar");
1237                     wps->config_error = WPS_CFG_SETUP_LOCKED;
1238                     wps->state = SEND_WSC_NACK;
1239                     return WPS_CONTINUE;
1240           }
1241 
1242           decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1243                                                         attr->encr_settings_len);
1244           if (decrypted == NULL) {
1245                     wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1246                                  "Settings attribute");
1247                     wps->state = SEND_WSC_NACK;
1248                     return WPS_CONTINUE;
1249           }
1250 
1251           if (wps_validate_m8_encr(decrypted, wps->wps->ap,
1252                                          attr->version2 != NULL) < 0) {
1253                     wpabuf_clear_free(decrypted);
1254                     wps->state = SEND_WSC_NACK;
1255                     return WPS_CONTINUE;
1256           }
1257 
1258           wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1259                        "attribute");
1260           if (wps_parse_msg(decrypted, &eattr) < 0 ||
1261               wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1262               wps_process_creds(wps, eattr.cred, eattr.cred_len,
1263                                     eattr.num_cred, attr->version2 != NULL) ||
1264               wps_process_ap_settings_e(wps, &eattr, decrypted,
1265                                               attr->version2 != NULL)) {
1266                     wpabuf_clear_free(decrypted);
1267                     wps->state = SEND_WSC_NACK;
1268                     return WPS_CONTINUE;
1269           }
1270           wpabuf_clear_free(decrypted);
1271 
1272           wps->state = WPS_MSG_DONE;
1273           return WPS_CONTINUE;
1274 }
1275 
1276 
wps_process_wsc_msg(struct wps_data * wps,const struct wpabuf * msg)1277 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1278                                                             const struct wpabuf *msg)
1279 {
1280           struct wps_parse_attr attr;
1281           enum wps_process_res ret = WPS_CONTINUE;
1282 
1283           wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1284 
1285           if (wps_parse_msg(msg, &attr) < 0)
1286                     return WPS_FAILURE;
1287 
1288           if (attr.enrollee_nonce == NULL ||
1289               os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1290                     wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1291                     return WPS_FAILURE;
1292           }
1293 
1294           if (attr.msg_type == NULL) {
1295                     wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1296                     wps->state = SEND_WSC_NACK;
1297                     return WPS_CONTINUE;
1298           }
1299 
1300           switch (*attr.msg_type) {
1301           case WPS_M2:
1302                     if (wps_validate_m2(msg) < 0)
1303                               return WPS_FAILURE;
1304                     ret = wps_process_m2(wps, msg, &attr);
1305                     break;
1306           case WPS_M2D:
1307                     if (wps_validate_m2d(msg) < 0)
1308                               return WPS_FAILURE;
1309                     ret = wps_process_m2d(wps, &attr);
1310                     break;
1311           case WPS_M4:
1312                     if (wps_validate_m4(msg) < 0)
1313                               return WPS_FAILURE;
1314                     ret = wps_process_m4(wps, msg, &attr);
1315                     if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1316                               wps_fail_event(wps->wps, WPS_M4, wps->config_error,
1317                                                wps->error_indication,
1318                                                wps->peer_dev.mac_addr);
1319                     break;
1320           case WPS_M6:
1321                     if (wps_validate_m6(msg) < 0)
1322                               return WPS_FAILURE;
1323                     ret = wps_process_m6(wps, msg, &attr);
1324                     if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1325                               wps_fail_event(wps->wps, WPS_M6, wps->config_error,
1326                                                wps->error_indication,
1327                                                wps->peer_dev.mac_addr);
1328                     break;
1329           case WPS_M8:
1330                     if (wps_validate_m8(msg) < 0)
1331                               return WPS_FAILURE;
1332                     ret = wps_process_m8(wps, msg, &attr);
1333                     if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1334                               wps_fail_event(wps->wps, WPS_M8, wps->config_error,
1335                                                wps->error_indication,
1336                                                wps->peer_dev.mac_addr);
1337                     break;
1338           default:
1339                     wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1340                                  *attr.msg_type);
1341                     return WPS_FAILURE;
1342           }
1343 
1344           /*
1345            * Save a copy of the last message for Authenticator derivation if we
1346            * are continuing. However, skip M2D since it is not authenticated and
1347            * neither is the ACK/NACK response frame. This allows the possibly
1348            * following M2 to be processed correctly by using the previously sent
1349            * M1 in Authenticator derivation.
1350            */
1351           if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
1352                     /* Save a copy of the last message for Authenticator derivation
1353                      */
1354                     wpabuf_free(wps->last_msg);
1355                     wps->last_msg = wpabuf_dup(msg);
1356           }
1357 
1358           return ret;
1359 }
1360 
1361 
wps_process_wsc_ack(struct wps_data * wps,const struct wpabuf * msg)1362 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1363                                                             const struct wpabuf *msg)
1364 {
1365           struct wps_parse_attr attr;
1366 
1367           wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1368 
1369           if (wps_parse_msg(msg, &attr) < 0)
1370                     return WPS_FAILURE;
1371 
1372           if (attr.msg_type == NULL) {
1373                     wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1374                     return WPS_FAILURE;
1375           }
1376 
1377           if (*attr.msg_type != WPS_WSC_ACK) {
1378                     wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1379                                  *attr.msg_type);
1380                     return WPS_FAILURE;
1381           }
1382 
1383           if (attr.registrar_nonce == NULL ||
1384               os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1385           {
1386                     wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1387                     return WPS_FAILURE;
1388           }
1389 
1390           if (attr.enrollee_nonce == NULL ||
1391               os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1392                     wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1393                     return WPS_FAILURE;
1394           }
1395 
1396           if (wps->state == RECV_ACK && wps->wps->ap) {
1397                     wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1398                                  "completed successfully");
1399                     wps_success_event(wps->wps, wps->peer_dev.mac_addr);
1400                     wps->state = WPS_FINISHED;
1401                     return WPS_DONE;
1402           }
1403 
1404           return WPS_FAILURE;
1405 }
1406 
1407 
wps_process_wsc_nack(struct wps_data * wps,const struct wpabuf * msg)1408 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1409                                                              const struct wpabuf *msg)
1410 {
1411           struct wps_parse_attr attr;
1412           u16 config_error;
1413 
1414           wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1415 
1416           if (wps_parse_msg(msg, &attr) < 0)
1417                     return WPS_FAILURE;
1418 
1419           if (attr.msg_type == NULL) {
1420                     wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1421                     return WPS_FAILURE;
1422           }
1423 
1424           if (*attr.msg_type != WPS_WSC_NACK) {
1425                     wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1426                                  *attr.msg_type);
1427                     return WPS_FAILURE;
1428           }
1429 
1430           if (attr.registrar_nonce == NULL ||
1431               os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1432           {
1433                     wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1434                     wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1435                                   attr.registrar_nonce, WPS_NONCE_LEN);
1436                     wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1437                                   wps->nonce_r, WPS_NONCE_LEN);
1438                     return WPS_FAILURE;
1439           }
1440 
1441           if (attr.enrollee_nonce == NULL ||
1442               os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1443                     wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1444                     wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1445                                   attr.enrollee_nonce, WPS_NONCE_LEN);
1446                     wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1447                                   wps->nonce_e, WPS_NONCE_LEN);
1448                     return WPS_FAILURE;
1449           }
1450 
1451           if (attr.config_error == NULL) {
1452                     wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1453                                  "in WSC_NACK");
1454                     return WPS_FAILURE;
1455           }
1456 
1457           config_error = WPA_GET_BE16(attr.config_error);
1458           wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
1459                        "Configuration Error %d", config_error);
1460 
1461           switch (wps->state) {
1462           case RECV_M4:
1463                     wps_fail_event(wps->wps, WPS_M3, config_error,
1464                                      wps->error_indication, wps->peer_dev.mac_addr);
1465                     break;
1466           case RECV_M6:
1467                     wps_fail_event(wps->wps, WPS_M5, config_error,
1468                                      wps->error_indication, wps->peer_dev.mac_addr);
1469                     break;
1470           case RECV_M8:
1471                     wps_fail_event(wps->wps, WPS_M7, config_error,
1472                                      wps->error_indication, wps->peer_dev.mac_addr);
1473                     break;
1474           default:
1475                     break;
1476           }
1477 
1478           /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1479            * Enrollee is Authenticator */
1480           wps->state = SEND_WSC_NACK;
1481 
1482           return WPS_FAILURE;
1483 }
1484 
1485 
wps_enrollee_process_msg(struct wps_data * wps,enum wsc_op_code op_code,const struct wpabuf * msg)1486 enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
1487                                                         enum wsc_op_code op_code,
1488                                                         const struct wpabuf *msg)
1489 {
1490 
1491           wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1492                        "op_code=%d)",
1493                        (unsigned long) wpabuf_len(msg), op_code);
1494 
1495           if (op_code == WSC_UPnP) {
1496                     /* Determine the OpCode based on message type attribute */
1497                     struct wps_parse_attr attr;
1498                     if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
1499                               if (*attr.msg_type == WPS_WSC_ACK)
1500                                         op_code = WSC_ACK;
1501                               else if (*attr.msg_type == WPS_WSC_NACK)
1502                                         op_code = WSC_NACK;
1503                     }
1504           }
1505 
1506           switch (op_code) {
1507           case WSC_MSG:
1508           case WSC_UPnP:
1509                     return wps_process_wsc_msg(wps, msg);
1510           case WSC_ACK:
1511                     if (wps_validate_wsc_ack(msg) < 0)
1512                               return WPS_FAILURE;
1513                     return wps_process_wsc_ack(wps, msg);
1514           case WSC_NACK:
1515                     if (wps_validate_wsc_nack(msg) < 0)
1516                               return WPS_FAILURE;
1517                     return wps_process_wsc_nack(wps, msg);
1518           default:
1519                     wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1520                     return WPS_FAILURE;
1521           }
1522 }
1523