Changed the Network Index value to 1 since that is the default value
[wpasupplicant] / src / wps / wps_registrar.c
1 /*
2  * Wi-Fi Protected Setup - Registrar
3  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "sha256.h"
19 #include "base64.h"
20 #include "ieee802_11_defs.h"
21 #include "eloop.h"
22 #include "wps_i.h"
23 #include "wps_dev_attr.h"
24
25
26 struct wps_uuid_pin {
27         struct wps_uuid_pin *next;
28         u8 uuid[WPS_UUID_LEN];
29         int wildcard_uuid;
30         u8 *pin;
31         size_t pin_len;
32         int locked;
33 };
34
35
36 static void wps_free_pin(struct wps_uuid_pin *pin)
37 {
38         os_free(pin->pin);
39         os_free(pin);
40 }
41
42
43 static void wps_free_pins(struct wps_uuid_pin *pins)
44 {
45         struct wps_uuid_pin *pin, *prev;
46
47         pin = pins;
48         while (pin) {
49                 prev = pin;
50                 pin = pin->next;
51                 wps_free_pin(prev);
52         }
53 }
54
55
56 struct wps_pbc_session {
57         struct wps_pbc_session *next;
58         u8 addr[ETH_ALEN];
59         u8 uuid_e[WPS_UUID_LEN];
60         struct os_time timestamp;
61 };
62
63
64 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
65 {
66         struct wps_pbc_session *prev;
67
68         while (pbc) {
69                 prev = pbc;
70                 pbc = pbc->next;
71                 os_free(prev);
72         }
73 }
74
75
76 struct wps_registrar {
77         struct wps_context *wps;
78
79         int pbc;
80         int selected_registrar;
81
82         int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
83                           size_t psk_len);
84         int (*set_ie_cb)(void *ctx, const u8 *beacon_ie, size_t beacon_ie_len,
85                          const u8 *probe_resp_ie, size_t probe_resp_ie_len);
86         void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
87                               const struct wps_device_data *dev);
88         void *cb_ctx;
89
90         struct wps_uuid_pin *pins;
91         struct wps_pbc_session *pbc_sessions;
92
93         int skip_cred_build;
94         struct wpabuf *extra_cred;
95 };
96
97
98 static int wps_set_ie(struct wps_registrar *reg);
99 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
100
101
102 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
103                                           const u8 *addr, const u8 *uuid_e)
104 {
105         struct wps_pbc_session *pbc, *prev = NULL;
106         struct os_time now;
107
108         os_get_time(&now);
109
110         pbc = reg->pbc_sessions;
111         while (pbc) {
112                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
113                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
114                         if (prev)
115                                 prev->next = pbc->next;
116                         else
117                                 reg->pbc_sessions = pbc->next;
118                         break;
119                 }
120                 prev = pbc;
121                 pbc = pbc->next;
122         }
123
124         if (!pbc) {
125                 pbc = os_zalloc(sizeof(*pbc));
126                 if (pbc == NULL)
127                         return;
128                 os_memcpy(pbc->addr, addr, ETH_ALEN);
129                 if (uuid_e)
130                         os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
131         }
132
133         pbc->next = reg->pbc_sessions;
134         reg->pbc_sessions = pbc;
135         pbc->timestamp = now;
136
137         /* remove entries that have timed out */
138         prev = pbc;
139         pbc = pbc->next;
140
141         while (pbc) {
142                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
143                         prev->next = NULL;
144                         wps_free_pbc_sessions(pbc);
145                         break;
146                 }
147                 prev = pbc;
148                 pbc = pbc->next;
149         }
150 }
151
152
153 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
154                                              const u8 *addr, const u8 *uuid_e)
155 {
156         struct wps_pbc_session *pbc, *prev = NULL;
157
158         pbc = reg->pbc_sessions;
159         while (pbc) {
160                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
161                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
162                         if (prev)
163                                 prev->next = pbc->next;
164                         else
165                                 reg->pbc_sessions = pbc->next;
166                         os_free(pbc);
167                         break;
168                 }
169                 prev = pbc;
170                 pbc = pbc->next;
171         }
172 }
173
174
175 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
176                                      const u8 *addr, const u8 *uuid_e)
177 {
178         int count = 0;
179         struct wps_pbc_session *pbc;
180         struct os_time now;
181
182         os_get_time(&now);
183
184         for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
185                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
186                         break;
187                 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
188                     uuid_e == NULL ||
189                     os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
190                         count++;
191         }
192
193         if (addr || uuid_e)
194                 count++;
195
196         return count > 1 ? 1 : 0;
197 }
198
199
200 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
201 {
202         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
203                    wps->wps_state);
204         wpabuf_put_be16(msg, ATTR_WPS_STATE);
205         wpabuf_put_be16(msg, 1);
206         wpabuf_put_u8(msg, wps->wps_state);
207         return 0;
208 }
209
210
211 static int wps_build_ap_setup_locked(struct wps_context *wps,
212                                      struct wpabuf *msg)
213 {
214         if (wps->ap_setup_locked) {
215                 wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
216                 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
217                 wpabuf_put_be16(msg, 1);
218                 wpabuf_put_u8(msg, 1);
219         }
220         return 0;
221 }
222
223
224 static int wps_build_selected_registrar(struct wps_registrar *reg,
225                                         struct wpabuf *msg)
226 {
227         if (!reg->selected_registrar)
228                 return 0;
229         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
230         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
231         wpabuf_put_be16(msg, 1);
232         wpabuf_put_u8(msg, 1);
233         return 0;
234 }
235
236
237 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
238                                              struct wpabuf *msg)
239 {
240         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
241         if (!reg->selected_registrar)
242                 return 0;
243         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
244         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
245         wpabuf_put_be16(msg, 2);
246         wpabuf_put_be16(msg, id);
247         return 0;
248 }
249
250
251 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
252                                             struct wpabuf *msg)
253 {
254         u16 methods;
255         if (!reg->selected_registrar)
256                 return 0;
257         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
258         if (reg->pbc)
259                 methods |= WPS_CONFIG_PUSHBUTTON;
260         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
261                    methods);
262         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
263         wpabuf_put_be16(msg, 2);
264         wpabuf_put_be16(msg, methods);
265         return 0;
266 }
267
268
269 static int wps_build_probe_config_methods(struct wps_registrar *reg,
270                                           struct wpabuf *msg)
271 {
272         u16 methods;
273         methods = 0;
274         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
275         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
276         wpabuf_put_be16(msg, 2);
277         wpabuf_put_be16(msg, methods);
278         return 0;
279 }
280
281
282 static int wps_build_config_methods_r(struct wps_registrar *reg,
283                                       struct wpabuf *msg)
284 {
285         u16 methods;
286         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
287         if (reg->pbc)
288                 methods |= WPS_CONFIG_PUSHBUTTON;
289         return wps_build_config_methods(msg, methods);
290 }
291
292
293 static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
294 {
295         u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
296         wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", resp);
297         wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
298         wpabuf_put_be16(msg, 1);
299         wpabuf_put_u8(msg, resp);
300         return 0;
301 }
302
303
304 /**
305  * wps_registrar_init - Initialize WPS Registrar data
306  * @wps: Pointer to longterm WPS context
307  * @cfg: Registrar configuration
308  * Returns: Pointer to allocated Registrar data or %NULL on failure
309  *
310  * This function is used to initialize WPS Registrar functionality. It can be
311  * used for a single Registrar run (e.g., when run in a supplicant) or multiple
312  * runs (e.g., when run as an internal Registrar in an AP). Caller is
313  * responsible for freeing the returned data with wps_registrar_deinit() when
314  * Registrar functionality is not needed anymore.
315  */
316 struct wps_registrar *
317 wps_registrar_init(struct wps_context *wps,
318                    const struct wps_registrar_config *cfg)
319 {
320         struct wps_registrar *reg = os_zalloc(sizeof(*reg));
321         if (reg == NULL)
322                 return NULL;
323
324         reg->wps = wps;
325         reg->new_psk_cb = cfg->new_psk_cb;
326         reg->set_ie_cb = cfg->set_ie_cb;
327         reg->pin_needed_cb = cfg->pin_needed_cb;
328         reg->cb_ctx = cfg->cb_ctx;
329         reg->skip_cred_build = cfg->skip_cred_build;
330         if (cfg->extra_cred) {
331                 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
332                                                     cfg->extra_cred_len);
333                 if (reg->extra_cred == NULL) {
334                         os_free(reg);
335                         return NULL;
336                 }
337         }
338
339         if (wps_set_ie(reg)) {
340                 wps_registrar_deinit(reg);
341                 return NULL;
342         }
343
344         return reg;
345 }
346
347
348 /**
349  * wps_registrar_deinit - Deinitialize WPS Registrar data
350  * @reg: Registrar data from wps_registrar_init()
351  */
352 void wps_registrar_deinit(struct wps_registrar *reg)
353 {
354         if (reg == NULL)
355                 return;
356         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
357         wps_free_pins(reg->pins);
358         wps_free_pbc_sessions(reg->pbc_sessions);
359         wpabuf_free(reg->extra_cred);
360         os_free(reg);
361 }
362
363
364 /**
365  * wps_registrar_add_pin - Configure a new PIN for Registrar
366  * @reg: Registrar data from wps_registrar_init()
367  * @uuid: UUID-E or %NULL for wildcard (any UUID)
368  * @pin: PIN (Device Password)
369  * @pin_len: Length of pin in octets
370  * Returns: 0 on success, -1 on failure
371  */
372 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
373                           const u8 *pin, size_t pin_len)
374 {
375         struct wps_uuid_pin *p;
376
377         p = os_zalloc(sizeof(*p));
378         if (p == NULL)
379                 return -1;
380         if (uuid == NULL)
381                 p->wildcard_uuid = 1;
382         else
383                 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
384         p->pin = os_malloc(pin_len);
385         if (p->pin == NULL) {
386                 os_free(p);
387                 return -1;
388         }
389         os_memcpy(p->pin, pin, pin_len);
390         p->pin_len = pin_len;
391
392         p->next = reg->pins;
393         reg->pins = p;
394
395         wpa_printf(MSG_DEBUG, "WPS: A new PIN configured");
396         wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
397         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
398         reg->selected_registrar = 1;
399         reg->pbc = 0;
400         wps_set_ie(reg);
401
402         return 0;
403 }
404
405
406 /**
407  * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
408  * @reg: Registrar data from wps_registrar_init()
409  * @uuid: UUID-E
410  * Returns: 0 on success, -1 on failure (e.g., PIN not found)
411  */
412 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
413 {
414         struct wps_uuid_pin *pin, *prev;
415
416         prev = NULL;
417         pin = reg->pins;
418         while (pin) {
419                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
420                         if (prev == NULL)
421                                 reg->pins = pin->next;
422                         else
423                                 prev->next = pin->next;
424                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
425                                     pin->uuid, WPS_UUID_LEN);
426                         wps_free_pin(pin);
427                         return 0;
428                 }
429                 prev = pin;
430                 pin = pin->next;
431         }
432
433         return -1;
434 }
435
436
437 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
438                                         const u8 *uuid, size_t *pin_len)
439 {
440         struct wps_uuid_pin *pin;
441
442         pin = reg->pins;
443         while (pin) {
444                 if (!pin->wildcard_uuid &&
445                     os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
446                         break;
447                 pin = pin->next;
448         }
449
450         if (!pin) {
451                 /* Check for wildcard UUIDs since none of the UUID-specific
452                  * PINs matched */
453                 pin = reg->pins;
454                 while (pin) {
455                         if (pin->wildcard_uuid == 1) {
456                                 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
457                                            "PIN. Assigned it for this UUID-E");
458                                 pin->wildcard_uuid = 2;
459                                 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
460                                 break;
461                         }
462                         pin = pin->next;
463                 }
464         }
465
466         if (!pin)
467                 return NULL;
468
469         /*
470          * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
471          * that could otherwise avoid PIN invalidations.
472          */
473         if (pin->locked) {
474                 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
475                            "allow concurrent re-use");
476                 return NULL;
477         }
478         *pin_len = pin->pin_len;
479         pin->locked = 1;
480         return pin->pin;
481 }
482
483
484 /**
485  * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
486  * @reg: Registrar data from wps_registrar_init()
487  * @uuid: UUID-E
488  * Returns: 0 on success, -1 on failure
489  *
490  * PINs are locked to enforce only one concurrent use. This function unlocks a
491  * PIN to allow it to be used again. If the specified PIN was configured using
492  * a wildcard UUID, it will be removed instead of allowing multiple uses.
493  */
494 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
495 {
496         struct wps_uuid_pin *pin;
497
498         pin = reg->pins;
499         while (pin) {
500                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
501                         if (pin->wildcard_uuid == 2) {
502                                 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
503                                            "wildcard PIN");
504                                 return wps_registrar_invalidate_pin(reg, uuid);
505                         }
506                         pin->locked = 0;
507                         return 0;
508                 }
509                 pin = pin->next;
510         }
511
512         return -1;
513 }
514
515
516 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
517 {
518         reg->selected_registrar = 0;
519         reg->pbc = 0;
520         wps_set_ie(reg);
521 }
522
523
524 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
525 {
526         struct wps_registrar *reg = eloop_ctx;
527
528         wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
529         wps_registrar_stop_pbc(reg);
530 }
531
532
533 /**
534  * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
535  * @reg: Registrar data from wps_registrar_init()
536  * Returns: 0 on success, -1 on failure
537  *
538  * This function is called on an AP when a push button is pushed to activate
539  * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
540  * or when a PBC registration is completed.
541  */
542 int wps_registrar_button_pushed(struct wps_registrar *reg)
543 {
544         if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
545                 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
546                            "mode");
547                 return -1;
548         }
549         wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
550         reg->selected_registrar = 1;
551         reg->pbc = 1;
552         wps_set_ie(reg);
553
554         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
555         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
556                                reg, NULL);
557         return 0;
558 }
559
560
561 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
562 {
563         wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
564         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
565         wps_registrar_stop_pbc(reg);
566 }
567
568
569 /**
570  * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
571  * @reg: Registrar data from wps_registrar_init()
572  * @addr: MAC address of the Probe Request sender
573  * @wps_data: WPS IE contents
574  *
575  * This function is called on an AP when a Probe Request with WPS IE is
576  * received. This is used to track PBC mode use and to detect possible overlap
577  * situation with other WPS APs.
578  */
579 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
580                                 const struct wpabuf *wps_data)
581 {
582         struct wps_parse_attr attr;
583         u16 methods;
584
585         wpa_hexdump_buf(MSG_MSGDUMP,
586                         "WPS: Probe Request with WPS data received",
587                         wps_data);
588
589         if (wps_parse_msg(wps_data, &attr) < 0 ||
590             attr.version == NULL || *attr.version != WPS_VERSION) {
591                 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
592                            "version 0x%x", attr.version ? *attr.version : 0);
593                 return;
594         }
595
596         if (attr.config_methods == NULL) {
597                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
598                            "Probe Request");
599                 return;
600         }
601
602         methods = WPA_GET_BE16(attr.config_methods);
603         if (!(methods & WPS_CONFIG_PUSHBUTTON))
604                 return; /* Not PBC */
605
606         wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
607                    MACSTR, MAC2STR(addr));
608
609         wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
610 }
611
612
613 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
614                           const u8 *psk, size_t psk_len)
615 {
616         if (reg->new_psk_cb == NULL)
617                 return 0;
618
619         return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
620 }
621
622
623 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
624                               const struct wps_device_data *dev)
625 {
626         if (reg->pin_needed_cb == NULL)
627                 return;
628
629         reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
630 }
631
632
633 static int wps_cb_set_ie(struct wps_registrar *reg,
634                          const struct wpabuf *beacon_ie,
635                          const struct wpabuf *probe_resp_ie)
636 {
637         if (reg->set_ie_cb == NULL)
638                 return 0;
639
640         return reg->set_ie_cb(reg->cb_ctx, wpabuf_head(beacon_ie),
641                               wpabuf_len(beacon_ie),
642                               wpabuf_head(probe_resp_ie),
643                               wpabuf_len(probe_resp_ie));
644 }
645
646
647 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
648 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
649 {
650         struct wpabuf *ie;
651         const u8 *pos, *end;
652
653         ie = wpabuf_alloc(wpabuf_len(data) + 100);
654         if (ie == NULL) {
655                 wpabuf_free(data);
656                 return NULL;
657         }
658
659         pos = wpabuf_head(data);
660         end = pos + wpabuf_len(data);
661
662         while (end > pos) {
663                 size_t frag_len = end - pos;
664                 if (frag_len > 251)
665                         frag_len = 251;
666                 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
667                 wpabuf_put_u8(ie, 4 + frag_len);
668                 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
669                 wpabuf_put_data(ie, pos, frag_len);
670                 pos += frag_len;
671         }
672
673         wpabuf_free(data);
674
675         return ie;
676 }
677
678
679 static int wps_set_ie(struct wps_registrar *reg)
680 {
681         struct wpabuf *beacon;
682         struct wpabuf *probe;
683         int ret;
684
685         wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
686
687         beacon = wpabuf_alloc(300);
688         if (beacon == NULL)
689                 return -1;
690         probe = wpabuf_alloc(400);
691         if (probe == NULL) {
692                 wpabuf_free(beacon);
693                 return -1;
694         }
695
696         if (wps_build_version(beacon) ||
697             wps_build_wps_state(reg->wps, beacon) ||
698             wps_build_ap_setup_locked(reg->wps, beacon) ||
699             wps_build_selected_registrar(reg, beacon) ||
700             wps_build_sel_reg_dev_password_id(reg, beacon) ||
701             wps_build_sel_reg_config_methods(reg, beacon) ||
702             wps_build_version(probe) ||
703             wps_build_wps_state(reg->wps, probe) ||
704             wps_build_ap_setup_locked(reg->wps, probe) ||
705             wps_build_selected_registrar(reg, probe) ||
706             wps_build_sel_reg_dev_password_id(reg, probe) ||
707             wps_build_sel_reg_config_methods(reg, probe) ||
708             wps_build_resp_type(reg, probe) ||
709             wps_build_uuid_e(probe, reg->wps->uuid) ||
710             wps_build_device_attrs(&reg->wps->dev, probe) ||
711             wps_build_probe_config_methods(reg, probe) ||
712             wps_build_rf_bands(&reg->wps->dev, probe)) {
713                 wpabuf_free(beacon);
714                 wpabuf_free(probe);
715                 return -1;
716         }
717
718         beacon = wps_ie_encapsulate(beacon);
719         probe = wps_ie_encapsulate(probe);
720
721         if (!beacon || !probe) {
722                 wpabuf_free(beacon);
723                 wpabuf_free(probe);
724                 return -1;
725         }
726
727         ret = wps_cb_set_ie(reg, beacon, probe);
728         wpabuf_free(beacon);
729         wpabuf_free(probe);
730
731         return ret;
732 }
733
734
735 static int wps_get_dev_password(struct wps_data *wps)
736 {
737         const u8 *pin;
738         size_t pin_len = 0;
739
740         os_free(wps->dev_password);
741         wps->dev_password = NULL;
742
743         if (wps->pbc) {
744                 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
745                 pin = (const u8 *) "00000000";
746                 pin_len = 8;
747         } else {
748                 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
749                                             &pin_len);
750         }
751         if (pin == NULL) {
752                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
753                            "the Enrollee");
754                 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
755                                   &wps->peer_dev);
756                 return -1;
757         }
758
759         wps->dev_password = os_malloc(pin_len);
760         if (wps->dev_password == NULL)
761                 return -1;
762         os_memcpy(wps->dev_password, pin, pin_len);
763         wps->dev_password_len = pin_len;
764
765         return 0;
766 }
767
768
769 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
770 {
771         wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
772         wpabuf_put_be16(msg, ATTR_UUID_R);
773         wpabuf_put_be16(msg, WPS_UUID_LEN);
774         wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
775         return 0;
776 }
777
778
779 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
780 {
781         u8 *hash;
782         const u8 *addr[4];
783         size_t len[4];
784
785         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
786                 return -1;
787         wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
788         wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
789                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
790
791         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
792                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
793                            "R-Hash derivation");
794                 return -1;
795         }
796
797         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
798         wpabuf_put_be16(msg, ATTR_R_HASH1);
799         wpabuf_put_be16(msg, SHA256_MAC_LEN);
800         hash = wpabuf_put(msg, SHA256_MAC_LEN);
801         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
802         addr[0] = wps->snonce;
803         len[0] = WPS_SECRET_NONCE_LEN;
804         addr[1] = wps->psk1;
805         len[1] = WPS_PSK_LEN;
806         addr[2] = wpabuf_head(wps->dh_pubkey_e);
807         len[2] = wpabuf_len(wps->dh_pubkey_e);
808         addr[3] = wpabuf_head(wps->dh_pubkey_r);
809         len[3] = wpabuf_len(wps->dh_pubkey_r);
810         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
811         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
812
813         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
814         wpabuf_put_be16(msg, ATTR_R_HASH2);
815         wpabuf_put_be16(msg, SHA256_MAC_LEN);
816         hash = wpabuf_put(msg, SHA256_MAC_LEN);
817         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
818         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
819         addr[1] = wps->psk2;
820         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
821         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
822
823         return 0;
824 }
825
826
827 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
828 {
829         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
830         wpabuf_put_be16(msg, ATTR_R_SNONCE1);
831         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
832         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
833         return 0;
834 }
835
836
837 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
838 {
839         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
840         wpabuf_put_be16(msg, ATTR_R_SNONCE2);
841         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
842         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
843                         WPS_SECRET_NONCE_LEN);
844         return 0;
845 }
846
847
848 static int wps_build_cred_network_idx(struct wpabuf *msg,
849                                       struct wps_credential *cred)
850 {
851         wpa_printf(MSG_DEBUG, "WPS:  * Network Index");
852         wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
853         wpabuf_put_be16(msg, 1);
854         wpabuf_put_u8(msg, 1);
855         return 0;
856 }
857
858
859 static int wps_build_cred_ssid(struct wpabuf *msg,
860                                struct wps_credential *cred)
861 {
862         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
863         wpabuf_put_be16(msg, ATTR_SSID);
864         wpabuf_put_be16(msg, cred->ssid_len);
865         wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
866         return 0;
867 }
868
869
870 static int wps_build_cred_auth_type(struct wpabuf *msg,
871                                     struct wps_credential *cred)
872 {
873         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
874                    cred->auth_type);
875         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
876         wpabuf_put_be16(msg, 2);
877         wpabuf_put_be16(msg, cred->auth_type);
878         return 0;
879 }
880
881
882 static int wps_build_cred_encr_type(struct wpabuf *msg,
883                                     struct wps_credential *cred)
884 {
885         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
886                    cred->encr_type);
887         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
888         wpabuf_put_be16(msg, 2);
889         wpabuf_put_be16(msg, cred->encr_type);
890         return 0;
891 }
892
893
894 static int wps_build_cred_network_key(struct wpabuf *msg,
895                                       struct wps_credential *cred)
896 {
897         wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
898         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
899         wpabuf_put_be16(msg, cred->key_len);
900         wpabuf_put_data(msg, cred->key, cred->key_len);
901         return 0;
902 }
903
904
905 static int wps_build_cred_mac_addr(struct wpabuf *msg,
906                                    struct wps_credential *cred)
907 {
908         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
909         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
910         wpabuf_put_be16(msg, ETH_ALEN);
911         wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
912         return 0;
913 }
914
915
916 static int wps_build_credential(struct wpabuf *msg,
917                                 struct wps_credential *cred)
918 {
919         if (wps_build_cred_network_idx(msg, cred) ||
920             wps_build_cred_ssid(msg, cred) ||
921             wps_build_cred_auth_type(msg, cred) ||
922             wps_build_cred_encr_type(msg, cred) ||
923             wps_build_cred_network_key(msg, cred) ||
924             wps_build_cred_mac_addr(msg, cred))
925                 return -1;
926         return 0;
927 }
928
929
930 static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
931 {
932         struct wpabuf *cred;
933
934         if (wps->wps->registrar->skip_cred_build)
935                 goto skip_cred_build;
936
937         wpa_printf(MSG_DEBUG, "WPS:  * Credential");
938         os_memset(&wps->cred, 0, sizeof(wps->cred));
939
940         os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
941         wps->cred.ssid_len = wps->wps->ssid_len;
942
943         /* Select the best authentication and encryption type */
944         if (wps->auth_type & WPS_AUTH_WPA2PSK)
945                 wps->auth_type = WPS_AUTH_WPA2PSK;
946         else if (wps->auth_type & WPS_AUTH_WPAPSK)
947                 wps->auth_type = WPS_AUTH_WPAPSK;
948         else if (wps->auth_type & WPS_AUTH_OPEN)
949                 wps->auth_type = WPS_AUTH_OPEN;
950         else if (wps->auth_type & WPS_AUTH_SHARED)
951                 wps->auth_type = WPS_AUTH_SHARED;
952         else {
953                 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
954                            wps->auth_type);
955                 return -1;
956         }
957         wps->cred.auth_type = wps->auth_type;
958
959         if (wps->auth_type == WPS_AUTH_WPA2PSK ||
960             wps->auth_type == WPS_AUTH_WPAPSK) {
961                 if (wps->encr_type & WPS_ENCR_AES)
962                         wps->encr_type = WPS_ENCR_AES;
963                 else if (wps->encr_type & WPS_ENCR_TKIP)
964                         wps->encr_type = WPS_ENCR_TKIP;
965                 else {
966                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
967                                    "type for WPA/WPA2");
968                         return -1;
969                 }
970         } else {
971                 if (wps->encr_type & WPS_ENCR_WEP)
972                         wps->encr_type = WPS_ENCR_WEP;
973                 else if (wps->encr_type & WPS_ENCR_NONE)
974                         wps->encr_type = WPS_ENCR_NONE;
975                 else {
976                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
977                                    "type for non-WPA/WPA2 mode");
978                         return -1;
979                 }
980         }
981         wps->cred.encr_type = wps->encr_type;
982         os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
983
984         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap) {
985                 u8 r[16];
986                 /* Generate a random passphrase */
987                 if (os_get_random(r, sizeof(r)) < 0)
988                         return -1;
989                 os_free(wps->new_psk);
990                 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
991                 if (wps->new_psk == NULL)
992                         return -1;
993                 wps->new_psk_len--; /* remove newline */
994                 while (wps->new_psk_len &&
995                        wps->new_psk[wps->new_psk_len - 1] == '=')
996                         wps->new_psk_len--;
997                 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
998                                       wps->new_psk, wps->new_psk_len);
999                 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1000                 wps->cred.key_len = wps->new_psk_len;
1001         } else if (wps->wps->network_key) {
1002                 os_memcpy(wps->cred.key, wps->wps->network_key,
1003                           wps->wps->network_key_len);
1004                 wps->cred.key_len = wps->wps->network_key_len;
1005         } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1006                 char hex[65];
1007                 /* Generate a random per-device PSK */
1008                 os_free(wps->new_psk);
1009                 wps->new_psk_len = 32;
1010                 wps->new_psk = os_malloc(wps->new_psk_len);
1011                 if (wps->new_psk == NULL)
1012                         return -1;
1013                 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
1014                         os_free(wps->new_psk);
1015                         wps->new_psk = NULL;
1016                         return -1;
1017                 }
1018                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1019                                 wps->new_psk, wps->new_psk_len);
1020                 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1021                                  wps->new_psk_len);
1022                 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1023                 wps->cred.key_len = wps->new_psk_len * 2;
1024         }
1025
1026         cred = wpabuf_alloc(200);
1027         if (cred == NULL)
1028                 return -1;
1029
1030         if (wps_build_credential(cred, &wps->cred)) {
1031                 wpabuf_free(cred);
1032                 return -1;
1033         }
1034
1035         wpabuf_put_be16(msg, ATTR_CRED);
1036         wpabuf_put_be16(msg, wpabuf_len(cred));
1037         wpabuf_put_buf(msg, cred);
1038         wpabuf_free(cred);
1039
1040 skip_cred_build:
1041         if (wps->wps->registrar->extra_cred) {
1042                 wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
1043                 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1044         }
1045
1046         return 0;
1047 }
1048
1049
1050 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1051 {
1052         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
1053
1054         if (wps_build_credential(msg, &wps->cred))
1055                 return -1;
1056
1057         return 0;
1058 }
1059
1060
1061 static struct wpabuf * wps_build_m2(struct wps_data *wps)
1062 {
1063         struct wpabuf *msg;
1064
1065         if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
1066                 return NULL;
1067         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1068                     wps->nonce_r, WPS_NONCE_LEN);
1069         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1070
1071         wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1072         msg = wpabuf_alloc(1000);
1073         if (msg == NULL)
1074                 return NULL;
1075
1076         if (wps_build_version(msg) ||
1077             wps_build_msg_type(msg, WPS_M2) ||
1078             wps_build_enrollee_nonce(wps, msg) ||
1079             wps_build_registrar_nonce(wps, msg) ||
1080             wps_build_uuid_r(wps, msg) ||
1081             wps_build_public_key(wps, msg) ||
1082             wps_derive_keys(wps) ||
1083             wps_build_auth_type_flags(wps, msg) ||
1084             wps_build_encr_type_flags(wps, msg) ||
1085             wps_build_conn_type_flags(wps, msg) ||
1086             wps_build_config_methods_r(wps->wps->registrar, msg) ||
1087             wps_build_device_attrs(&wps->wps->dev, msg) ||
1088             wps_build_rf_bands(&wps->wps->dev, msg) ||
1089             wps_build_assoc_state(wps, msg) ||
1090             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1091             wps_build_dev_password_id(msg, DEV_PW_DEFAULT) ||
1092             wps_build_os_version(&wps->wps->dev, msg) ||
1093             wps_build_authenticator(wps, msg)) {
1094                 wpabuf_free(msg);
1095                 return NULL;
1096         }
1097
1098         wps->state = RECV_M3;
1099         return msg;
1100 }
1101
1102
1103 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1104 {
1105         struct wpabuf *msg;
1106         u16 err = WPS_CFG_NO_ERROR;
1107
1108         wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1109         msg = wpabuf_alloc(1000);
1110         if (msg == NULL)
1111                 return NULL;
1112
1113         if (wps->wps->ap && wps->wps->ap_setup_locked)
1114                 err = WPS_CFG_SETUP_LOCKED;
1115
1116         if (wps_build_version(msg) ||
1117             wps_build_msg_type(msg, WPS_M2D) ||
1118             wps_build_enrollee_nonce(wps, msg) ||
1119             wps_build_registrar_nonce(wps, msg) ||
1120             wps_build_uuid_r(wps, msg) ||
1121             wps_build_auth_type_flags(wps, msg) ||
1122             wps_build_encr_type_flags(wps, msg) ||
1123             wps_build_conn_type_flags(wps, msg) ||
1124             wps_build_config_methods_r(wps->wps->registrar, msg) ||
1125             wps_build_device_attrs(&wps->wps->dev, msg) ||
1126             wps_build_rf_bands(&wps->wps->dev, msg) ||
1127             wps_build_assoc_state(wps, msg) ||
1128             wps_build_config_error(msg, err) ||
1129             wps_build_os_version(&wps->wps->dev, msg)) {
1130                 wpabuf_free(msg);
1131                 return NULL;
1132         }
1133
1134         wps->state = RECV_M2D_ACK;
1135         return msg;
1136 }
1137
1138
1139 static struct wpabuf * wps_build_m4(struct wps_data *wps)
1140 {
1141         struct wpabuf *msg, *plain;
1142
1143         wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1144
1145         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1146
1147         plain = wpabuf_alloc(200);
1148         if (plain == NULL)
1149                 return NULL;
1150
1151         msg = wpabuf_alloc(1000);
1152         if (msg == NULL) {
1153                 wpabuf_free(plain);
1154                 return NULL;
1155         }
1156
1157         if (wps_build_version(msg) ||
1158             wps_build_msg_type(msg, WPS_M4) ||
1159             wps_build_enrollee_nonce(wps, msg) ||
1160             wps_build_r_hash(wps, msg) ||
1161             wps_build_r_snonce1(wps, plain) ||
1162             wps_build_key_wrap_auth(wps, plain) ||
1163             wps_build_encr_settings(wps, msg, plain) ||
1164             wps_build_authenticator(wps, msg)) {
1165                 wpabuf_free(plain);
1166                 wpabuf_free(msg);
1167                 return NULL;
1168         }
1169         wpabuf_free(plain);
1170
1171         wps->state = RECV_M5;
1172         return msg;
1173 }
1174
1175
1176 static struct wpabuf * wps_build_m6(struct wps_data *wps)
1177 {
1178         struct wpabuf *msg, *plain;
1179
1180         wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1181
1182         plain = wpabuf_alloc(200);
1183         if (plain == NULL)
1184                 return NULL;
1185
1186         msg = wpabuf_alloc(1000);
1187         if (msg == NULL) {
1188                 wpabuf_free(plain);
1189                 return NULL;
1190         }
1191
1192         if (wps_build_version(msg) ||
1193             wps_build_msg_type(msg, WPS_M6) ||
1194             wps_build_enrollee_nonce(wps, msg) ||
1195             wps_build_r_snonce2(wps, plain) ||
1196             wps_build_key_wrap_auth(wps, plain) ||
1197             wps_build_encr_settings(wps, msg, plain) ||
1198             wps_build_authenticator(wps, msg)) {
1199                 wpabuf_free(plain);
1200                 wpabuf_free(msg);
1201                 return NULL;
1202         }
1203         wpabuf_free(plain);
1204
1205         wps->wps_pin_revealed = 1;
1206         wps->state = RECV_M7;
1207         return msg;
1208 }
1209
1210
1211 static struct wpabuf * wps_build_m8(struct wps_data *wps)
1212 {
1213         struct wpabuf *msg, *plain;
1214
1215         wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1216
1217         plain = wpabuf_alloc(500);
1218         if (plain == NULL)
1219                 return NULL;
1220
1221         msg = wpabuf_alloc(1000);
1222         if (msg == NULL) {
1223                 wpabuf_free(plain);
1224                 return NULL;
1225         }
1226
1227         if (wps_build_version(msg) ||
1228             wps_build_msg_type(msg, WPS_M8) ||
1229             wps_build_enrollee_nonce(wps, msg) ||
1230             (wps->wps->ap && wps_build_cred(wps, plain)) ||
1231             (!wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
1232             wps_build_key_wrap_auth(wps, plain) ||
1233             wps_build_encr_settings(wps, msg, plain) ||
1234             wps_build_authenticator(wps, msg)) {
1235                 wpabuf_free(plain);
1236                 wpabuf_free(msg);
1237                 return NULL;
1238         }
1239         wpabuf_free(plain);
1240
1241         wps->state = RECV_DONE;
1242         return msg;
1243 }
1244
1245
1246 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
1247 {
1248         struct wpabuf *msg;
1249
1250         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
1251
1252         msg = wpabuf_alloc(1000);
1253         if (msg == NULL)
1254                 return NULL;
1255
1256         if (wps_build_version(msg) ||
1257             wps_build_msg_type(msg, WPS_WSC_ACK) ||
1258             wps_build_enrollee_nonce(wps, msg) ||
1259             wps_build_registrar_nonce(wps, msg)) {
1260                 wpabuf_free(msg);
1261                 return NULL;
1262         }
1263
1264         return msg;
1265 }
1266
1267
1268 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
1269 {
1270         struct wpabuf *msg;
1271
1272         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
1273
1274         msg = wpabuf_alloc(1000);
1275         if (msg == NULL)
1276                 return NULL;
1277
1278         if (wps_build_version(msg) ||
1279             wps_build_msg_type(msg, WPS_WSC_NACK) ||
1280             wps_build_enrollee_nonce(wps, msg) ||
1281             wps_build_registrar_nonce(wps, msg) ||
1282             wps_build_config_error(msg, wps->config_error)) {
1283                 wpabuf_free(msg);
1284                 return NULL;
1285         }
1286
1287         return msg;
1288 }
1289
1290
1291 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1292                                       enum wsc_op_code *op_code)
1293 {
1294         struct wpabuf *msg;
1295
1296         switch (wps->state) {
1297         case SEND_M2:
1298                 if (wps_get_dev_password(wps) < 0)
1299                         msg = wps_build_m2d(wps);
1300                 else
1301                         msg = wps_build_m2(wps);
1302                 *op_code = WSC_MSG;
1303                 break;
1304         case SEND_M2D:
1305                 msg = wps_build_m2d(wps);
1306                 *op_code = WSC_MSG;
1307                 break;
1308         case SEND_M4:
1309                 msg = wps_build_m4(wps);
1310                 *op_code = WSC_MSG;
1311                 break;
1312         case SEND_M6:
1313                 msg = wps_build_m6(wps);
1314                 *op_code = WSC_MSG;
1315                 break;
1316         case SEND_M8:
1317                 msg = wps_build_m8(wps);
1318                 *op_code = WSC_MSG;
1319                 break;
1320         case RECV_DONE:
1321                 msg = wps_build_wsc_ack(wps);
1322                 *op_code = WSC_ACK;
1323                 break;
1324         case SEND_WSC_NACK:
1325                 msg = wps_build_wsc_nack(wps);
1326                 *op_code = WSC_NACK;
1327                 break;
1328         default:
1329                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
1330                            "a message", wps->state);
1331                 msg = NULL;
1332                 break;
1333         }
1334
1335         if (*op_code == WSC_MSG && msg) {
1336                 /* Save a copy of the last message for Authenticator derivation
1337                  */
1338                 wpabuf_free(wps->last_msg);
1339                 wps->last_msg = wpabuf_dup(msg);
1340         }
1341
1342         return msg;
1343 }
1344
1345
1346 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
1347 {
1348         if (e_nonce == NULL) {
1349                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
1350                 return -1;
1351         }
1352
1353         os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
1354         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
1355                     wps->nonce_e, WPS_NONCE_LEN);
1356
1357         return 0;
1358 }
1359
1360
1361 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
1362 {
1363         if (r_nonce == NULL) {
1364                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
1365                 return -1;
1366         }
1367
1368         if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
1369                 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
1370                 return -1;
1371         }
1372
1373         return 0;
1374 }
1375
1376
1377 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
1378 {
1379         if (uuid_e == NULL) {
1380                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
1381                 return -1;
1382         }
1383
1384         os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
1385         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
1386
1387         return 0;
1388 }
1389
1390
1391 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
1392 {
1393         if (pw_id == NULL) {
1394                 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
1395                 return -1;
1396         }
1397
1398         wps->dev_pw_id = WPA_GET_BE16(pw_id);
1399         wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
1400
1401         return 0;
1402 }
1403
1404
1405 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
1406 {
1407         if (e_hash1 == NULL) {
1408                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
1409                 return -1;
1410         }
1411
1412         os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
1413         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
1414
1415         return 0;
1416 }
1417
1418
1419 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
1420 {
1421         if (e_hash2 == NULL) {
1422                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
1423                 return -1;
1424         }
1425
1426         os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
1427         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
1428
1429         return 0;
1430 }
1431
1432
1433 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
1434 {
1435         u8 hash[SHA256_MAC_LEN];
1436         const u8 *addr[4];
1437         size_t len[4];
1438
1439         if (e_snonce1 == NULL) {
1440                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
1441                 return -1;
1442         }
1443
1444         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
1445                         WPS_SECRET_NONCE_LEN);
1446
1447         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1448         addr[0] = e_snonce1;
1449         len[0] = WPS_SECRET_NONCE_LEN;
1450         addr[1] = wps->psk1;
1451         len[1] = WPS_PSK_LEN;
1452         addr[2] = wpabuf_head(wps->dh_pubkey_e);
1453         len[2] = wpabuf_len(wps->dh_pubkey_e);
1454         addr[3] = wpabuf_head(wps->dh_pubkey_r);
1455         len[3] = wpabuf_len(wps->dh_pubkey_r);
1456         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1457
1458         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
1459                 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
1460                            "not match with the pre-committed value");
1461                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1462                 return -1;
1463         }
1464
1465         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
1466                    "half of the device password");
1467
1468         return 0;
1469 }
1470
1471
1472 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
1473 {
1474         u8 hash[SHA256_MAC_LEN];
1475         const u8 *addr[4];
1476         size_t len[4];
1477
1478         if (e_snonce2 == NULL) {
1479                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
1480                 return -1;
1481         }
1482
1483         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
1484                         WPS_SECRET_NONCE_LEN);
1485
1486         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1487         addr[0] = e_snonce2;
1488         len[0] = WPS_SECRET_NONCE_LEN;
1489         addr[1] = wps->psk2;
1490         len[1] = WPS_PSK_LEN;
1491         addr[2] = wpabuf_head(wps->dh_pubkey_e);
1492         len[2] = wpabuf_len(wps->dh_pubkey_e);
1493         addr[3] = wpabuf_head(wps->dh_pubkey_r);
1494         len[3] = wpabuf_len(wps->dh_pubkey_r);
1495         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1496
1497         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
1498                 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
1499                            "not match with the pre-committed value");
1500                 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
1501                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1502                 return -1;
1503         }
1504
1505         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
1506                    "half of the device password");
1507         wps->wps_pin_revealed = 0;
1508         wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
1509
1510         return 0;
1511 }
1512
1513
1514 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
1515 {
1516         if (mac_addr == NULL) {
1517                 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
1518                 return -1;
1519         }
1520
1521         wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
1522                    MAC2STR(mac_addr));
1523         os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
1524         os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
1525
1526         return 0;
1527 }
1528
1529
1530 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
1531                               size_t pk_len)
1532 {
1533         if (pk == NULL || pk_len == 0) {
1534                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
1535                 return -1;
1536         }
1537
1538         wpabuf_free(wps->dh_pubkey_e);
1539         wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
1540         if (wps->dh_pubkey_e == NULL)
1541                 return -1;
1542
1543         return 0;
1544 }
1545
1546
1547 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
1548 {
1549         u16 auth_types;
1550
1551         if (auth == NULL) {
1552                 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
1553                            "received");
1554                 return -1;
1555         }
1556
1557         auth_types = WPA_GET_BE16(auth);
1558
1559         wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
1560                    auth_types);
1561         wps->auth_type = wps->wps->auth_types & auth_types;
1562         if (wps->auth_type == 0) {
1563                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1564                            "authentication types (own 0x%x Enrollee 0x%x)",
1565                            wps->wps->auth_types, auth_types);
1566                 return -1;
1567         }
1568
1569         return 0;
1570 }
1571
1572
1573 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
1574 {
1575         u16 encr_types;
1576
1577         if (encr == NULL) {
1578                 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
1579                            "received");
1580                 return -1;
1581         }
1582
1583         encr_types = WPA_GET_BE16(encr);
1584
1585         wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
1586                    encr_types);
1587         wps->encr_type = wps->wps->encr_types & encr_types;
1588         if (wps->encr_type == 0) {
1589                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1590                            "encryption types");
1591                 return -1;
1592         }
1593
1594         return 0;
1595 }
1596
1597
1598 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
1599 {
1600         if (conn == NULL) {
1601                 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
1602                            "received");
1603                 return -1;
1604         }
1605
1606         wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
1607                    *conn);
1608
1609         return 0;
1610 }
1611
1612
1613 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
1614 {
1615         u16 m;
1616
1617         if (methods == NULL) {
1618                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
1619                 return -1;
1620         }
1621
1622         m = WPA_GET_BE16(methods);
1623
1624         wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x", m);
1625
1626         return 0;
1627 }
1628
1629
1630 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
1631 {
1632         if (state == NULL) {
1633                 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
1634                            "received");
1635                 return -1;
1636         }
1637
1638         wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
1639                    *state);
1640
1641         return 0;
1642 }
1643
1644
1645 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
1646 {
1647         u16 a;
1648
1649         if (assoc == NULL) {
1650                 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
1651                 return -1;
1652         }
1653
1654         a = WPA_GET_BE16(assoc);
1655         wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
1656
1657         return 0;
1658 }
1659
1660
1661 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
1662 {
1663         u16 e;
1664
1665         if (err == NULL) {
1666                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
1667                 return -1;
1668         }
1669
1670         e = WPA_GET_BE16(err);
1671         wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
1672
1673         return 0;
1674 }
1675
1676
1677 static enum wps_process_res wps_process_m1(struct wps_data *wps,
1678                                            struct wps_parse_attr *attr)
1679 {
1680         wpa_printf(MSG_DEBUG, "WPS: Received M1");
1681
1682         if (wps->state != RECV_M1) {
1683                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1684                            "receiving M1", wps->state);
1685                 return WPS_FAILURE;
1686         }
1687
1688         if (wps_process_uuid_e(wps, attr->uuid_e) ||
1689             wps_process_mac_addr(wps, attr->mac_addr) ||
1690             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1691             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
1692             wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
1693             wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
1694             wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
1695             wps_process_config_methods(wps, attr->config_methods) ||
1696             wps_process_wps_state(wps, attr->wps_state) ||
1697             wps_process_device_attrs(&wps->peer_dev, attr) ||
1698             wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
1699             wps_process_assoc_state(wps, attr->assoc_state) ||
1700             wps_process_dev_password_id(wps, attr->dev_password_id) ||
1701             wps_process_config_error(wps, attr->config_error) ||
1702             wps_process_os_version(&wps->peer_dev, attr->os_version))
1703                 return WPS_FAILURE;
1704
1705         if (wps->dev_pw_id != DEV_PW_DEFAULT &&
1706             wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
1707             wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
1708             wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
1709             (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
1710              !wps->wps->registrar->pbc)) {
1711                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
1712                            wps->dev_pw_id);
1713                 wps->state = SEND_M2D;
1714                 return WPS_CONTINUE;
1715         }
1716
1717         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
1718                 if (wps_registrar_pbc_overlap(wps->wps->registrar,
1719                                               wps->mac_addr_e, wps->uuid_e)) {
1720                         wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
1721                                    "negotiation");
1722                         wps->state = SEND_M2D;
1723                         return WPS_CONTINUE;
1724                 }
1725                 wps_registrar_add_pbc_session(wps->wps->registrar,
1726                                               wps->mac_addr_e, wps->uuid_e);
1727                 wps->pbc = 1;
1728         }
1729
1730         wps->state = SEND_M2;
1731         return WPS_CONTINUE;
1732 }
1733
1734
1735 static enum wps_process_res wps_process_m3(struct wps_data *wps,
1736                                            const struct wpabuf *msg,
1737                                            struct wps_parse_attr *attr)
1738 {
1739         wpa_printf(MSG_DEBUG, "WPS: Received M3");
1740
1741         if (wps->state != RECV_M3) {
1742                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1743                            "receiving M3", wps->state);
1744                 wps->state = SEND_WSC_NACK;
1745                 return WPS_CONTINUE;
1746         }
1747
1748         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
1749             wps_process_authenticator(wps, attr->authenticator, msg) ||
1750             wps_process_e_hash1(wps, attr->e_hash1) ||
1751             wps_process_e_hash2(wps, attr->e_hash2)) {
1752                 wps->state = SEND_WSC_NACK;
1753                 return WPS_CONTINUE;
1754         }
1755
1756         wps->state = SEND_M4;
1757         return WPS_CONTINUE;
1758 }
1759
1760
1761 static enum wps_process_res wps_process_m5(struct wps_data *wps,
1762                                            const struct wpabuf *msg,
1763                                            struct wps_parse_attr *attr)
1764 {
1765         struct wpabuf *decrypted;
1766         struct wps_parse_attr eattr;
1767
1768         wpa_printf(MSG_DEBUG, "WPS: Received M5");
1769
1770         if (wps->state != RECV_M5) {
1771                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1772                            "receiving M5", wps->state);
1773                 wps->state = SEND_WSC_NACK;
1774                 return WPS_CONTINUE;
1775         }
1776
1777         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
1778             wps_process_authenticator(wps, attr->authenticator, msg)) {
1779                 wps->state = SEND_WSC_NACK;
1780                 return WPS_CONTINUE;
1781         }
1782
1783         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1784                                               attr->encr_settings_len);
1785         if (decrypted == NULL) {
1786                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1787                            "Settings attribute");
1788                 wps->state = SEND_WSC_NACK;
1789                 return WPS_CONTINUE;
1790         }
1791
1792         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1793                    "attribute");
1794         if (wps_parse_msg(decrypted, &eattr) < 0 ||
1795             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1796             wps_process_e_snonce1(wps, eattr.e_snonce1)) {
1797                 wpabuf_free(decrypted);
1798                 wps->state = SEND_WSC_NACK;
1799                 return WPS_CONTINUE;
1800         }
1801         wpabuf_free(decrypted);
1802
1803         wps->state = SEND_M6;
1804         return WPS_CONTINUE;
1805 }
1806
1807
1808 static int wps_process_ap_settings_r(struct wps_data *wps,
1809                                      struct wps_parse_attr *attr)
1810 {
1811         if (wps->wps->ap)
1812                 return 0;
1813
1814         /* AP Settings Attributes in M7 when Enrollee is an AP */
1815         if (wps_process_ap_settings(attr, &wps->cred) < 0)
1816                 return -1;
1817
1818         wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
1819
1820         /*
1821          * TODO: Provide access to AP settings and allow changes before sending
1822          * out M8. For now, just copy the settings unchanged into M8.
1823          */
1824
1825         return 0;
1826 }
1827
1828
1829 static enum wps_process_res wps_process_m7(struct wps_data *wps,
1830                                            const struct wpabuf *msg,
1831                                            struct wps_parse_attr *attr)
1832 {
1833         struct wpabuf *decrypted;
1834         struct wps_parse_attr eattr;
1835
1836         wpa_printf(MSG_DEBUG, "WPS: Received M7");
1837
1838         if (wps->state != RECV_M7) {
1839                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1840                            "receiving M7", wps->state);
1841                 wps->state = SEND_WSC_NACK;
1842                 return WPS_CONTINUE;
1843         }
1844
1845         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
1846             wps_process_authenticator(wps, attr->authenticator, msg)) {
1847                 wps->state = SEND_WSC_NACK;
1848                 return WPS_CONTINUE;
1849         }
1850
1851         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1852                                               attr->encr_settings_len);
1853         if (decrypted == NULL) {
1854                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1855                            "Settings attribute");
1856                 wps->state = SEND_WSC_NACK;
1857                 return WPS_CONTINUE;
1858         }
1859
1860         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1861                    "attribute");
1862         if (wps_parse_msg(decrypted, &eattr) < 0 ||
1863             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1864             wps_process_e_snonce2(wps, eattr.e_snonce2) ||
1865             wps_process_ap_settings_r(wps, &eattr)) {
1866                 wpabuf_free(decrypted);
1867                 wps->state = SEND_WSC_NACK;
1868                 return WPS_CONTINUE;
1869         }
1870
1871         wpabuf_free(decrypted);
1872
1873         wps->state = SEND_M8;
1874         return WPS_CONTINUE;
1875 }
1876
1877
1878 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1879                                                 const struct wpabuf *msg)
1880 {
1881         struct wps_parse_attr attr;
1882         enum wps_process_res ret = WPS_CONTINUE;
1883
1884         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1885
1886         if (wps_parse_msg(msg, &attr) < 0)
1887                 return WPS_FAILURE;
1888
1889         if (attr.version == NULL || *attr.version != WPS_VERSION) {
1890                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
1891                            attr.version ? *attr.version : 0);
1892                 return WPS_FAILURE;
1893         }
1894
1895         if (attr.msg_type == NULL) {
1896                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1897                 return WPS_FAILURE;
1898         }
1899
1900         if (*attr.msg_type != WPS_M1 &&
1901             (attr.registrar_nonce == NULL ||
1902              os_memcmp(wps->nonce_r, attr.registrar_nonce,
1903                        WPS_NONCE_LEN != 0))) {
1904                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1905                 return WPS_FAILURE;
1906         }
1907
1908         switch (*attr.msg_type) {
1909         case WPS_M1:
1910                 ret = wps_process_m1(wps, &attr);
1911                 break;
1912         case WPS_M3:
1913                 ret = wps_process_m3(wps, msg, &attr);
1914                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1915                         wps_fail_event(wps->wps, WPS_M3);
1916                 break;
1917         case WPS_M5:
1918                 ret = wps_process_m5(wps, msg, &attr);
1919                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1920                         wps_fail_event(wps->wps, WPS_M5);
1921                 break;
1922         case WPS_M7:
1923                 ret = wps_process_m7(wps, msg, &attr);
1924                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1925                         wps_fail_event(wps->wps, WPS_M7);
1926                 break;
1927         default:
1928                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1929                            *attr.msg_type);
1930                 return WPS_FAILURE;
1931         }
1932
1933         if (ret == WPS_CONTINUE) {
1934                 /* Save a copy of the last message for Authenticator derivation
1935                  */
1936                 wpabuf_free(wps->last_msg);
1937                 wps->last_msg = wpabuf_dup(msg);
1938         }
1939
1940         return ret;
1941 }
1942
1943
1944 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1945                                                 const struct wpabuf *msg)
1946 {
1947         struct wps_parse_attr attr;
1948
1949         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1950
1951         if (wps_parse_msg(msg, &attr) < 0)
1952                 return WPS_FAILURE;
1953
1954         if (attr.version == NULL || *attr.version != WPS_VERSION) {
1955                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
1956                            attr.version ? *attr.version : 0);
1957                 return WPS_FAILURE;
1958         }
1959
1960         if (attr.msg_type == NULL) {
1961                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1962                 return WPS_FAILURE;
1963         }
1964
1965         if (*attr.msg_type != WPS_WSC_ACK) {
1966                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1967                            *attr.msg_type);
1968                 return WPS_FAILURE;
1969         }
1970
1971         if (attr.registrar_nonce == NULL ||
1972             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
1973         {
1974                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1975                 return WPS_FAILURE;
1976         }
1977
1978         if (attr.enrollee_nonce == NULL ||
1979             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
1980                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1981                 return WPS_FAILURE;
1982         }
1983
1984         if (wps->state == RECV_M2D_ACK) {
1985                 /* TODO: support for multiple registrars and sending of
1986                  * multiple M2/M2D messages */
1987
1988                 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
1989                            "terminate negotiation");
1990         }
1991
1992         return WPS_FAILURE;
1993 }
1994
1995
1996 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1997                                                  const struct wpabuf *msg)
1998 {
1999         struct wps_parse_attr attr;
2000         int old_state;
2001
2002         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
2003
2004         old_state = wps->state;
2005         wps->state = SEND_WSC_NACK;
2006
2007         if (wps_parse_msg(msg, &attr) < 0)
2008                 return WPS_FAILURE;
2009
2010         if (attr.version == NULL || *attr.version != WPS_VERSION) {
2011                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2012                            attr.version ? *attr.version : 0);
2013                 return WPS_FAILURE;
2014         }
2015
2016         if (attr.msg_type == NULL) {
2017                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2018                 return WPS_FAILURE;
2019         }
2020
2021         if (*attr.msg_type != WPS_WSC_NACK) {
2022                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2023                            *attr.msg_type);
2024                 return WPS_FAILURE;
2025         }
2026
2027         if (attr.registrar_nonce == NULL ||
2028             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2029         {
2030                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2031                 return WPS_FAILURE;
2032         }
2033
2034         if (attr.enrollee_nonce == NULL ||
2035             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2036                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2037                 return WPS_FAILURE;
2038         }
2039
2040         if (attr.config_error == NULL) {
2041                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
2042                            "in WSC_NACK");
2043                 return WPS_FAILURE;
2044         }
2045
2046         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
2047                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
2048
2049         switch (old_state) {
2050         case RECV_M3:
2051                 wps_fail_event(wps->wps, WPS_M2);
2052                 break;
2053         case RECV_M5:
2054                 wps_fail_event(wps->wps, WPS_M4);
2055                 break;
2056         case RECV_M7:
2057                 wps_fail_event(wps->wps, WPS_M6);
2058                 break;
2059         case RECV_DONE:
2060                 wps_fail_event(wps->wps, WPS_M8);
2061                 break;
2062         default:
2063                 break;
2064         }
2065
2066         return WPS_FAILURE;
2067 }
2068
2069
2070 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
2071                                                  const struct wpabuf *msg)
2072 {
2073         struct wps_parse_attr attr;
2074
2075         wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
2076
2077         if (wps->state != RECV_DONE) {
2078                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2079                            "receiving WSC_Done", wps->state);
2080                 return WPS_FAILURE;
2081         }
2082
2083         if (wps_parse_msg(msg, &attr) < 0)
2084                 return WPS_FAILURE;
2085
2086         if (attr.version == NULL || *attr.version != WPS_VERSION) {
2087                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2088                            attr.version ? *attr.version : 0);
2089                 return WPS_FAILURE;
2090         }
2091
2092         if (attr.msg_type == NULL) {
2093                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2094                 return WPS_FAILURE;
2095         }
2096
2097         if (*attr.msg_type != WPS_WSC_DONE) {
2098                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2099                            *attr.msg_type);
2100                 return WPS_FAILURE;
2101         }
2102
2103         if (attr.registrar_nonce == NULL ||
2104             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2105         {
2106                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2107                 return WPS_FAILURE;
2108         }
2109
2110         if (attr.enrollee_nonce == NULL ||
2111             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2112                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2113                 return WPS_FAILURE;
2114         }
2115
2116         wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
2117
2118         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
2119             wps->wps->ap) {
2120                 struct wps_credential cred;
2121
2122                 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
2123                            "on first Enrollee connection");
2124
2125                 os_memset(&cred, 0, sizeof(cred));
2126                 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
2127                 cred.ssid_len = wps->wps->ssid_len;
2128                 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
2129                 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
2130                 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
2131                 cred.key_len = wps->new_psk_len;
2132
2133                 wps->wps->wps_state = WPS_STATE_CONFIGURED;
2134                 wpa_hexdump_ascii_key(MSG_DEBUG,
2135                                       "WPS: Generated random passphrase",
2136                                       wps->new_psk, wps->new_psk_len);
2137                 if (wps->wps->cred_cb)
2138                         wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
2139
2140                 os_free(wps->new_psk);
2141                 wps->new_psk = NULL;
2142         }
2143
2144         if (!wps->wps->ap) {
2145                 wpa_printf(MSG_DEBUG, "WPS: Update local configuration based "
2146                            "on the modified AP configuration");
2147                 if (wps->wps->cred_cb)
2148                         wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2149         }
2150
2151         if (wps->new_psk) {
2152                 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
2153                                    wps->new_psk, wps->new_psk_len)) {
2154                         wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
2155                                    "new PSK");
2156                 }
2157                 os_free(wps->new_psk);
2158                 wps->new_psk = NULL;
2159         }
2160
2161         if (wps->pbc) {
2162                 wps_registrar_remove_pbc_session(wps->wps->registrar,
2163                                                  wps->mac_addr_e, wps->uuid_e);
2164                 wps_registrar_pbc_completed(wps->wps->registrar);
2165         }
2166
2167         wps_success_event(wps->wps);
2168
2169         return WPS_DONE;
2170 }
2171
2172
2173 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
2174                                                enum wsc_op_code op_code,
2175                                                const struct wpabuf *msg)
2176 {
2177         enum wps_process_res ret;
2178
2179         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
2180                    "op_code=%d)",
2181                    (unsigned long) wpabuf_len(msg), op_code);
2182
2183         switch (op_code) {
2184         case WSC_MSG:
2185                 return wps_process_wsc_msg(wps, msg);
2186         case WSC_ACK:
2187                 return wps_process_wsc_ack(wps, msg);
2188         case WSC_NACK:
2189                 return wps_process_wsc_nack(wps, msg);
2190         case WSC_Done:
2191                 ret = wps_process_wsc_done(wps, msg);
2192                 if (ret == WPS_FAILURE) {
2193                         wps->state = SEND_WSC_NACK;
2194                         wps_fail_event(wps->wps, WPS_WSC_DONE);
2195                 }
2196                 return ret;
2197         default:
2198                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
2199                 return WPS_FAILURE;
2200         }
2201 }