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