]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/wpa/src/wps/wps_registrar.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / wpa / src / wps / wps_registrar.c
1 /*
2  * Wi-Fi Protected Setup - Registrar
3  * Copyright (c) 2008-2009, 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 "utils/includes.h"
16
17 #include "utils/common.h"
18 #include "utils/base64.h"
19 #include "utils/eloop.h"
20 #include "utils/uuid.h"
21 #include "utils/list.h"
22 #include "crypto/crypto.h"
23 #include "crypto/sha256.h"
24 #include "common/ieee802_11_defs.h"
25 #include "wps_i.h"
26 #include "wps_dev_attr.h"
27 #include "wps_upnp.h"
28 #include "wps_upnp_i.h"
29
30 #define WPS_WORKAROUNDS
31
32 struct wps_uuid_pin {
33         struct dl_list list;
34         u8 uuid[WPS_UUID_LEN];
35         int wildcard_uuid;
36         u8 *pin;
37         size_t pin_len;
38 #define PIN_LOCKED BIT(0)
39 #define PIN_EXPIRES BIT(1)
40         int flags;
41         struct os_time expiration;
42 };
43
44
45 static void wps_free_pin(struct wps_uuid_pin *pin)
46 {
47         os_free(pin->pin);
48         os_free(pin);
49 }
50
51
52 static void wps_remove_pin(struct wps_uuid_pin *pin)
53 {
54         dl_list_del(&pin->list);
55         wps_free_pin(pin);
56 }
57
58
59 static void wps_free_pins(struct dl_list *pins)
60 {
61         struct wps_uuid_pin *pin, *prev;
62         dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
63                 wps_remove_pin(pin);
64 }
65
66
67 struct wps_pbc_session {
68         struct wps_pbc_session *next;
69         u8 addr[ETH_ALEN];
70         u8 uuid_e[WPS_UUID_LEN];
71         struct os_time timestamp;
72 };
73
74
75 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
76 {
77         struct wps_pbc_session *prev;
78
79         while (pbc) {
80                 prev = pbc;
81                 pbc = pbc->next;
82                 os_free(prev);
83         }
84 }
85
86
87 struct wps_registrar_device {
88         struct wps_registrar_device *next;
89         struct wps_device_data dev;
90         u8 uuid[WPS_UUID_LEN];
91 };
92
93
94 struct wps_registrar {
95         struct wps_context *wps;
96
97         int pbc;
98         int selected_registrar;
99
100         int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
101                           size_t psk_len);
102         int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
103                          struct wpabuf *probe_resp_ie);
104         void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
105                               const struct wps_device_data *dev);
106         void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
107                                const u8 *uuid_e);
108         void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
109                                u16 sel_reg_config_methods);
110         void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
111                                  const u8 *pri_dev_type, u16 config_methods,
112                                  u16 dev_password_id, u8 request_type,
113                                  const char *dev_name);
114         void *cb_ctx;
115
116         struct dl_list pins;
117         struct wps_pbc_session *pbc_sessions;
118
119         int skip_cred_build;
120         struct wpabuf *extra_cred;
121         int disable_auto_conf;
122         int sel_reg_union;
123         int sel_reg_dev_password_id_override;
124         int sel_reg_config_methods_override;
125         int static_wep_only;
126
127         struct wps_registrar_device *devices;
128
129         int force_pbc_overlap;
130 };
131
132
133 static int wps_set_ie(struct wps_registrar *reg);
134 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
135 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
136                                                void *timeout_ctx);
137
138
139 static void wps_free_devices(struct wps_registrar_device *dev)
140 {
141         struct wps_registrar_device *prev;
142
143         while (dev) {
144                 prev = dev;
145                 dev = dev->next;
146                 wps_device_data_free(&prev->dev);
147                 os_free(prev);
148         }
149 }
150
151
152 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
153                                                     const u8 *addr)
154 {
155         struct wps_registrar_device *dev;
156
157         for (dev = reg->devices; dev; dev = dev->next) {
158                 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
159                         return dev;
160         }
161         return NULL;
162 }
163
164
165 static void wps_device_clone_data(struct wps_device_data *dst,
166                                   struct wps_device_data *src)
167 {
168         os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
169         os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
170
171 #define WPS_STRDUP(n) \
172         os_free(dst->n); \
173         dst->n = src->n ? os_strdup(src->n) : NULL
174
175         WPS_STRDUP(device_name);
176         WPS_STRDUP(manufacturer);
177         WPS_STRDUP(model_name);
178         WPS_STRDUP(model_number);
179         WPS_STRDUP(serial_number);
180 #undef WPS_STRDUP
181 }
182
183
184 int wps_device_store(struct wps_registrar *reg,
185                      struct wps_device_data *dev, const u8 *uuid)
186 {
187         struct wps_registrar_device *d;
188
189         d = wps_device_get(reg, dev->mac_addr);
190         if (d == NULL) {
191                 d = os_zalloc(sizeof(*d));
192                 if (d == NULL)
193                         return -1;
194                 d->next = reg->devices;
195                 reg->devices = d;
196         }
197
198         wps_device_clone_data(&d->dev, dev);
199         os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
200
201         return 0;
202 }
203
204
205 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
206                                           const u8 *addr, const u8 *uuid_e)
207 {
208         struct wps_pbc_session *pbc, *prev = NULL;
209         struct os_time now;
210
211         os_get_time(&now);
212
213         pbc = reg->pbc_sessions;
214         while (pbc) {
215                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
216                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
217                         if (prev)
218                                 prev->next = pbc->next;
219                         else
220                                 reg->pbc_sessions = pbc->next;
221                         break;
222                 }
223                 prev = pbc;
224                 pbc = pbc->next;
225         }
226
227         if (!pbc) {
228                 pbc = os_zalloc(sizeof(*pbc));
229                 if (pbc == NULL)
230                         return;
231                 os_memcpy(pbc->addr, addr, ETH_ALEN);
232                 if (uuid_e)
233                         os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
234         }
235
236         pbc->next = reg->pbc_sessions;
237         reg->pbc_sessions = pbc;
238         pbc->timestamp = now;
239
240         /* remove entries that have timed out */
241         prev = pbc;
242         pbc = pbc->next;
243
244         while (pbc) {
245                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
246                         prev->next = NULL;
247                         wps_free_pbc_sessions(pbc);
248                         break;
249                 }
250                 prev = pbc;
251                 pbc = pbc->next;
252         }
253 }
254
255
256 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
257                                              const u8 *addr, const u8 *uuid_e)
258 {
259         struct wps_pbc_session *pbc, *prev = NULL;
260
261         pbc = reg->pbc_sessions;
262         while (pbc) {
263                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
264                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
265                         if (prev)
266                                 prev->next = pbc->next;
267                         else
268                                 reg->pbc_sessions = pbc->next;
269                         os_free(pbc);
270                         break;
271                 }
272                 prev = pbc;
273                 pbc = pbc->next;
274         }
275 }
276
277
278 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
279                                      const u8 *addr, const u8 *uuid_e)
280 {
281         int count = 0;
282         struct wps_pbc_session *pbc;
283         struct os_time now;
284
285         os_get_time(&now);
286
287         for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
288                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
289                         break;
290                 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
291                     uuid_e == NULL ||
292                     os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
293                         count++;
294         }
295
296         if (addr || uuid_e)
297                 count++;
298
299         return count > 1 ? 1 : 0;
300 }
301
302
303 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
304 {
305         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
306                    wps->wps_state);
307         wpabuf_put_be16(msg, ATTR_WPS_STATE);
308         wpabuf_put_be16(msg, 1);
309         wpabuf_put_u8(msg, wps->wps_state);
310         return 0;
311 }
312
313
314 #ifdef CONFIG_WPS_UPNP
315 static void wps_registrar_free_pending_m2(struct wps_context *wps)
316 {
317         struct upnp_pending_message *p, *p2, *prev = NULL;
318         p = wps->upnp_msgs;
319         while (p) {
320                 if (p->type == WPS_M2 || p->type == WPS_M2D) {
321                         if (prev == NULL)
322                                 wps->upnp_msgs = p->next;
323                         else
324                                 prev->next = p->next;
325                         wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
326                         p2 = p;
327                         p = p->next;
328                         wpabuf_free(p2->msg);
329                         os_free(p2);
330                         continue;
331                 }
332                 prev = p;
333                 p = p->next;
334         }
335 }
336 #endif /* CONFIG_WPS_UPNP */
337
338
339 static int wps_build_ap_setup_locked(struct wps_context *wps,
340                                      struct wpabuf *msg)
341 {
342         if (wps->ap_setup_locked) {
343                 wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
344                 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
345                 wpabuf_put_be16(msg, 1);
346                 wpabuf_put_u8(msg, 1);
347         }
348         return 0;
349 }
350
351
352 static int wps_build_selected_registrar(struct wps_registrar *reg,
353                                         struct wpabuf *msg)
354 {
355         if (!reg->sel_reg_union)
356                 return 0;
357         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
358         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
359         wpabuf_put_be16(msg, 1);
360         wpabuf_put_u8(msg, 1);
361         return 0;
362 }
363
364
365 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
366                                              struct wpabuf *msg)
367 {
368         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
369         if (!reg->sel_reg_union)
370                 return 0;
371         if (reg->sel_reg_dev_password_id_override >= 0)
372                 id = reg->sel_reg_dev_password_id_override;
373         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
374         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
375         wpabuf_put_be16(msg, 2);
376         wpabuf_put_be16(msg, id);
377         return 0;
378 }
379
380
381 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
382                                             struct wpabuf *msg)
383 {
384         u16 methods;
385         if (!reg->sel_reg_union)
386                 return 0;
387         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
388         if (reg->pbc)
389                 methods |= WPS_CONFIG_PUSHBUTTON;
390         if (reg->sel_reg_config_methods_override >= 0)
391                 methods = reg->sel_reg_config_methods_override;
392         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
393                    methods);
394         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
395         wpabuf_put_be16(msg, 2);
396         wpabuf_put_be16(msg, methods);
397         return 0;
398 }
399
400
401 static int wps_build_probe_config_methods(struct wps_registrar *reg,
402                                           struct wpabuf *msg)
403 {
404         u16 methods;
405         /*
406          * These are the methods that the AP supports as an Enrollee for adding
407          * external Registrars.
408          */
409         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
410         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
411         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
412         wpabuf_put_be16(msg, 2);
413         wpabuf_put_be16(msg, methods);
414         return 0;
415 }
416
417
418 static int wps_build_config_methods_r(struct wps_registrar *reg,
419                                       struct wpabuf *msg)
420 {
421         u16 methods;
422         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
423         if (reg->pbc)
424                 methods |= WPS_CONFIG_PUSHBUTTON;
425         return wps_build_config_methods(msg, methods);
426 }
427
428
429 /**
430  * wps_registrar_init - Initialize WPS Registrar data
431  * @wps: Pointer to longterm WPS context
432  * @cfg: Registrar configuration
433  * Returns: Pointer to allocated Registrar data or %NULL on failure
434  *
435  * This function is used to initialize WPS Registrar functionality. It can be
436  * used for a single Registrar run (e.g., when run in a supplicant) or multiple
437  * runs (e.g., when run as an internal Registrar in an AP). Caller is
438  * responsible for freeing the returned data with wps_registrar_deinit() when
439  * Registrar functionality is not needed anymore.
440  */
441 struct wps_registrar *
442 wps_registrar_init(struct wps_context *wps,
443                    const struct wps_registrar_config *cfg)
444 {
445         struct wps_registrar *reg = os_zalloc(sizeof(*reg));
446         if (reg == NULL)
447                 return NULL;
448
449         dl_list_init(&reg->pins);
450         reg->wps = wps;
451         reg->new_psk_cb = cfg->new_psk_cb;
452         reg->set_ie_cb = cfg->set_ie_cb;
453         reg->pin_needed_cb = cfg->pin_needed_cb;
454         reg->reg_success_cb = cfg->reg_success_cb;
455         reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
456         reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
457         reg->cb_ctx = cfg->cb_ctx;
458         reg->skip_cred_build = cfg->skip_cred_build;
459         if (cfg->extra_cred) {
460                 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
461                                                     cfg->extra_cred_len);
462                 if (reg->extra_cred == NULL) {
463                         os_free(reg);
464                         return NULL;
465                 }
466         }
467         reg->disable_auto_conf = cfg->disable_auto_conf;
468         reg->sel_reg_dev_password_id_override = -1;
469         reg->sel_reg_config_methods_override = -1;
470         reg->static_wep_only = cfg->static_wep_only;
471
472         if (wps_set_ie(reg)) {
473                 wps_registrar_deinit(reg);
474                 return NULL;
475         }
476
477         return reg;
478 }
479
480
481 /**
482  * wps_registrar_deinit - Deinitialize WPS Registrar data
483  * @reg: Registrar data from wps_registrar_init()
484  */
485 void wps_registrar_deinit(struct wps_registrar *reg)
486 {
487         if (reg == NULL)
488                 return;
489         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
490         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
491         wps_free_pins(&reg->pins);
492         wps_free_pbc_sessions(reg->pbc_sessions);
493         wpabuf_free(reg->extra_cred);
494         wps_free_devices(reg->devices);
495         os_free(reg);
496 }
497
498
499 /**
500  * wps_registrar_add_pin - Configure a new PIN for Registrar
501  * @reg: Registrar data from wps_registrar_init()
502  * @uuid: UUID-E or %NULL for wildcard (any UUID)
503  * @pin: PIN (Device Password)
504  * @pin_len: Length of pin in octets
505  * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
506  * Returns: 0 on success, -1 on failure
507  */
508 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
509                           const u8 *pin, size_t pin_len, int timeout)
510 {
511         struct wps_uuid_pin *p;
512
513         p = os_zalloc(sizeof(*p));
514         if (p == NULL)
515                 return -1;
516         if (uuid == NULL)
517                 p->wildcard_uuid = 1;
518         else
519                 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
520         p->pin = os_malloc(pin_len);
521         if (p->pin == NULL) {
522                 os_free(p);
523                 return -1;
524         }
525         os_memcpy(p->pin, pin, pin_len);
526         p->pin_len = pin_len;
527
528         if (timeout) {
529                 p->flags |= PIN_EXPIRES;
530                 os_get_time(&p->expiration);
531                 p->expiration.sec += timeout;
532         }
533
534         dl_list_add(&reg->pins, &p->list);
535
536         wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
537                    timeout);
538         wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
539         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
540         reg->selected_registrar = 1;
541         reg->pbc = 0;
542         wps_registrar_selected_registrar_changed(reg);
543         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
544         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
545                                wps_registrar_set_selected_timeout,
546                                reg, NULL);
547
548         return 0;
549 }
550
551
552 static void wps_registrar_expire_pins(struct wps_registrar *reg)
553 {
554         struct wps_uuid_pin *pin, *prev;
555         struct os_time now;
556
557         os_get_time(&now);
558         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
559         {
560                 if ((pin->flags & PIN_EXPIRES) &&
561                     os_time_before(&pin->expiration, &now)) {
562                         wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
563                                     pin->uuid, WPS_UUID_LEN);
564                         wps_remove_pin(pin);
565                 }
566         }
567 }
568
569
570 /**
571  * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
572  * @reg: Registrar data from wps_registrar_init()
573  * @uuid: UUID-E
574  * Returns: 0 on success, -1 on failure (e.g., PIN not found)
575  */
576 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
577 {
578         struct wps_uuid_pin *pin, *prev;
579
580         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
581         {
582                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
583                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
584                                     pin->uuid, WPS_UUID_LEN);
585                         wps_remove_pin(pin);
586                         return 0;
587                 }
588         }
589
590         return -1;
591 }
592
593
594 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
595                                         const u8 *uuid, size_t *pin_len)
596 {
597         struct wps_uuid_pin *pin, *found = NULL;
598
599         wps_registrar_expire_pins(reg);
600
601         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
602                 if (!pin->wildcard_uuid &&
603                     os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
604                         found = pin;
605                         break;
606                 }
607         }
608
609         if (!found) {
610                 /* Check for wildcard UUIDs since none of the UUID-specific
611                  * PINs matched */
612                 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
613                         if (pin->wildcard_uuid == 1) {
614                                 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
615                                            "PIN. Assigned it for this UUID-E");
616                                 pin->wildcard_uuid = 2;
617                                 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
618                                 found = pin;
619                                 break;
620                         }
621                 }
622         }
623
624         if (!found)
625                 return NULL;
626
627         /*
628          * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
629          * that could otherwise avoid PIN invalidations.
630          */
631         if (found->flags & PIN_LOCKED) {
632                 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
633                            "allow concurrent re-use");
634                 return NULL;
635         }
636         *pin_len = found->pin_len;
637         found->flags |= PIN_LOCKED;
638         return found->pin;
639 }
640
641
642 /**
643  * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
644  * @reg: Registrar data from wps_registrar_init()
645  * @uuid: UUID-E
646  * Returns: 0 on success, -1 on failure
647  *
648  * PINs are locked to enforce only one concurrent use. This function unlocks a
649  * PIN to allow it to be used again. If the specified PIN was configured using
650  * a wildcard UUID, it will be removed instead of allowing multiple uses.
651  */
652 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
653 {
654         struct wps_uuid_pin *pin;
655
656         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
657                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
658                         if (pin->wildcard_uuid == 2) {
659                                 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
660                                            "wildcard PIN");
661                                 return wps_registrar_invalidate_pin(reg, uuid);
662                         }
663                         pin->flags &= ~PIN_LOCKED;
664                         return 0;
665                 }
666         }
667
668         return -1;
669 }
670
671
672 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
673 {
674         reg->selected_registrar = 0;
675         reg->pbc = 0;
676         wps_registrar_selected_registrar_changed(reg);
677 }
678
679
680 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
681 {
682         struct wps_registrar *reg = eloop_ctx;
683
684         wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
685         wps_pbc_timeout_event(reg->wps);
686         wps_registrar_stop_pbc(reg);
687 }
688
689
690 /**
691  * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
692  * @reg: Registrar data from wps_registrar_init()
693  * Returns: 0 on success, -1 on failure
694  *
695  * This function is called on an AP when a push button is pushed to activate
696  * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
697  * or when a PBC registration is completed.
698  */
699 int wps_registrar_button_pushed(struct wps_registrar *reg)
700 {
701         if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
702                 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
703                            "mode");
704                 wps_pbc_overlap_event(reg->wps);
705                 return -1;
706         }
707         wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
708         reg->force_pbc_overlap = 0;
709         reg->selected_registrar = 1;
710         reg->pbc = 1;
711         wps_registrar_selected_registrar_changed(reg);
712
713         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
714         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
715                                reg, NULL);
716         return 0;
717 }
718
719
720 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
721 {
722         wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
723         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
724         wps_registrar_stop_pbc(reg);
725 }
726
727
728 static void wps_registrar_pin_completed(struct wps_registrar *reg)
729 {
730         wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
731         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
732         reg->selected_registrar = 0;
733         wps_registrar_selected_registrar_changed(reg);
734 }
735
736
737 /**
738  * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
739  * @reg: Registrar data from wps_registrar_init()
740  * @addr: MAC address of the Probe Request sender
741  * @wps_data: WPS IE contents
742  *
743  * This function is called on an AP when a Probe Request with WPS IE is
744  * received. This is used to track PBC mode use and to detect possible overlap
745  * situation with other WPS APs.
746  */
747 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
748                                 const struct wpabuf *wps_data)
749 {
750         struct wps_parse_attr attr;
751
752         wpa_hexdump_buf(MSG_MSGDUMP,
753                         "WPS: Probe Request with WPS data received",
754                         wps_data);
755
756         if (wps_parse_msg(wps_data, &attr) < 0)
757                 return;
758         if (!wps_version_supported(attr.version)) {
759                 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
760                            "version 0x%x", attr.version ? *attr.version : 0);
761                 return;
762         }
763
764         if (attr.config_methods == NULL) {
765                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
766                            "Probe Request");
767                 return;
768         }
769
770         if (attr.dev_password_id == NULL) {
771                 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
772                            "in Probe Request");
773                 return;
774         }
775
776         if (reg->enrollee_seen_cb && attr.uuid_e &&
777             attr.primary_dev_type && attr.request_type) {
778                 char *dev_name = NULL;
779                 if (attr.dev_name) {
780                         dev_name = os_zalloc(attr.dev_name_len + 1);
781                         if (dev_name) {
782                                 os_memcpy(dev_name, attr.dev_name,
783                                           attr.dev_name_len);
784                         }
785                 }
786                 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
787                                       attr.primary_dev_type,
788                                       WPA_GET_BE16(attr.config_methods),
789                                       WPA_GET_BE16(attr.dev_password_id),
790                                       *attr.request_type, dev_name);
791                 os_free(dev_name);
792         }
793
794         if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
795                 return; /* Not PBC */
796
797         wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
798                    MACSTR, MAC2STR(addr));
799         if (attr.uuid_e == NULL) {
800                 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
801                            "UUID-E included");
802                 return;
803         }
804
805         wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
806         if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
807                 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
808                 reg->force_pbc_overlap = 1;
809                 wps_pbc_overlap_event(reg->wps);
810         }
811 }
812
813
814 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
815                           const u8 *psk, size_t psk_len)
816 {
817         if (reg->new_psk_cb == NULL)
818                 return 0;
819
820         return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
821 }
822
823
824 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
825                               const struct wps_device_data *dev)
826 {
827         if (reg->pin_needed_cb == NULL)
828                 return;
829
830         reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
831 }
832
833
834 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
835                                const u8 *uuid_e)
836 {
837         if (reg->reg_success_cb == NULL)
838                 return;
839
840         reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
841 }
842
843
844 static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
845                          struct wpabuf *probe_resp_ie)
846 {
847         return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
848 }
849
850
851 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
852 {
853         u16 methods = 0;
854         if (reg->set_sel_reg_cb == NULL)
855                 return;
856
857         if (reg->selected_registrar) {
858                 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
859                 if (reg->pbc)
860                         methods |= WPS_CONFIG_PUSHBUTTON;
861         }
862
863         reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
864                             reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
865                             methods);
866 }
867
868
869 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
870 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
871 {
872         struct wpabuf *ie;
873         const u8 *pos, *end;
874
875         ie = wpabuf_alloc(wpabuf_len(data) + 100);
876         if (ie == NULL) {
877                 wpabuf_free(data);
878                 return NULL;
879         }
880
881         pos = wpabuf_head(data);
882         end = pos + wpabuf_len(data);
883
884         while (end > pos) {
885                 size_t frag_len = end - pos;
886                 if (frag_len > 251)
887                         frag_len = 251;
888                 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
889                 wpabuf_put_u8(ie, 4 + frag_len);
890                 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
891                 wpabuf_put_data(ie, pos, frag_len);
892                 pos += frag_len;
893         }
894
895         wpabuf_free(data);
896
897         return ie;
898 }
899
900
901 static int wps_set_ie(struct wps_registrar *reg)
902 {
903         struct wpabuf *beacon;
904         struct wpabuf *probe;
905
906         if (reg->set_ie_cb == NULL)
907                 return 0;
908
909         wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
910
911         beacon = wpabuf_alloc(300);
912         if (beacon == NULL)
913                 return -1;
914         probe = wpabuf_alloc(400);
915         if (probe == NULL) {
916                 wpabuf_free(beacon);
917                 return -1;
918         }
919
920         if (wps_build_version(beacon) ||
921             wps_build_wps_state(reg->wps, beacon) ||
922             wps_build_ap_setup_locked(reg->wps, beacon) ||
923             wps_build_selected_registrar(reg, beacon) ||
924             wps_build_sel_reg_dev_password_id(reg, beacon) ||
925             wps_build_sel_reg_config_methods(reg, beacon) ||
926             wps_build_version(probe) ||
927             wps_build_wps_state(reg->wps, probe) ||
928             wps_build_ap_setup_locked(reg->wps, probe) ||
929             wps_build_selected_registrar(reg, probe) ||
930             wps_build_sel_reg_dev_password_id(reg, probe) ||
931             wps_build_sel_reg_config_methods(reg, probe) ||
932             wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
933                                 WPS_RESP_REGISTRAR) ||
934             wps_build_uuid_e(probe, reg->wps->uuid) ||
935             wps_build_device_attrs(&reg->wps->dev, probe) ||
936             wps_build_probe_config_methods(reg, probe) ||
937             wps_build_rf_bands(&reg->wps->dev, probe)) {
938                 wpabuf_free(beacon);
939                 wpabuf_free(probe);
940                 return -1;
941         }
942
943         beacon = wps_ie_encapsulate(beacon);
944         probe = wps_ie_encapsulate(probe);
945
946         if (!beacon || !probe) {
947                 wpabuf_free(beacon);
948                 wpabuf_free(probe);
949                 return -1;
950         }
951
952         if (reg->static_wep_only) {
953                 /*
954                  * Windows XP and Vista clients can get confused about
955                  * EAP-Identity/Request when they probe the network with
956                  * EAPOL-Start. In such a case, they may assume the network is
957                  * using IEEE 802.1X and prompt user for a certificate while
958                  * the correct (non-WPS) behavior would be to ask for the
959                  * static WEP key. As a workaround, use Microsoft Provisioning
960                  * IE to advertise that legacy 802.1X is not supported.
961                  */
962                 const u8 ms_wps[7] = {
963                         WLAN_EID_VENDOR_SPECIFIC, 5,
964                         /* Microsoft Provisioning IE (00:50:f2:5) */
965                         0x00, 0x50, 0xf2, 5,
966                         0x00 /* no legacy 802.1X or MS WPS */
967                 };
968                 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
969                            "into Beacon/Probe Response frames");
970                 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
971                 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
972         }
973
974         return wps_cb_set_ie(reg, beacon, probe);
975 }
976
977
978 static int wps_get_dev_password(struct wps_data *wps)
979 {
980         const u8 *pin;
981         size_t pin_len = 0;
982
983         os_free(wps->dev_password);
984         wps->dev_password = NULL;
985
986         if (wps->pbc) {
987                 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
988                 pin = (const u8 *) "00000000";
989                 pin_len = 8;
990         } else {
991                 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
992                                             &pin_len);
993         }
994         if (pin == NULL) {
995                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
996                            "the Enrollee");
997                 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
998                                   &wps->peer_dev);
999                 return -1;
1000         }
1001
1002         wps->dev_password = os_malloc(pin_len);
1003         if (wps->dev_password == NULL)
1004                 return -1;
1005         os_memcpy(wps->dev_password, pin, pin_len);
1006         wps->dev_password_len = pin_len;
1007
1008         return 0;
1009 }
1010
1011
1012 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
1013 {
1014         wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
1015         wpabuf_put_be16(msg, ATTR_UUID_R);
1016         wpabuf_put_be16(msg, WPS_UUID_LEN);
1017         wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
1018         return 0;
1019 }
1020
1021
1022 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
1023 {
1024         u8 *hash;
1025         const u8 *addr[4];
1026         size_t len[4];
1027
1028         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
1029                 return -1;
1030         wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
1031         wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
1032                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
1033
1034         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
1035                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
1036                            "R-Hash derivation");
1037                 return -1;
1038         }
1039
1040         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
1041         wpabuf_put_be16(msg, ATTR_R_HASH1);
1042         wpabuf_put_be16(msg, SHA256_MAC_LEN);
1043         hash = wpabuf_put(msg, SHA256_MAC_LEN);
1044         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
1045         addr[0] = wps->snonce;
1046         len[0] = WPS_SECRET_NONCE_LEN;
1047         addr[1] = wps->psk1;
1048         len[1] = WPS_PSK_LEN;
1049         addr[2] = wpabuf_head(wps->dh_pubkey_e);
1050         len[2] = wpabuf_len(wps->dh_pubkey_e);
1051         addr[3] = wpabuf_head(wps->dh_pubkey_r);
1052         len[3] = wpabuf_len(wps->dh_pubkey_r);
1053         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1054         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
1055
1056         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
1057         wpabuf_put_be16(msg, ATTR_R_HASH2);
1058         wpabuf_put_be16(msg, SHA256_MAC_LEN);
1059         hash = wpabuf_put(msg, SHA256_MAC_LEN);
1060         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
1061         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
1062         addr[1] = wps->psk2;
1063         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1064         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
1065
1066         return 0;
1067 }
1068
1069
1070 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
1071 {
1072         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
1073         wpabuf_put_be16(msg, ATTR_R_SNONCE1);
1074         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1075         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
1076         return 0;
1077 }
1078
1079
1080 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
1081 {
1082         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
1083         wpabuf_put_be16(msg, ATTR_R_SNONCE2);
1084         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
1085         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
1086                         WPS_SECRET_NONCE_LEN);
1087         return 0;
1088 }
1089
1090
1091 static int wps_build_cred_network_idx(struct wpabuf *msg,
1092                                       const struct wps_credential *cred)
1093 {
1094         wpa_printf(MSG_DEBUG, "WPS:  * Network Index");
1095         wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
1096         wpabuf_put_be16(msg, 1);
1097         wpabuf_put_u8(msg, 1);
1098         return 0;
1099 }
1100
1101
1102 static int wps_build_cred_ssid(struct wpabuf *msg,
1103                                const struct wps_credential *cred)
1104 {
1105         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
1106         wpabuf_put_be16(msg, ATTR_SSID);
1107         wpabuf_put_be16(msg, cred->ssid_len);
1108         wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
1109         return 0;
1110 }
1111
1112
1113 static int wps_build_cred_auth_type(struct wpabuf *msg,
1114                                     const struct wps_credential *cred)
1115 {
1116         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
1117                    cred->auth_type);
1118         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
1119         wpabuf_put_be16(msg, 2);
1120         wpabuf_put_be16(msg, cred->auth_type);
1121         return 0;
1122 }
1123
1124
1125 static int wps_build_cred_encr_type(struct wpabuf *msg,
1126                                     const struct wps_credential *cred)
1127 {
1128         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
1129                    cred->encr_type);
1130         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
1131         wpabuf_put_be16(msg, 2);
1132         wpabuf_put_be16(msg, cred->encr_type);
1133         return 0;
1134 }
1135
1136
1137 static int wps_build_cred_network_key(struct wpabuf *msg,
1138                                       const struct wps_credential *cred)
1139 {
1140         wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%d)",
1141                    (int) cred->key_len);
1142         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
1143         wpabuf_put_be16(msg, cred->key_len);
1144         wpabuf_put_data(msg, cred->key, cred->key_len);
1145         return 0;
1146 }
1147
1148
1149 static int wps_build_cred_mac_addr(struct wpabuf *msg,
1150                                    const struct wps_credential *cred)
1151 {
1152         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (" MACSTR ")",
1153                    MAC2STR(cred->mac_addr));
1154         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
1155         wpabuf_put_be16(msg, ETH_ALEN);
1156         wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
1157         return 0;
1158 }
1159
1160
1161 static int wps_build_credential(struct wpabuf *msg,
1162                                 const struct wps_credential *cred)
1163 {
1164         if (wps_build_cred_network_idx(msg, cred) ||
1165             wps_build_cred_ssid(msg, cred) ||
1166             wps_build_cred_auth_type(msg, cred) ||
1167             wps_build_cred_encr_type(msg, cred) ||
1168             wps_build_cred_network_key(msg, cred) ||
1169             wps_build_cred_mac_addr(msg, cred))
1170                 return -1;
1171         return 0;
1172 }
1173
1174
1175 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
1176 {
1177         struct wpabuf *cred;
1178
1179         if (wps->wps->registrar->skip_cred_build)
1180                 goto skip_cred_build;
1181
1182         wpa_printf(MSG_DEBUG, "WPS:  * Credential");
1183         if (wps->use_cred) {
1184                 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
1185                 goto use_provided;
1186         }
1187         os_memset(&wps->cred, 0, sizeof(wps->cred));
1188
1189         os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
1190         wps->cred.ssid_len = wps->wps->ssid_len;
1191
1192         /* Select the best authentication and encryption type */
1193         if (wps->auth_type & WPS_AUTH_WPA2PSK)
1194                 wps->auth_type = WPS_AUTH_WPA2PSK;
1195         else if (wps->auth_type & WPS_AUTH_WPAPSK)
1196                 wps->auth_type = WPS_AUTH_WPAPSK;
1197         else if (wps->auth_type & WPS_AUTH_OPEN)
1198                 wps->auth_type = WPS_AUTH_OPEN;
1199         else if (wps->auth_type & WPS_AUTH_SHARED)
1200                 wps->auth_type = WPS_AUTH_SHARED;
1201         else {
1202                 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
1203                            wps->auth_type);
1204                 return -1;
1205         }
1206         wps->cred.auth_type = wps->auth_type;
1207
1208         if (wps->auth_type == WPS_AUTH_WPA2PSK ||
1209             wps->auth_type == WPS_AUTH_WPAPSK) {
1210                 if (wps->encr_type & WPS_ENCR_AES)
1211                         wps->encr_type = WPS_ENCR_AES;
1212                 else if (wps->encr_type & WPS_ENCR_TKIP)
1213                         wps->encr_type = WPS_ENCR_TKIP;
1214                 else {
1215                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1216                                    "type for WPA/WPA2");
1217                         return -1;
1218                 }
1219         } else {
1220                 if (wps->encr_type & WPS_ENCR_WEP)
1221                         wps->encr_type = WPS_ENCR_WEP;
1222                 else if (wps->encr_type & WPS_ENCR_NONE)
1223                         wps->encr_type = WPS_ENCR_NONE;
1224                 else {
1225                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
1226                                    "type for non-WPA/WPA2 mode");
1227                         return -1;
1228                 }
1229         }
1230         wps->cred.encr_type = wps->encr_type;
1231         /*
1232          * Set MAC address in the Credential to be the Enrollee's MAC address
1233          */
1234         os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
1235
1236         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
1237             !wps->wps->registrar->disable_auto_conf) {
1238                 u8 r[16];
1239                 /* Generate a random passphrase */
1240                 if (os_get_random(r, sizeof(r)) < 0)
1241                         return -1;
1242                 os_free(wps->new_psk);
1243                 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
1244                 if (wps->new_psk == NULL)
1245                         return -1;
1246                 wps->new_psk_len--; /* remove newline */
1247                 while (wps->new_psk_len &&
1248                        wps->new_psk[wps->new_psk_len - 1] == '=')
1249                         wps->new_psk_len--;
1250                 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
1251                                       wps->new_psk, wps->new_psk_len);
1252                 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
1253                 wps->cred.key_len = wps->new_psk_len;
1254         } else if (wps->use_psk_key && wps->wps->psk_set) {
1255                 char hex[65];
1256                 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
1257                 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
1258                 os_memcpy(wps->cred.key, hex, 32 * 2);
1259                 wps->cred.key_len = 32 * 2;
1260         } else if (wps->wps->network_key) {
1261                 os_memcpy(wps->cred.key, wps->wps->network_key,
1262                           wps->wps->network_key_len);
1263                 wps->cred.key_len = wps->wps->network_key_len;
1264         } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
1265                 char hex[65];
1266                 /* Generate a random per-device PSK */
1267                 os_free(wps->new_psk);
1268                 wps->new_psk_len = 32;
1269                 wps->new_psk = os_malloc(wps->new_psk_len);
1270                 if (wps->new_psk == NULL)
1271                         return -1;
1272                 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
1273                         os_free(wps->new_psk);
1274                         wps->new_psk = NULL;
1275                         return -1;
1276                 }
1277                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
1278                                 wps->new_psk, wps->new_psk_len);
1279                 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
1280                                  wps->new_psk_len);
1281                 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
1282                 wps->cred.key_len = wps->new_psk_len * 2;
1283         }
1284
1285 use_provided:
1286         cred = wpabuf_alloc(200);
1287         if (cred == NULL)
1288                 return -1;
1289
1290         if (wps_build_credential(cred, &wps->cred)) {
1291                 wpabuf_free(cred);
1292                 return -1;
1293         }
1294
1295         wpabuf_put_be16(msg, ATTR_CRED);
1296         wpabuf_put_be16(msg, wpabuf_len(cred));
1297         wpabuf_put_buf(msg, cred);
1298         wpabuf_free(cred);
1299
1300 skip_cred_build:
1301         if (wps->wps->registrar->extra_cred) {
1302                 wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
1303                 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
1304         }
1305
1306         return 0;
1307 }
1308
1309
1310 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
1311 {
1312         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
1313
1314         if (wps_build_credential(msg, &wps->cred))
1315                 return -1;
1316
1317         return 0;
1318 }
1319
1320
1321 static struct wpabuf * wps_build_m2(struct wps_data *wps)
1322 {
1323         struct wpabuf *msg;
1324
1325         if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
1326                 return NULL;
1327         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
1328                     wps->nonce_r, WPS_NONCE_LEN);
1329         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
1330
1331         wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
1332         msg = wpabuf_alloc(1000);
1333         if (msg == NULL)
1334                 return NULL;
1335
1336         if (wps_build_version(msg) ||
1337             wps_build_msg_type(msg, WPS_M2) ||
1338             wps_build_enrollee_nonce(wps, msg) ||
1339             wps_build_registrar_nonce(wps, msg) ||
1340             wps_build_uuid_r(wps, msg) ||
1341             wps_build_public_key(wps, msg) ||
1342             wps_derive_keys(wps) ||
1343             wps_build_auth_type_flags(wps, msg) ||
1344             wps_build_encr_type_flags(wps, msg) ||
1345             wps_build_conn_type_flags(wps, msg) ||
1346             wps_build_config_methods_r(wps->wps->registrar, msg) ||
1347             wps_build_device_attrs(&wps->wps->dev, msg) ||
1348             wps_build_rf_bands(&wps->wps->dev, msg) ||
1349             wps_build_assoc_state(wps, msg) ||
1350             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
1351             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
1352             wps_build_os_version(&wps->wps->dev, msg) ||
1353             wps_build_authenticator(wps, msg)) {
1354                 wpabuf_free(msg);
1355                 return NULL;
1356         }
1357
1358         wps->int_reg = 1;
1359         wps->state = RECV_M3;
1360         return msg;
1361 }
1362
1363
1364 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
1365 {
1366         struct wpabuf *msg;
1367         u16 err = wps->config_error;
1368
1369         wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
1370         msg = wpabuf_alloc(1000);
1371         if (msg == NULL)
1372                 return NULL;
1373
1374         if (wps->wps->ap && wps->wps->ap_setup_locked &&
1375             err == WPS_CFG_NO_ERROR)
1376                 err = WPS_CFG_SETUP_LOCKED;
1377
1378         if (wps_build_version(msg) ||
1379             wps_build_msg_type(msg, WPS_M2D) ||
1380             wps_build_enrollee_nonce(wps, msg) ||
1381             wps_build_registrar_nonce(wps, msg) ||
1382             wps_build_uuid_r(wps, msg) ||
1383             wps_build_auth_type_flags(wps, msg) ||
1384             wps_build_encr_type_flags(wps, msg) ||
1385             wps_build_conn_type_flags(wps, msg) ||
1386             wps_build_config_methods_r(wps->wps->registrar, msg) ||
1387             wps_build_device_attrs(&wps->wps->dev, msg) ||
1388             wps_build_rf_bands(&wps->wps->dev, msg) ||
1389             wps_build_assoc_state(wps, msg) ||
1390             wps_build_config_error(msg, err) ||
1391             wps_build_os_version(&wps->wps->dev, msg)) {
1392                 wpabuf_free(msg);
1393                 return NULL;
1394         }
1395
1396         wps->state = RECV_M2D_ACK;
1397         return msg;
1398 }
1399
1400
1401 static struct wpabuf * wps_build_m4(struct wps_data *wps)
1402 {
1403         struct wpabuf *msg, *plain;
1404
1405         wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
1406
1407         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
1408
1409         plain = wpabuf_alloc(200);
1410         if (plain == NULL)
1411                 return NULL;
1412
1413         msg = wpabuf_alloc(1000);
1414         if (msg == NULL) {
1415                 wpabuf_free(plain);
1416                 return NULL;
1417         }
1418
1419         if (wps_build_version(msg) ||
1420             wps_build_msg_type(msg, WPS_M4) ||
1421             wps_build_enrollee_nonce(wps, msg) ||
1422             wps_build_r_hash(wps, msg) ||
1423             wps_build_r_snonce1(wps, plain) ||
1424             wps_build_key_wrap_auth(wps, plain) ||
1425             wps_build_encr_settings(wps, msg, plain) ||
1426             wps_build_authenticator(wps, msg)) {
1427                 wpabuf_free(plain);
1428                 wpabuf_free(msg);
1429                 return NULL;
1430         }
1431         wpabuf_free(plain);
1432
1433         wps->state = RECV_M5;
1434         return msg;
1435 }
1436
1437
1438 static struct wpabuf * wps_build_m6(struct wps_data *wps)
1439 {
1440         struct wpabuf *msg, *plain;
1441
1442         wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
1443
1444         plain = wpabuf_alloc(200);
1445         if (plain == NULL)
1446                 return NULL;
1447
1448         msg = wpabuf_alloc(1000);
1449         if (msg == NULL) {
1450                 wpabuf_free(plain);
1451                 return NULL;
1452         }
1453
1454         if (wps_build_version(msg) ||
1455             wps_build_msg_type(msg, WPS_M6) ||
1456             wps_build_enrollee_nonce(wps, msg) ||
1457             wps_build_r_snonce2(wps, plain) ||
1458             wps_build_key_wrap_auth(wps, plain) ||
1459             wps_build_encr_settings(wps, msg, plain) ||
1460             wps_build_authenticator(wps, msg)) {
1461                 wpabuf_free(plain);
1462                 wpabuf_free(msg);
1463                 return NULL;
1464         }
1465         wpabuf_free(plain);
1466
1467         wps->wps_pin_revealed = 1;
1468         wps->state = RECV_M7;
1469         return msg;
1470 }
1471
1472
1473 static struct wpabuf * wps_build_m8(struct wps_data *wps)
1474 {
1475         struct wpabuf *msg, *plain;
1476
1477         wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
1478
1479         plain = wpabuf_alloc(500);
1480         if (plain == NULL)
1481                 return NULL;
1482
1483         msg = wpabuf_alloc(1000);
1484         if (msg == NULL) {
1485                 wpabuf_free(plain);
1486                 return NULL;
1487         }
1488
1489         if (wps_build_version(msg) ||
1490             wps_build_msg_type(msg, WPS_M8) ||
1491             wps_build_enrollee_nonce(wps, msg) ||
1492             ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
1493             (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
1494             wps_build_key_wrap_auth(wps, plain) ||
1495             wps_build_encr_settings(wps, msg, plain) ||
1496             wps_build_authenticator(wps, msg)) {
1497                 wpabuf_free(plain);
1498                 wpabuf_free(msg);
1499                 return NULL;
1500         }
1501         wpabuf_free(plain);
1502
1503         wps->state = RECV_DONE;
1504         return msg;
1505 }
1506
1507
1508 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
1509 {
1510         struct wpabuf *msg;
1511
1512         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
1513
1514         msg = wpabuf_alloc(1000);
1515         if (msg == NULL)
1516                 return NULL;
1517
1518         if (wps_build_version(msg) ||
1519             wps_build_msg_type(msg, WPS_WSC_ACK) ||
1520             wps_build_enrollee_nonce(wps, msg) ||
1521             wps_build_registrar_nonce(wps, msg)) {
1522                 wpabuf_free(msg);
1523                 return NULL;
1524         }
1525
1526         return msg;
1527 }
1528
1529
1530 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
1531 {
1532         struct wpabuf *msg;
1533
1534         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
1535
1536         msg = wpabuf_alloc(1000);
1537         if (msg == NULL)
1538                 return NULL;
1539
1540         if (wps_build_version(msg) ||
1541             wps_build_msg_type(msg, WPS_WSC_NACK) ||
1542             wps_build_enrollee_nonce(wps, msg) ||
1543             wps_build_registrar_nonce(wps, msg) ||
1544             wps_build_config_error(msg, wps->config_error)) {
1545                 wpabuf_free(msg);
1546                 return NULL;
1547         }
1548
1549         return msg;
1550 }
1551
1552
1553 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
1554                                       enum wsc_op_code *op_code)
1555 {
1556         struct wpabuf *msg;
1557
1558 #ifdef CONFIG_WPS_UPNP
1559         if (!wps->int_reg && wps->wps->wps_upnp) {
1560                 struct upnp_pending_message *p, *prev = NULL;
1561                 if (wps->ext_reg > 1)
1562                         wps_registrar_free_pending_m2(wps->wps);
1563                 p = wps->wps->upnp_msgs;
1564                 /* TODO: check pending message MAC address */
1565                 while (p && p->next) {
1566                         prev = p;
1567                         p = p->next;
1568                 }
1569                 if (p) {
1570                         wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
1571                                    "UPnP");
1572                         if (prev)
1573                                 prev->next = NULL;
1574                         else
1575                                 wps->wps->upnp_msgs = NULL;
1576                         msg = p->msg;
1577                         switch (p->type) {
1578                         case WPS_WSC_ACK:
1579                                 *op_code = WSC_ACK;
1580                                 break;
1581                         case WPS_WSC_NACK:
1582                                 *op_code = WSC_NACK;
1583                                 break;
1584                         default:
1585                                 *op_code = WSC_MSG;
1586                                 break;
1587                         }
1588                         os_free(p);
1589                         if (wps->ext_reg == 0)
1590                                 wps->ext_reg = 1;
1591                         return msg;
1592                 }
1593         }
1594         if (wps->ext_reg) {
1595                 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
1596                            "pending message available");
1597                 return NULL;
1598         }
1599 #endif /* CONFIG_WPS_UPNP */
1600
1601         switch (wps->state) {
1602         case SEND_M2:
1603                 if (wps_get_dev_password(wps) < 0)
1604                         msg = wps_build_m2d(wps);
1605                 else
1606                         msg = wps_build_m2(wps);
1607                 *op_code = WSC_MSG;
1608                 break;
1609         case SEND_M2D:
1610                 msg = wps_build_m2d(wps);
1611                 *op_code = WSC_MSG;
1612                 break;
1613         case SEND_M4:
1614                 msg = wps_build_m4(wps);
1615                 *op_code = WSC_MSG;
1616                 break;
1617         case SEND_M6:
1618                 msg = wps_build_m6(wps);
1619                 *op_code = WSC_MSG;
1620                 break;
1621         case SEND_M8:
1622                 msg = wps_build_m8(wps);
1623                 *op_code = WSC_MSG;
1624                 break;
1625         case RECV_DONE:
1626                 msg = wps_build_wsc_ack(wps);
1627                 *op_code = WSC_ACK;
1628                 break;
1629         case SEND_WSC_NACK:
1630                 msg = wps_build_wsc_nack(wps);
1631                 *op_code = WSC_NACK;
1632                 break;
1633         default:
1634                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
1635                            "a message", wps->state);
1636                 msg = NULL;
1637                 break;
1638         }
1639
1640         if (*op_code == WSC_MSG && msg) {
1641                 /* Save a copy of the last message for Authenticator derivation
1642                  */
1643                 wpabuf_free(wps->last_msg);
1644                 wps->last_msg = wpabuf_dup(msg);
1645         }
1646
1647         return msg;
1648 }
1649
1650
1651 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
1652 {
1653         if (e_nonce == NULL) {
1654                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
1655                 return -1;
1656         }
1657
1658         os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
1659         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
1660                     wps->nonce_e, WPS_NONCE_LEN);
1661
1662         return 0;
1663 }
1664
1665
1666 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
1667 {
1668         if (r_nonce == NULL) {
1669                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
1670                 return -1;
1671         }
1672
1673         if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
1674                 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
1675                 return -1;
1676         }
1677
1678         return 0;
1679 }
1680
1681
1682 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
1683 {
1684         if (uuid_e == NULL) {
1685                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
1686                 return -1;
1687         }
1688
1689         os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
1690         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
1691
1692         return 0;
1693 }
1694
1695
1696 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
1697 {
1698         if (pw_id == NULL) {
1699                 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
1700                 return -1;
1701         }
1702
1703         wps->dev_pw_id = WPA_GET_BE16(pw_id);
1704         wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
1705
1706         return 0;
1707 }
1708
1709
1710 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
1711 {
1712         if (e_hash1 == NULL) {
1713                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
1714                 return -1;
1715         }
1716
1717         os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
1718         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
1719
1720         return 0;
1721 }
1722
1723
1724 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
1725 {
1726         if (e_hash2 == NULL) {
1727                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
1728                 return -1;
1729         }
1730
1731         os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
1732         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
1733
1734         return 0;
1735 }
1736
1737
1738 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
1739 {
1740         u8 hash[SHA256_MAC_LEN];
1741         const u8 *addr[4];
1742         size_t len[4];
1743
1744         if (e_snonce1 == NULL) {
1745                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
1746                 return -1;
1747         }
1748
1749         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
1750                         WPS_SECRET_NONCE_LEN);
1751
1752         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
1753         addr[0] = e_snonce1;
1754         len[0] = WPS_SECRET_NONCE_LEN;
1755         addr[1] = wps->psk1;
1756         len[1] = WPS_PSK_LEN;
1757         addr[2] = wpabuf_head(wps->dh_pubkey_e);
1758         len[2] = wpabuf_len(wps->dh_pubkey_e);
1759         addr[3] = wpabuf_head(wps->dh_pubkey_r);
1760         len[3] = wpabuf_len(wps->dh_pubkey_r);
1761         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1762
1763         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
1764                 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
1765                            "not match with the pre-committed value");
1766                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1767                 wps_pwd_auth_fail_event(wps->wps, 0, 1);
1768                 return -1;
1769         }
1770
1771         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
1772                    "half of the device password");
1773
1774         return 0;
1775 }
1776
1777
1778 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
1779 {
1780         u8 hash[SHA256_MAC_LEN];
1781         const u8 *addr[4];
1782         size_t len[4];
1783
1784         if (e_snonce2 == NULL) {
1785                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
1786                 return -1;
1787         }
1788
1789         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
1790                         WPS_SECRET_NONCE_LEN);
1791
1792         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
1793         addr[0] = e_snonce2;
1794         len[0] = WPS_SECRET_NONCE_LEN;
1795         addr[1] = wps->psk2;
1796         len[1] = WPS_PSK_LEN;
1797         addr[2] = wpabuf_head(wps->dh_pubkey_e);
1798         len[2] = wpabuf_len(wps->dh_pubkey_e);
1799         addr[3] = wpabuf_head(wps->dh_pubkey_r);
1800         len[3] = wpabuf_len(wps->dh_pubkey_r);
1801         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
1802
1803         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
1804                 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
1805                            "not match with the pre-committed value");
1806                 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
1807                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
1808                 wps_pwd_auth_fail_event(wps->wps, 0, 2);
1809                 return -1;
1810         }
1811
1812         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
1813                    "half of the device password");
1814         wps->wps_pin_revealed = 0;
1815         wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
1816
1817         return 0;
1818 }
1819
1820
1821 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
1822 {
1823         if (mac_addr == NULL) {
1824                 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
1825                 return -1;
1826         }
1827
1828         wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
1829                    MAC2STR(mac_addr));
1830         os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
1831         os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
1832
1833         return 0;
1834 }
1835
1836
1837 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
1838                               size_t pk_len)
1839 {
1840         if (pk == NULL || pk_len == 0) {
1841                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
1842                 return -1;
1843         }
1844
1845 #ifdef CONFIG_WPS_OOB
1846         if (wps->wps->oob_conf.pubkey_hash != NULL) {
1847                 const u8 *addr[1];
1848                 u8 hash[WPS_HASH_LEN];
1849
1850                 addr[0] = pk;
1851                 sha256_vector(1, addr, &pk_len, hash);
1852                 if (os_memcmp(hash,
1853                               wpabuf_head(wps->wps->oob_conf.pubkey_hash),
1854                               WPS_OOB_PUBKEY_HASH_LEN) != 0) {
1855                         wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
1856                         return -1;
1857                 }
1858         }
1859 #endif /* CONFIG_WPS_OOB */
1860
1861         wpabuf_free(wps->dh_pubkey_e);
1862         wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
1863         if (wps->dh_pubkey_e == NULL)
1864                 return -1;
1865
1866         return 0;
1867 }
1868
1869
1870 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
1871 {
1872         u16 auth_types;
1873
1874         if (auth == NULL) {
1875                 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
1876                            "received");
1877                 return -1;
1878         }
1879
1880         auth_types = WPA_GET_BE16(auth);
1881
1882         wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
1883                    auth_types);
1884         wps->auth_type = wps->wps->auth_types & auth_types;
1885         if (wps->auth_type == 0) {
1886                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1887                            "authentication types (own 0x%x Enrollee 0x%x)",
1888                            wps->wps->auth_types, auth_types);
1889 #ifdef WPS_WORKAROUNDS
1890                 /*
1891                  * Some deployed implementations seem to advertise incorrect
1892                  * information in this attribute. For example, Linksys WRT350N
1893                  * seems to have a byteorder bug that breaks this negotiation.
1894                  * In order to interoperate with existing implementations,
1895                  * assume that the Enrollee supports everything we do.
1896                  */
1897                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
1898                            "does not advertise supported authentication types "
1899                            "correctly");
1900                 wps->auth_type = wps->wps->auth_types;
1901 #else /* WPS_WORKAROUNDS */
1902                 return -1;
1903 #endif /* WPS_WORKAROUNDS */
1904         }
1905
1906         return 0;
1907 }
1908
1909
1910 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
1911 {
1912         u16 encr_types;
1913
1914         if (encr == NULL) {
1915                 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
1916                            "received");
1917                 return -1;
1918         }
1919
1920         encr_types = WPA_GET_BE16(encr);
1921
1922         wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
1923                    encr_types);
1924         wps->encr_type = wps->wps->encr_types & encr_types;
1925         if (wps->encr_type == 0) {
1926                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
1927                            "encryption types (own 0x%x Enrollee 0x%x)",
1928                            wps->wps->encr_types, encr_types);
1929 #ifdef WPS_WORKAROUNDS
1930                 /*
1931                  * Some deployed implementations seem to advertise incorrect
1932                  * information in this attribute. For example, Linksys WRT350N
1933                  * seems to have a byteorder bug that breaks this negotiation.
1934                  * In order to interoperate with existing implementations,
1935                  * assume that the Enrollee supports everything we do.
1936                  */
1937                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
1938                            "does not advertise supported encryption types "
1939                            "correctly");
1940                 wps->encr_type = wps->wps->encr_types;
1941 #else /* WPS_WORKAROUNDS */
1942                 return -1;
1943 #endif /* WPS_WORKAROUNDS */
1944         }
1945
1946         return 0;
1947 }
1948
1949
1950 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
1951 {
1952         if (conn == NULL) {
1953                 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
1954                            "received");
1955                 return -1;
1956         }
1957
1958         wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
1959                    *conn);
1960
1961         return 0;
1962 }
1963
1964
1965 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
1966 {
1967         u16 m;
1968
1969         if (methods == NULL) {
1970                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
1971                 return -1;
1972         }
1973
1974         m = WPA_GET_BE16(methods);
1975
1976         wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
1977                    "%s%s%s%s%s%s%s%s%s", m,
1978                    m & WPS_CONFIG_USBA ? " [USBA]" : "",
1979                    m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
1980                    m & WPS_CONFIG_LABEL ? " [Label]" : "",
1981                    m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
1982                    m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
1983                    m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
1984                    m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
1985                    m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
1986                    m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
1987
1988         if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
1989                 /*
1990                  * The Enrollee does not have a display so it is unlikely to be
1991                  * able to show the passphrase to a user and as such, could
1992                  * benefit from receiving PSK to reduce key derivation time.
1993                  */
1994                 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
1995                            "Enrollee not supporting display");
1996                 wps->use_psk_key = 1;
1997         }
1998
1999         return 0;
2000 }
2001
2002
2003 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
2004 {
2005         if (state == NULL) {
2006                 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
2007                            "received");
2008                 return -1;
2009         }
2010
2011         wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
2012                    *state);
2013
2014         return 0;
2015 }
2016
2017
2018 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
2019 {
2020         u16 a;
2021
2022         if (assoc == NULL) {
2023                 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
2024                 return -1;
2025         }
2026
2027         a = WPA_GET_BE16(assoc);
2028         wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
2029
2030         return 0;
2031 }
2032
2033
2034 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
2035 {
2036         u16 e;
2037
2038         if (err == NULL) {
2039                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
2040                 return -1;
2041         }
2042
2043         e = WPA_GET_BE16(err);
2044         wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
2045
2046         return 0;
2047 }
2048
2049
2050 static enum wps_process_res wps_process_m1(struct wps_data *wps,
2051                                            struct wps_parse_attr *attr)
2052 {
2053         wpa_printf(MSG_DEBUG, "WPS: Received M1");
2054
2055         if (wps->state != RECV_M1) {
2056                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2057                            "receiving M1", wps->state);
2058                 return WPS_FAILURE;
2059         }
2060
2061         if (wps_process_uuid_e(wps, attr->uuid_e) ||
2062             wps_process_mac_addr(wps, attr->mac_addr) ||
2063             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
2064             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
2065             wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
2066             wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
2067             wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
2068             wps_process_config_methods(wps, attr->config_methods) ||
2069             wps_process_wps_state(wps, attr->wps_state) ||
2070             wps_process_device_attrs(&wps->peer_dev, attr) ||
2071             wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
2072             wps_process_assoc_state(wps, attr->assoc_state) ||
2073             wps_process_dev_password_id(wps, attr->dev_password_id) ||
2074             wps_process_config_error(wps, attr->config_error) ||
2075             wps_process_os_version(&wps->peer_dev, attr->os_version))
2076                 return WPS_FAILURE;
2077
2078         if (wps->dev_pw_id < 0x10 &&
2079             wps->dev_pw_id != DEV_PW_DEFAULT &&
2080             wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
2081             wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
2082             wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
2083             (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
2084              !wps->wps->registrar->pbc)) {
2085                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
2086                            wps->dev_pw_id);
2087                 wps->state = SEND_M2D;
2088                 return WPS_CONTINUE;
2089         }
2090
2091 #ifdef CONFIG_WPS_OOB
2092         if (wps->dev_pw_id >= 0x10 &&
2093             wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
2094                 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
2095                            "%d mismatch", wps->dev_pw_id);
2096                 wps->state = SEND_M2D;
2097                 return WPS_CONTINUE;
2098         }
2099 #endif /* CONFIG_WPS_OOB */
2100
2101         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
2102                 if (wps->wps->registrar->force_pbc_overlap ||
2103                     wps_registrar_pbc_overlap(wps->wps->registrar,
2104                                               wps->mac_addr_e, wps->uuid_e)) {
2105                         wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
2106                                    "negotiation");
2107                         wps->state = SEND_M2D;
2108                         wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2109                         wps_pbc_overlap_event(wps->wps);
2110                         wps->wps->registrar->force_pbc_overlap = 1;
2111                         return WPS_CONTINUE;
2112                 }
2113                 wps_registrar_add_pbc_session(wps->wps->registrar,
2114                                               wps->mac_addr_e, wps->uuid_e);
2115                 wps->pbc = 1;
2116         }
2117
2118 #ifdef WPS_WORKAROUNDS
2119         /*
2120          * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
2121          * passphrase format. To avoid interop issues, force PSK format to be
2122          * used.
2123          */
2124         if (!wps->use_psk_key &&
2125             wps->peer_dev.manufacturer &&
2126             os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
2127             wps->peer_dev.model_name &&
2128             os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
2129                 wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
2130                            "PSK format");
2131                 wps->use_psk_key = 1;
2132         }
2133 #endif /* WPS_WORKAROUNDS */
2134
2135         wps->state = SEND_M2;
2136         return WPS_CONTINUE;
2137 }
2138
2139
2140 static enum wps_process_res wps_process_m3(struct wps_data *wps,
2141                                            const struct wpabuf *msg,
2142                                            struct wps_parse_attr *attr)
2143 {
2144         wpa_printf(MSG_DEBUG, "WPS: Received M3");
2145
2146         if (wps->state != RECV_M3) {
2147                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2148                            "receiving M3", wps->state);
2149                 wps->state = SEND_WSC_NACK;
2150                 return WPS_CONTINUE;
2151         }
2152
2153         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2154                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2155                            "session overlap");
2156                 wps->state = SEND_WSC_NACK;
2157                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2158                 return WPS_CONTINUE;
2159         }
2160
2161         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2162             wps_process_authenticator(wps, attr->authenticator, msg) ||
2163             wps_process_e_hash1(wps, attr->e_hash1) ||
2164             wps_process_e_hash2(wps, attr->e_hash2)) {
2165                 wps->state = SEND_WSC_NACK;
2166                 return WPS_CONTINUE;
2167         }
2168
2169         wps->state = SEND_M4;
2170         return WPS_CONTINUE;
2171 }
2172
2173
2174 static enum wps_process_res wps_process_m5(struct wps_data *wps,
2175                                            const struct wpabuf *msg,
2176                                            struct wps_parse_attr *attr)
2177 {
2178         struct wpabuf *decrypted;
2179         struct wps_parse_attr eattr;
2180
2181         wpa_printf(MSG_DEBUG, "WPS: Received M5");
2182
2183         if (wps->state != RECV_M5) {
2184                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2185                            "receiving M5", wps->state);
2186                 wps->state = SEND_WSC_NACK;
2187                 return WPS_CONTINUE;
2188         }
2189
2190         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2191                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2192                            "session overlap");
2193                 wps->state = SEND_WSC_NACK;
2194                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2195                 return WPS_CONTINUE;
2196         }
2197
2198         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2199             wps_process_authenticator(wps, attr->authenticator, msg)) {
2200                 wps->state = SEND_WSC_NACK;
2201                 return WPS_CONTINUE;
2202         }
2203
2204         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2205                                               attr->encr_settings_len);
2206         if (decrypted == NULL) {
2207                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
2208                            "Settings attribute");
2209                 wps->state = SEND_WSC_NACK;
2210                 return WPS_CONTINUE;
2211         }
2212
2213         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2214                    "attribute");
2215         if (wps_parse_msg(decrypted, &eattr) < 0 ||
2216             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2217             wps_process_e_snonce1(wps, eattr.e_snonce1)) {
2218                 wpabuf_free(decrypted);
2219                 wps->state = SEND_WSC_NACK;
2220                 return WPS_CONTINUE;
2221         }
2222         wpabuf_free(decrypted);
2223
2224         wps->state = SEND_M6;
2225         return WPS_CONTINUE;
2226 }
2227
2228
2229 static void wps_sta_cred_cb(struct wps_data *wps)
2230 {
2231         /*
2232          * Update credential to only include a single authentication and
2233          * encryption type in case the AP configuration includes more than one
2234          * option.
2235          */
2236         if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
2237                 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
2238         else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
2239                 wps->cred.auth_type = WPS_AUTH_WPAPSK;
2240         if (wps->cred.encr_type & WPS_ENCR_AES)
2241                 wps->cred.encr_type = WPS_ENCR_AES;
2242         else if (wps->cred.encr_type & WPS_ENCR_TKIP)
2243                 wps->cred.encr_type = WPS_ENCR_TKIP;
2244         wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
2245                    "AP configuration");
2246         if (wps->wps->cred_cb)
2247                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
2248 }
2249
2250
2251 static void wps_cred_update(struct wps_credential *dst,
2252                             struct wps_credential *src)
2253 {
2254         os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
2255         dst->ssid_len = src->ssid_len;
2256         dst->auth_type = src->auth_type;
2257         dst->encr_type = src->encr_type;
2258         dst->key_idx = src->key_idx;
2259         os_memcpy(dst->key, src->key, sizeof(dst->key));
2260         dst->key_len = src->key_len;
2261 }
2262
2263
2264 static int wps_process_ap_settings_r(struct wps_data *wps,
2265                                      struct wps_parse_attr *attr)
2266 {
2267         if (wps->wps->ap || wps->er)
2268                 return 0;
2269
2270         /* AP Settings Attributes in M7 when Enrollee is an AP */
2271         if (wps_process_ap_settings(attr, &wps->cred) < 0)
2272                 return -1;
2273
2274         wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
2275
2276         if (wps->new_ap_settings) {
2277                 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
2278                            "new settings");
2279                 wps_cred_update(&wps->cred, wps->new_ap_settings);
2280                 return 0;
2281         } else {
2282                 /*
2283                  * Use the AP PIN only to receive the current AP settings, not
2284                  * to reconfigure the AP.
2285                  */
2286                 if (wps->ap_settings_cb) {
2287                         wps->ap_settings_cb(wps->ap_settings_cb_ctx,
2288                                             &wps->cred);
2289                         return 1;
2290                 }
2291                 wps_sta_cred_cb(wps);
2292                 return 1;
2293         }
2294 }
2295
2296
2297 static enum wps_process_res wps_process_m7(struct wps_data *wps,
2298                                            const struct wpabuf *msg,
2299                                            struct wps_parse_attr *attr)
2300 {
2301         struct wpabuf *decrypted;
2302         struct wps_parse_attr eattr;
2303
2304         wpa_printf(MSG_DEBUG, "WPS: Received M7");
2305
2306         if (wps->state != RECV_M7) {
2307                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2308                            "receiving M7", wps->state);
2309                 wps->state = SEND_WSC_NACK;
2310                 return WPS_CONTINUE;
2311         }
2312
2313         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
2314                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
2315                            "session overlap");
2316                 wps->state = SEND_WSC_NACK;
2317                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
2318                 return WPS_CONTINUE;
2319         }
2320
2321         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
2322             wps_process_authenticator(wps, attr->authenticator, msg)) {
2323                 wps->state = SEND_WSC_NACK;
2324                 return WPS_CONTINUE;
2325         }
2326
2327         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
2328                                               attr->encr_settings_len);
2329         if (decrypted == NULL) {
2330                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
2331                            "Settings attribute");
2332                 wps->state = SEND_WSC_NACK;
2333                 return WPS_CONTINUE;
2334         }
2335
2336         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
2337                    "attribute");
2338         if (wps_parse_msg(decrypted, &eattr) < 0 ||
2339             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
2340             wps_process_e_snonce2(wps, eattr.e_snonce2) ||
2341             wps_process_ap_settings_r(wps, &eattr)) {
2342                 wpabuf_free(decrypted);
2343                 wps->state = SEND_WSC_NACK;
2344                 return WPS_CONTINUE;
2345         }
2346
2347         wpabuf_free(decrypted);
2348
2349         wps->state = SEND_M8;
2350         return WPS_CONTINUE;
2351 }
2352
2353
2354 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
2355                                                 const struct wpabuf *msg)
2356 {
2357         struct wps_parse_attr attr;
2358         enum wps_process_res ret = WPS_CONTINUE;
2359
2360         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
2361
2362         if (wps_parse_msg(msg, &attr) < 0)
2363                 return WPS_FAILURE;
2364
2365         if (!wps_version_supported(attr.version)) {
2366                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2367                            attr.version ? *attr.version : 0);
2368                 return WPS_FAILURE;
2369         }
2370
2371         if (attr.msg_type == NULL) {
2372                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2373                 return WPS_FAILURE;
2374         }
2375
2376         if (*attr.msg_type != WPS_M1 &&
2377             (attr.registrar_nonce == NULL ||
2378              os_memcmp(wps->nonce_r, attr.registrar_nonce,
2379                        WPS_NONCE_LEN != 0))) {
2380                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2381                 return WPS_FAILURE;
2382         }
2383
2384         switch (*attr.msg_type) {
2385         case WPS_M1:
2386 #ifdef CONFIG_WPS_UPNP
2387                 if (wps->wps->wps_upnp && attr.mac_addr) {
2388                         /* Remove old pending messages when starting new run */
2389                         wps_free_pending_msgs(wps->wps->upnp_msgs);
2390                         wps->wps->upnp_msgs = NULL;
2391
2392                         upnp_wps_device_send_wlan_event(
2393                                 wps->wps->wps_upnp, attr.mac_addr,
2394                                 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
2395                 }
2396 #endif /* CONFIG_WPS_UPNP */
2397                 ret = wps_process_m1(wps, &attr);
2398                 break;
2399         case WPS_M3:
2400                 ret = wps_process_m3(wps, msg, &attr);
2401                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2402                         wps_fail_event(wps->wps, WPS_M3);
2403                 break;
2404         case WPS_M5:
2405                 ret = wps_process_m5(wps, msg, &attr);
2406                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2407                         wps_fail_event(wps->wps, WPS_M5);
2408                 break;
2409         case WPS_M7:
2410                 ret = wps_process_m7(wps, msg, &attr);
2411                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
2412                         wps_fail_event(wps->wps, WPS_M7);
2413                 break;
2414         default:
2415                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
2416                            *attr.msg_type);
2417                 return WPS_FAILURE;
2418         }
2419
2420         if (ret == WPS_CONTINUE) {
2421                 /* Save a copy of the last message for Authenticator derivation
2422                  */
2423                 wpabuf_free(wps->last_msg);
2424                 wps->last_msg = wpabuf_dup(msg);
2425         }
2426
2427         return ret;
2428 }
2429
2430
2431 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
2432                                                 const struct wpabuf *msg)
2433 {
2434         struct wps_parse_attr attr;
2435
2436         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
2437
2438         if (wps_parse_msg(msg, &attr) < 0)
2439                 return WPS_FAILURE;
2440
2441         if (!wps_version_supported(attr.version)) {
2442                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2443                            attr.version ? *attr.version : 0);
2444                 return WPS_FAILURE;
2445         }
2446
2447         if (attr.msg_type == NULL) {
2448                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2449                 return WPS_FAILURE;
2450         }
2451
2452         if (*attr.msg_type != WPS_WSC_ACK) {
2453                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2454                            *attr.msg_type);
2455                 return WPS_FAILURE;
2456         }
2457
2458 #ifdef CONFIG_WPS_UPNP
2459         if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
2460             upnp_wps_subscribers(wps->wps->wps_upnp)) {
2461                 if (wps->wps->upnp_msgs)
2462                         return WPS_CONTINUE;
2463                 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2464                            "external Registrar");
2465                 return WPS_PENDING;
2466         }
2467 #endif /* CONFIG_WPS_UPNP */
2468
2469         if (attr.registrar_nonce == NULL ||
2470             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2471         {
2472                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2473                 return WPS_FAILURE;
2474         }
2475
2476         if (attr.enrollee_nonce == NULL ||
2477             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2478                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2479                 return WPS_FAILURE;
2480         }
2481
2482         if (wps->state == RECV_M2D_ACK) {
2483 #ifdef CONFIG_WPS_UPNP
2484                 if (wps->wps->wps_upnp &&
2485                     upnp_wps_subscribers(wps->wps->wps_upnp)) {
2486                         if (wps->wps->upnp_msgs)
2487                                 return WPS_CONTINUE;
2488                         if (wps->ext_reg == 0)
2489                                 wps->ext_reg = 1;
2490                         wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
2491                                    "external Registrar");
2492                         return WPS_PENDING;
2493                 }
2494 #endif /* CONFIG_WPS_UPNP */
2495
2496                 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
2497                            "terminate negotiation");
2498         }
2499
2500         return WPS_FAILURE;
2501 }
2502
2503
2504 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
2505                                                  const struct wpabuf *msg)
2506 {
2507         struct wps_parse_attr attr;
2508         int old_state;
2509
2510         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
2511
2512         old_state = wps->state;
2513         wps->state = SEND_WSC_NACK;
2514
2515         if (wps_parse_msg(msg, &attr) < 0)
2516                 return WPS_FAILURE;
2517
2518         if (!wps_version_supported(attr.version)) {
2519                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2520                            attr.version ? *attr.version : 0);
2521                 return WPS_FAILURE;
2522         }
2523
2524         if (attr.msg_type == NULL) {
2525                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2526                 return WPS_FAILURE;
2527         }
2528
2529         if (*attr.msg_type != WPS_WSC_NACK) {
2530                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2531                            *attr.msg_type);
2532                 return WPS_FAILURE;
2533         }
2534
2535 #ifdef CONFIG_WPS_UPNP
2536         if (wps->wps->wps_upnp && wps->ext_reg) {
2537                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2538                            "Registrar terminated by the Enrollee");
2539                 return WPS_FAILURE;
2540         }
2541 #endif /* CONFIG_WPS_UPNP */
2542
2543         if (attr.registrar_nonce == NULL ||
2544             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2545         {
2546                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2547                 return WPS_FAILURE;
2548         }
2549
2550         if (attr.enrollee_nonce == NULL ||
2551             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2552                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2553                 return WPS_FAILURE;
2554         }
2555
2556         if (attr.config_error == NULL) {
2557                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
2558                            "in WSC_NACK");
2559                 return WPS_FAILURE;
2560         }
2561
2562         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
2563                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
2564
2565         switch (old_state) {
2566         case RECV_M3:
2567                 wps_fail_event(wps->wps, WPS_M2);
2568                 break;
2569         case RECV_M5:
2570                 wps_fail_event(wps->wps, WPS_M4);
2571                 break;
2572         case RECV_M7:
2573                 wps_fail_event(wps->wps, WPS_M6);
2574                 break;
2575         case RECV_DONE:
2576                 wps_fail_event(wps->wps, WPS_M8);
2577                 break;
2578         default:
2579                 break;
2580         }
2581
2582         return WPS_FAILURE;
2583 }
2584
2585
2586 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
2587                                                  const struct wpabuf *msg)
2588 {
2589         struct wps_parse_attr attr;
2590
2591         wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
2592
2593         if (wps->state != RECV_DONE &&
2594             (!wps->wps->wps_upnp || !wps->ext_reg)) {
2595                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
2596                            "receiving WSC_Done", wps->state);
2597                 return WPS_FAILURE;
2598         }
2599
2600         if (wps_parse_msg(msg, &attr) < 0)
2601                 return WPS_FAILURE;
2602
2603         if (!wps_version_supported(attr.version)) {
2604                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
2605                            attr.version ? *attr.version : 0);
2606                 return WPS_FAILURE;
2607         }
2608
2609         if (attr.msg_type == NULL) {
2610                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
2611                 return WPS_FAILURE;
2612         }
2613
2614         if (*attr.msg_type != WPS_WSC_DONE) {
2615                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
2616                            *attr.msg_type);
2617                 return WPS_FAILURE;
2618         }
2619
2620 #ifdef CONFIG_WPS_UPNP
2621         if (wps->wps->wps_upnp && wps->ext_reg) {
2622                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
2623                            "Registrar completed successfully");
2624                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
2625                                  wps->uuid_e);
2626                 return WPS_DONE;
2627         }
2628 #endif /* CONFIG_WPS_UPNP */
2629
2630         if (attr.registrar_nonce == NULL ||
2631             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
2632         {
2633                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
2634                 return WPS_FAILURE;
2635         }
2636
2637         if (attr.enrollee_nonce == NULL ||
2638             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
2639                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
2640                 return WPS_FAILURE;
2641         }
2642
2643         wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
2644         wps_device_store(wps->wps->registrar, &wps->peer_dev,
2645                          wps->uuid_e);
2646
2647         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
2648             wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
2649                 struct wps_credential cred;
2650
2651                 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
2652                            "on first Enrollee connection");
2653
2654                 os_memset(&cred, 0, sizeof(cred));
2655                 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
2656                 cred.ssid_len = wps->wps->ssid_len;
2657                 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
2658                 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
2659                 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
2660                 cred.key_len = wps->new_psk_len;
2661
2662                 wps->wps->wps_state = WPS_STATE_CONFIGURED;
2663                 wpa_hexdump_ascii_key(MSG_DEBUG,
2664                                       "WPS: Generated random passphrase",
2665                                       wps->new_psk, wps->new_psk_len);
2666                 if (wps->wps->cred_cb)
2667                         wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
2668
2669                 os_free(wps->new_psk);
2670                 wps->new_psk = NULL;
2671         }
2672
2673         if (!wps->wps->ap && !wps->er)
2674                 wps_sta_cred_cb(wps);
2675
2676         if (wps->new_psk) {
2677                 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
2678                                    wps->new_psk, wps->new_psk_len)) {
2679                         wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
2680                                    "new PSK");
2681                 }
2682                 os_free(wps->new_psk);
2683                 wps->new_psk = NULL;
2684         }
2685
2686         wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
2687
2688         if (wps->pbc) {
2689                 wps_registrar_remove_pbc_session(wps->wps->registrar,
2690                                                  wps->mac_addr_e, wps->uuid_e);
2691                 wps_registrar_pbc_completed(wps->wps->registrar);
2692         } else {
2693                 wps_registrar_pin_completed(wps->wps->registrar);
2694         }
2695
2696         wps_success_event(wps->wps);
2697
2698         return WPS_DONE;
2699 }
2700
2701
2702 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
2703                                                enum wsc_op_code op_code,
2704                                                const struct wpabuf *msg)
2705 {
2706         enum wps_process_res ret;
2707
2708         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
2709                    "op_code=%d)",
2710                    (unsigned long) wpabuf_len(msg), op_code);
2711
2712 #ifdef CONFIG_WPS_UPNP
2713         if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
2714                 struct wps_parse_attr attr;
2715                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
2716                     *attr.msg_type == WPS_M3)
2717                         wps->ext_reg = 2; /* past M2/M2D phase */
2718         }
2719         if (wps->ext_reg > 1)
2720                 wps_registrar_free_pending_m2(wps->wps);
2721         if (wps->wps->wps_upnp && wps->ext_reg &&
2722             wps->wps->upnp_msgs == NULL &&
2723             (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
2724         {
2725                 struct wps_parse_attr attr;
2726                 int type;
2727                 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
2728                         type = -1;
2729                 else
2730                         type = *attr.msg_type;
2731                 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
2732                            " to external Registrar for processing", type);
2733                 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
2734                                                 wps->mac_addr_e,
2735                                                 UPNP_WPS_WLANEVENT_TYPE_EAP,
2736                                                 msg);
2737                 if (op_code == WSC_MSG)
2738                         return WPS_PENDING;
2739         } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
2740                 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
2741                            "external Registrar");
2742                 return WPS_CONTINUE;
2743         }
2744 #endif /* CONFIG_WPS_UPNP */
2745
2746         switch (op_code) {
2747         case WSC_MSG:
2748                 return wps_process_wsc_msg(wps, msg);
2749         case WSC_ACK:
2750                 return wps_process_wsc_ack(wps, msg);
2751         case WSC_NACK:
2752                 return wps_process_wsc_nack(wps, msg);
2753         case WSC_Done:
2754                 ret = wps_process_wsc_done(wps, msg);
2755                 if (ret == WPS_FAILURE) {
2756                         wps->state = SEND_WSC_NACK;
2757                         wps_fail_event(wps->wps, WPS_WSC_DONE);
2758                 }
2759                 return ret;
2760         default:
2761                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
2762                 return WPS_FAILURE;
2763         }
2764 }
2765
2766
2767 int wps_registrar_update_ie(struct wps_registrar *reg)
2768 {
2769         return wps_set_ie(reg);
2770 }
2771
2772
2773 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
2774                                                void *timeout_ctx)
2775 {
2776         struct wps_registrar *reg = eloop_ctx;
2777
2778         wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
2779                    "unselect internal Registrar");
2780         reg->selected_registrar = 0;
2781         reg->pbc = 0;
2782         wps_registrar_selected_registrar_changed(reg);
2783 }
2784
2785
2786 #ifdef CONFIG_WPS_UPNP
2787 static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
2788                                       struct subscription *s)
2789 {
2790         wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
2791                    "config_methods=0x%x)",
2792                    s->dev_password_id, s->config_methods);
2793         reg->sel_reg_union = 1;
2794         if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
2795                 reg->sel_reg_dev_password_id_override = s->dev_password_id;
2796         if (reg->sel_reg_config_methods_override == -1)
2797                 reg->sel_reg_config_methods_override = 0;
2798         reg->sel_reg_config_methods_override |= s->config_methods;
2799 }
2800 #endif /* CONFIG_WPS_UPNP */
2801
2802
2803 static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
2804 {
2805 #ifdef CONFIG_WPS_UPNP
2806         struct subscription *s;
2807
2808         if (reg->wps->wps_upnp == NULL)
2809                 return;
2810
2811         dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
2812                          struct subscription, list) {
2813                 struct subscr_addr *sa;
2814                 sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
2815                 if (sa) {
2816                         wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
2817                                    inet_ntoa(sa->saddr.sin_addr),
2818                                    ntohs(sa->saddr.sin_port));
2819                 }
2820                 if (s->selected_registrar)
2821                         wps_registrar_sel_reg_add(reg, s);
2822                 else
2823                         wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
2824                                    "selected");
2825         }
2826 #endif /* CONFIG_WPS_UPNP */
2827 }
2828
2829
2830 /**
2831  * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
2832  * @reg: Registrar data from wps_registrar_init()
2833  *
2834  * This function is called when selected registrar state changes, e.g., when an
2835  * AP receives a SetSelectedRegistrar UPnP message.
2836  */
2837 void wps_registrar_selected_registrar_changed(struct wps_registrar *reg)
2838 {
2839         wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
2840
2841         reg->sel_reg_union = reg->selected_registrar;
2842         reg->sel_reg_dev_password_id_override = -1;
2843         reg->sel_reg_config_methods_override = -1;
2844         if (reg->selected_registrar) {
2845                 reg->sel_reg_config_methods_override =
2846                         reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
2847                 if (reg->pbc) {
2848                         reg->sel_reg_dev_password_id_override =
2849                                 DEV_PW_PUSHBUTTON;
2850                         reg->sel_reg_config_methods_override |=
2851                                 WPS_CONFIG_PUSHBUTTON;
2852                 }
2853                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
2854                            "(pbc=%d)", reg->pbc);
2855         } else
2856                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
2857
2858         wps_registrar_sel_reg_union(reg);
2859
2860         wps_set_ie(reg);
2861         wps_cb_set_sel_reg(reg);
2862 }
2863
2864
2865 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
2866                            char *buf, size_t buflen)
2867 {
2868         struct wps_registrar_device *d;
2869         int len = 0, ret;
2870         char uuid[40];
2871         char devtype[WPS_DEV_TYPE_BUFSIZE];
2872
2873         d = wps_device_get(reg, addr);
2874         if (d == NULL)
2875                 return 0;
2876         if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
2877                 return 0;
2878
2879         ret = os_snprintf(buf + len, buflen - len,
2880                           "wpsUuid=%s\n"
2881                           "wpsPrimaryDeviceType=%s\n"
2882                           "wpsDeviceName=%s\n"
2883                           "wpsManufacturer=%s\n"
2884                           "wpsModelName=%s\n"
2885                           "wpsModelNumber=%s\n"
2886                           "wpsSerialNumber=%s\n",
2887                           uuid,
2888                           wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
2889                                                sizeof(devtype)),
2890                           d->dev.device_name ? d->dev.device_name : "",
2891                           d->dev.manufacturer ? d->dev.manufacturer : "",
2892                           d->dev.model_name ? d->dev.model_name : "",
2893                           d->dev.model_number ? d->dev.model_number : "",
2894                           d->dev.serial_number ? d->dev.serial_number : "");
2895         if (ret < 0 || (size_t) ret >= buflen - len)
2896                 return len;
2897         len += ret;
2898
2899         return len;
2900 }