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