LCOV - code coverage report
Current view: top level - src/wps - wps_registrar.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1475438200 Lines: 1784 1971 90.5 %
Date: 2016-10-02 Functions: 114 114 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Wi-Fi Protected Setup - Registrar
       3             :  * Copyright (c) 2008-2016, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : 
      11             : #include "utils/common.h"
      12             : #include "utils/base64.h"
      13             : #include "utils/eloop.h"
      14             : #include "utils/uuid.h"
      15             : #include "utils/list.h"
      16             : #include "crypto/crypto.h"
      17             : #include "crypto/sha256.h"
      18             : #include "crypto/random.h"
      19             : #include "common/ieee802_11_defs.h"
      20             : #include "wps_i.h"
      21             : #include "wps_dev_attr.h"
      22             : #include "wps_upnp.h"
      23             : #include "wps_upnp_i.h"
      24             : 
      25             : #ifndef CONFIG_WPS_STRICT
      26             : #define WPS_WORKAROUNDS
      27             : #endif /* CONFIG_WPS_STRICT */
      28             : 
      29             : #ifdef CONFIG_WPS_NFC
      30             : 
      31             : struct wps_nfc_pw_token {
      32             :         struct dl_list list;
      33             :         u8 pubkey_hash[WPS_OOB_PUBKEY_HASH_LEN];
      34             :         unsigned int peer_pk_hash_known:1;
      35             :         u16 pw_id;
      36             :         u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN * 2 + 1];
      37             :         size_t dev_pw_len;
      38             :         int pk_hash_provided_oob; /* whether own PK hash was provided OOB */
      39             : };
      40             : 
      41             : 
      42           2 : static void wps_remove_nfc_pw_token(struct wps_nfc_pw_token *token)
      43             : {
      44           2 :         dl_list_del(&token->list);
      45           2 :         bin_clear_free(token, sizeof(*token));
      46           2 : }
      47             : 
      48             : 
      49        7491 : static void wps_free_nfc_pw_tokens(struct dl_list *tokens, u16 pw_id)
      50             : {
      51             :         struct wps_nfc_pw_token *token, *prev;
      52        7493 :         dl_list_for_each_safe(token, prev, tokens, struct wps_nfc_pw_token,
      53             :                               list) {
      54           2 :                 if (pw_id == 0 || pw_id == token->pw_id)
      55           2 :                         wps_remove_nfc_pw_token(token);
      56             :         }
      57        7491 : }
      58             : 
      59             : 
      60          36 : static struct wps_nfc_pw_token * wps_get_nfc_pw_token(struct dl_list *tokens,
      61             :                                                       u16 pw_id)
      62             : {
      63             :         struct wps_nfc_pw_token *token;
      64          36 :         dl_list_for_each(token, tokens, struct wps_nfc_pw_token, list) {
      65          30 :                 if (pw_id == token->pw_id)
      66          30 :                         return token;
      67             :         }
      68           6 :         return NULL;
      69             : }
      70             : 
      71             : #else /* CONFIG_WPS_NFC */
      72             : 
      73             : #define wps_free_nfc_pw_tokens(t, p) do { } while (0)
      74             : 
      75             : #endif /* CONFIG_WPS_NFC */
      76             : 
      77             : 
      78             : struct wps_uuid_pin {
      79             :         struct dl_list list;
      80             :         u8 uuid[WPS_UUID_LEN];
      81             :         int wildcard_uuid;
      82             :         u8 *pin;
      83             :         size_t pin_len;
      84             : #define PIN_LOCKED BIT(0)
      85             : #define PIN_EXPIRES BIT(1)
      86             :         int flags;
      87             :         struct os_reltime expiration;
      88             :         u8 enrollee_addr[ETH_ALEN];
      89             : };
      90             : 
      91             : 
      92         398 : static void wps_free_pin(struct wps_uuid_pin *pin)
      93             : {
      94         398 :         bin_clear_free(pin->pin, pin->pin_len);
      95         398 :         os_free(pin);
      96         398 : }
      97             : 
      98             : 
      99         398 : static void wps_remove_pin(struct wps_uuid_pin *pin)
     100             : {
     101         398 :         dl_list_del(&pin->list);
     102         398 :         wps_free_pin(pin);
     103         398 : }
     104             : 
     105             : 
     106        7461 : static void wps_free_pins(struct dl_list *pins)
     107             : {
     108             :         struct wps_uuid_pin *pin, *prev;
     109        7562 :         dl_list_for_each_safe(pin, prev, pins, struct wps_uuid_pin, list)
     110         101 :                 wps_remove_pin(pin);
     111        7461 : }
     112             : 
     113             : 
     114             : struct wps_pbc_session {
     115             :         struct wps_pbc_session *next;
     116             :         u8 addr[ETH_ALEN];
     117             :         u8 uuid_e[WPS_UUID_LEN];
     118             :         struct os_reltime timestamp;
     119             : };
     120             : 
     121             : 
     122        7461 : static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
     123             : {
     124             :         struct wps_pbc_session *prev;
     125             : 
     126       14987 :         while (pbc) {
     127          65 :                 prev = pbc;
     128          65 :                 pbc = pbc->next;
     129          65 :                 os_free(prev);
     130             :         }
     131        7461 : }
     132             : 
     133             : 
     134             : struct wps_registrar_device {
     135             :         struct wps_registrar_device *next;
     136             :         struct wps_device_data dev;
     137             :         u8 uuid[WPS_UUID_LEN];
     138             : };
     139             : 
     140             : 
     141             : struct wps_registrar {
     142             :         struct wps_context *wps;
     143             : 
     144             :         int pbc;
     145             :         int selected_registrar;
     146             : 
     147             :         int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
     148             :                           const u8 *psk, size_t psk_len);
     149             :         int (*set_ie_cb)(void *ctx, struct wpabuf *beacon_ie,
     150             :                          struct wpabuf *probe_resp_ie);
     151             :         void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
     152             :                               const struct wps_device_data *dev);
     153             :         void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
     154             :                                const u8 *uuid_e, const u8 *dev_pw,
     155             :                                size_t dev_pw_len);
     156             :         void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
     157             :                                u16 sel_reg_config_methods);
     158             :         void (*enrollee_seen_cb)(void *ctx, const u8 *addr, const u8 *uuid_e,
     159             :                                  const u8 *pri_dev_type, u16 config_methods,
     160             :                                  u16 dev_password_id, u8 request_type,
     161             :                                  const char *dev_name);
     162             :         void *cb_ctx;
     163             : 
     164             :         struct dl_list pins;
     165             :         struct dl_list nfc_pw_tokens;
     166             :         struct wps_pbc_session *pbc_sessions;
     167             : 
     168             :         int skip_cred_build;
     169             :         struct wpabuf *extra_cred;
     170             :         int disable_auto_conf;
     171             :         int sel_reg_union;
     172             :         int sel_reg_dev_password_id_override;
     173             :         int sel_reg_config_methods_override;
     174             :         int static_wep_only;
     175             :         int dualband;
     176             :         int force_per_enrollee_psk;
     177             : 
     178             :         struct wps_registrar_device *devices;
     179             : 
     180             :         int force_pbc_overlap;
     181             : 
     182             :         u8 authorized_macs[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
     183             :         u8 authorized_macs_union[WPS_MAX_AUTHORIZED_MACS][ETH_ALEN];
     184             : 
     185             :         u8 p2p_dev_addr[ETH_ALEN];
     186             : 
     187             :         u8 pbc_ignore_uuid[WPS_UUID_LEN];
     188             : #ifdef WPS_WORKAROUNDS
     189             :         struct os_reltime pbc_ignore_start;
     190             : #endif /* WPS_WORKAROUNDS */
     191             : };
     192             : 
     193             : 
     194             : static int wps_set_ie(struct wps_registrar *reg);
     195             : static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
     196             : static void wps_registrar_set_selected_timeout(void *eloop_ctx,
     197             :                                                void *timeout_ctx);
     198             : static void wps_registrar_remove_pin(struct wps_registrar *reg,
     199             :                                      struct wps_uuid_pin *pin);
     200             : 
     201             : 
     202         552 : static void wps_registrar_add_authorized_mac(struct wps_registrar *reg,
     203             :                                              const u8 *addr)
     204             : {
     205             :         int i;
     206        3312 :         wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC " MACSTR,
     207        3312 :                    MAC2STR(addr));
     208        3167 :         for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
     209        2644 :                 if (os_memcmp(reg->authorized_macs[i], addr, ETH_ALEN) == 0) {
     210          29 :                         wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was "
     211             :                                    "already in the list");
     212         581 :                         return; /* already in list */
     213             :                 }
     214        2615 :         for (i = WPS_MAX_AUTHORIZED_MACS - 1; i > 0; i--)
     215        2092 :                 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i - 1],
     216             :                           ETH_ALEN);
     217         523 :         os_memcpy(reg->authorized_macs[0], addr, ETH_ALEN);
     218         523 :         wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
     219         523 :                     (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
     220             : }
     221             : 
     222             : 
     223         388 : static void wps_registrar_remove_authorized_mac(struct wps_registrar *reg,
     224             :                                                 const u8 *addr)
     225             : {
     226             :         int i;
     227        2328 :         wpa_printf(MSG_DEBUG, "WPS: Remove authorized MAC " MACSTR,
     228        2328 :                    MAC2STR(addr));
     229         398 :         for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++) {
     230         396 :                 if (os_memcmp(reg->authorized_macs, addr, ETH_ALEN) == 0)
     231         386 :                         break;
     232             :         }
     233         388 :         if (i == WPS_MAX_AUTHORIZED_MACS) {
     234           2 :                 wpa_printf(MSG_DEBUG, "WPS: Authorized MAC was not in the "
     235             :                            "list");
     236         390 :                 return; /* not in the list */
     237             :         }
     238        1930 :         for (; i + 1 < WPS_MAX_AUTHORIZED_MACS; i++)
     239        1544 :                 os_memcpy(reg->authorized_macs[i], reg->authorized_macs[i + 1],
     240             :                           ETH_ALEN);
     241         386 :         os_memset(reg->authorized_macs[WPS_MAX_AUTHORIZED_MACS - 1], 0,
     242             :                   ETH_ALEN);
     243         386 :         wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs",
     244         386 :                     (u8 *) reg->authorized_macs, sizeof(reg->authorized_macs));
     245             : }
     246             : 
     247             : 
     248        7461 : static void wps_free_devices(struct wps_registrar_device *dev)
     249             : {
     250             :         struct wps_registrar_device *prev;
     251             : 
     252       15285 :         while (dev) {
     253         363 :                 prev = dev;
     254         363 :                 dev = dev->next;
     255         363 :                 wps_device_data_free(&prev->dev);
     256         363 :                 os_free(prev);
     257             :         }
     258        7461 : }
     259             : 
     260             : 
     261         382 : static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
     262             :                                                     const u8 *addr)
     263             : {
     264             :         struct wps_registrar_device *dev;
     265             : 
     266         450 :         for (dev = reg->devices; dev; dev = dev->next) {
     267          84 :                 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
     268          16 :                         return dev;
     269             :         }
     270         366 :         return NULL;
     271             : }
     272             : 
     273             : 
     274         375 : static void wps_device_clone_data(struct wps_device_data *dst,
     275             :                                   struct wps_device_data *src)
     276             : {
     277         375 :         os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
     278         375 :         os_memcpy(dst->pri_dev_type, src->pri_dev_type, WPS_DEV_TYPE_LEN);
     279             : 
     280             : #define WPS_STRDUP(n) \
     281             :         os_free(dst->n); \
     282             :         dst->n = src->n ? os_strdup(src->n) : NULL
     283             : 
     284         375 :         WPS_STRDUP(device_name);
     285         375 :         WPS_STRDUP(manufacturer);
     286         375 :         WPS_STRDUP(model_name);
     287         375 :         WPS_STRDUP(model_number);
     288         375 :         WPS_STRDUP(serial_number);
     289             : #undef WPS_STRDUP
     290         375 : }
     291             : 
     292             : 
     293         375 : int wps_device_store(struct wps_registrar *reg,
     294             :                      struct wps_device_data *dev, const u8 *uuid)
     295             : {
     296             :         struct wps_registrar_device *d;
     297             : 
     298         375 :         d = wps_device_get(reg, dev->mac_addr);
     299         375 :         if (d == NULL) {
     300         363 :                 d = os_zalloc(sizeof(*d));
     301         363 :                 if (d == NULL)
     302           0 :                         return -1;
     303         363 :                 d->next = reg->devices;
     304         363 :                 reg->devices = d;
     305             :         }
     306             : 
     307         375 :         wps_device_clone_data(&d->dev, dev);
     308         375 :         os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
     309             : 
     310         375 :         return 0;
     311             : }
     312             : 
     313             : 
     314         226 : static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
     315             :                                           const u8 *addr, const u8 *uuid_e)
     316             : {
     317         226 :         struct wps_pbc_session *pbc, *prev = NULL;
     318             :         struct os_reltime now;
     319             : 
     320         226 :         os_get_reltime(&now);
     321             : 
     322         226 :         pbc = reg->pbc_sessions;
     323         457 :         while (pbc) {
     324         217 :                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
     325         106 :                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
     326         106 :                         if (prev)
     327           0 :                                 prev->next = pbc->next;
     328             :                         else
     329         106 :                                 reg->pbc_sessions = pbc->next;
     330         106 :                         break;
     331             :                 }
     332           5 :                 prev = pbc;
     333           5 :                 pbc = pbc->next;
     334             :         }
     335             : 
     336         226 :         if (!pbc) {
     337         120 :                 pbc = os_zalloc(sizeof(*pbc));
     338         120 :                 if (pbc == NULL)
     339         226 :                         return;
     340         120 :                 os_memcpy(pbc->addr, addr, ETH_ALEN);
     341         120 :                 if (uuid_e)
     342         120 :                         os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
     343             :         }
     344             : 
     345         226 :         pbc->next = reg->pbc_sessions;
     346         226 :         reg->pbc_sessions = pbc;
     347         226 :         pbc->timestamp = now;
     348             : 
     349             :         /* remove entries that have timed out */
     350         226 :         prev = pbc;
     351         226 :         pbc = pbc->next;
     352             : 
     353         458 :         while (pbc) {
     354           6 :                 if (os_reltime_expired(&now, &pbc->timestamp,
     355             :                                        WPS_PBC_WALK_TIME)) {
     356           0 :                         prev->next = NULL;
     357           0 :                         wps_free_pbc_sessions(pbc);
     358           0 :                         break;
     359             :                 }
     360           6 :                 prev = pbc;
     361           6 :                 pbc = pbc->next;
     362             :         }
     363             : }
     364             : 
     365             : 
     366          54 : static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
     367             :                                              const u8 *uuid_e,
     368             :                                              const u8 *p2p_dev_addr)
     369             : {
     370          54 :         struct wps_pbc_session *pbc, *prev = NULL, *tmp;
     371             : 
     372          54 :         pbc = reg->pbc_sessions;
     373         163 :         while (pbc) {
     374          55 :                 if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 ||
     375           2 :                     (p2p_dev_addr && !is_zero_ether_addr(reg->p2p_dev_addr) &&
     376           1 :                      os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN) ==
     377             :                      0)) {
     378          55 :                         if (prev)
     379           0 :                                 prev->next = pbc->next;
     380             :                         else
     381          55 :                                 reg->pbc_sessions = pbc->next;
     382          55 :                         tmp = pbc;
     383          55 :                         pbc = pbc->next;
     384         330 :                         wpa_printf(MSG_DEBUG, "WPS: Removing PBC session for "
     385         330 :                                    "addr=" MACSTR, MAC2STR(tmp->addr));
     386          55 :                         wpa_hexdump(MSG_DEBUG, "WPS: Removed UUID-E",
     387          55 :                                     tmp->uuid_e, WPS_UUID_LEN);
     388          55 :                         os_free(tmp);
     389          55 :                         continue;
     390             :                 }
     391           0 :                 prev = pbc;
     392           0 :                 pbc = pbc->next;
     393             :         }
     394          54 : }
     395             : 
     396             : 
     397         337 : int wps_registrar_pbc_overlap(struct wps_registrar *reg,
     398             :                               const u8 *addr, const u8 *uuid_e)
     399             : {
     400         337 :         int count = 0;
     401             :         struct wps_pbc_session *pbc;
     402         337 :         struct wps_pbc_session *first = NULL;
     403             :         struct os_reltime now;
     404             : 
     405         337 :         os_get_reltime(&now);
     406             : 
     407         337 :         wpa_printf(MSG_DEBUG, "WPS: Checking active PBC sessions for overlap");
     408             : 
     409         337 :         if (uuid_e) {
     410         227 :                 wpa_printf(MSG_DEBUG, "WPS: Add one for the requested UUID");
     411         227 :                 wpa_hexdump(MSG_DEBUG, "WPS: Requested UUID",
     412             :                             uuid_e, WPS_UUID_LEN);
     413         227 :                 count++;
     414             :         }
     415             : 
     416         576 :         for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
     417        1434 :                 wpa_printf(MSG_DEBUG, "WPS: Consider PBC session with " MACSTR,
     418        1434 :                            MAC2STR(pbc->addr));
     419         239 :                 wpa_hexdump(MSG_DEBUG, "WPS: UUID-E",
     420         239 :                             pbc->uuid_e, WPS_UUID_LEN);
     421         239 :                 if (os_reltime_expired(&now, &pbc->timestamp,
     422             :                                        WPS_PBC_WALK_TIME)) {
     423           0 :                         wpa_printf(MSG_DEBUG, "WPS: PBC walk time has expired");
     424           0 :                         break;
     425             :                 }
     426         248 :                 if (first &&
     427           9 :                     os_memcmp(pbc->uuid_e, first->uuid_e, WPS_UUID_LEN) == 0) {
     428           0 :                         wpa_printf(MSG_DEBUG, "WPS: Same Enrollee");
     429           0 :                         continue; /* same Enrollee */
     430             :                 }
     431         464 :                 if (uuid_e == NULL ||
     432         225 :                     os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN)) {
     433          19 :                         wpa_printf(MSG_DEBUG, "WPS: New Enrollee");
     434          19 :                         count++;
     435             :                 }
     436         239 :                 if (first == NULL)
     437         230 :                         first = pbc;
     438             :         }
     439             : 
     440         337 :         wpa_printf(MSG_DEBUG, "WPS: %u active PBC session(s) found", count);
     441             : 
     442         337 :         return count > 1 ? 1 : 0;
     443             : }
     444             : 
     445             : 
     446        3688 : static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
     447             : {
     448        3688 :         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
     449        3688 :                    wps->wps_state);
     450        3688 :         wpabuf_put_be16(msg, ATTR_WPS_STATE);
     451        3688 :         wpabuf_put_be16(msg, 1);
     452        3688 :         wpabuf_put_u8(msg, wps->wps_state);
     453        3688 :         return 0;
     454             : }
     455             : 
     456             : 
     457             : #ifdef CONFIG_WPS_UPNP
     458          90 : static void wps_registrar_free_pending_m2(struct wps_context *wps)
     459             : {
     460          90 :         struct upnp_pending_message *p, *p2, *prev = NULL;
     461          90 :         p = wps->upnp_msgs;
     462         235 :         while (p) {
     463          55 :                 if (p->type == WPS_M2 || p->type == WPS_M2D) {
     464           1 :                         if (prev == NULL)
     465           1 :                                 wps->upnp_msgs = p->next;
     466             :                         else
     467           0 :                                 prev->next = p->next;
     468           1 :                         wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
     469           1 :                         p2 = p;
     470           1 :                         p = p->next;
     471           1 :                         wpabuf_free(p2->msg);
     472           1 :                         os_free(p2);
     473           1 :                         continue;
     474             :                 }
     475          54 :                 prev = p;
     476          54 :                 p = p->next;
     477             :         }
     478          90 : }
     479             : #endif /* CONFIG_WPS_UPNP */
     480             : 
     481             : 
     482        3688 : static int wps_build_ap_setup_locked(struct wps_context *wps,
     483             :                                      struct wpabuf *msg)
     484             : {
     485        3688 :         if (wps->ap_setup_locked && wps->ap_setup_locked != 2) {
     486          12 :                 wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
     487          12 :                 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
     488          12 :                 wpabuf_put_be16(msg, 1);
     489          12 :                 wpabuf_put_u8(msg, 1);
     490             :         }
     491        3688 :         return 0;
     492             : }
     493             : 
     494             : 
     495        3688 : static int wps_build_selected_registrar(struct wps_registrar *reg,
     496             :                                         struct wpabuf *msg)
     497             : {
     498        3688 :         if (!reg->sel_reg_union)
     499        2238 :                 return 0;
     500        1450 :         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
     501        1450 :         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
     502        1450 :         wpabuf_put_be16(msg, 1);
     503        1450 :         wpabuf_put_u8(msg, 1);
     504        1450 :         return 0;
     505             : }
     506             : 
     507             : 
     508        3688 : static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
     509             :                                              struct wpabuf *msg)
     510             : {
     511        3688 :         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
     512        3688 :         if (!reg->sel_reg_union)
     513        2238 :                 return 0;
     514        1450 :         if (reg->sel_reg_dev_password_id_override >= 0)
     515         330 :                 id = reg->sel_reg_dev_password_id_override;
     516        1450 :         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
     517        1450 :         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
     518        1450 :         wpabuf_put_be16(msg, 2);
     519        1450 :         wpabuf_put_be16(msg, id);
     520        1450 :         return 0;
     521             : }
     522             : 
     523             : 
     524        1844 : static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg,
     525             :                                         struct wpabuf *msg)
     526             : {
     527        1844 :         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
     528        1844 :         if (!reg->sel_reg_union)
     529        1119 :                 return 0;
     530         725 :         if (reg->sel_reg_dev_password_id_override >= 0)
     531         165 :                 id = reg->sel_reg_dev_password_id_override;
     532         725 :         if (id != DEV_PW_PUSHBUTTON || !reg->dualband)
     533         719 :                 return 0;
     534           6 :         return wps_build_uuid_e(msg, reg->wps->uuid);
     535             : }
     536             : 
     537             : 
     538         366 : static void wps_set_pushbutton(u16 *methods, u16 conf_methods)
     539             : {
     540         366 :         *methods |= WPS_CONFIG_PUSHBUTTON;
     541         366 :         if ((conf_methods & WPS_CONFIG_VIRT_PUSHBUTTON) ==
     542             :             WPS_CONFIG_VIRT_PUSHBUTTON)
     543           0 :                 *methods |= WPS_CONFIG_VIRT_PUSHBUTTON;
     544         366 :         if ((conf_methods & WPS_CONFIG_PHY_PUSHBUTTON) ==
     545             :             WPS_CONFIG_PHY_PUSHBUTTON)
     546           0 :                 *methods |= WPS_CONFIG_PHY_PUSHBUTTON;
     547         366 :         if ((*methods & WPS_CONFIG_VIRT_PUSHBUTTON) !=
     548         366 :             WPS_CONFIG_VIRT_PUSHBUTTON &&
     549         366 :             (*methods & WPS_CONFIG_PHY_PUSHBUTTON) !=
     550             :             WPS_CONFIG_PHY_PUSHBUTTON) {
     551             :                 /*
     552             :                  * Required to include virtual/physical flag, but we were not
     553             :                  * configured with push button type, so have to default to one
     554             :                  * of them.
     555             :                  */
     556         366 :                 *methods |= WPS_CONFIG_PHY_PUSHBUTTON;
     557             :         }
     558         366 : }
     559             : 
     560             : 
     561        3688 : static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
     562             :                                             struct wpabuf *msg)
     563             : {
     564             :         u16 methods;
     565        3688 :         if (!reg->sel_reg_union)
     566        2238 :                 return 0;
     567        1450 :         methods = reg->wps->config_methods;
     568        1450 :         methods &= ~WPS_CONFIG_PUSHBUTTON;
     569        1450 :         methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
     570             :                      WPS_CONFIG_PHY_PUSHBUTTON);
     571        1450 :         if (reg->pbc)
     572         236 :                 wps_set_pushbutton(&methods, reg->wps->config_methods);
     573        1450 :         if (reg->sel_reg_config_methods_override >= 0)
     574        1450 :                 methods = reg->sel_reg_config_methods_override;
     575        1450 :         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
     576             :                    methods);
     577        1450 :         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
     578        1450 :         wpabuf_put_be16(msg, 2);
     579        1450 :         wpabuf_put_be16(msg, methods);
     580        1450 :         return 0;
     581             : }
     582             : 
     583             : 
     584        1844 : static int wps_build_probe_config_methods(struct wps_registrar *reg,
     585             :                                           struct wpabuf *msg)
     586             : {
     587             :         u16 methods;
     588             :         /*
     589             :          * These are the methods that the AP supports as an Enrollee for adding
     590             :          * external Registrars.
     591             :          */
     592        1844 :         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
     593        1844 :         methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
     594             :                      WPS_CONFIG_PHY_PUSHBUTTON);
     595        1844 :         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
     596        1844 :         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
     597        1844 :         wpabuf_put_be16(msg, 2);
     598        1844 :         wpabuf_put_be16(msg, methods);
     599        1844 :         return 0;
     600             : }
     601             : 
     602             : 
     603         497 : static int wps_build_config_methods_r(struct wps_registrar *reg,
     604             :                                       struct wpabuf *msg)
     605             : {
     606         497 :         return wps_build_config_methods(msg, reg->wps->config_methods);
     607             : }
     608             : 
     609             : 
     610        1901 : const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count)
     611             : {
     612        1901 :         *count = 0;
     613             : 
     614        4349 :         while (*count < WPS_MAX_AUTHORIZED_MACS) {
     615        2447 :                 if (is_zero_ether_addr(reg->authorized_macs_union[*count]))
     616        1900 :                         break;
     617         547 :                 (*count)++;
     618             :         }
     619             : 
     620        1901 :         return (const u8 *) reg->authorized_macs_union;
     621             : }
     622             : 
     623             : 
     624             : /**
     625             :  * wps_registrar_init - Initialize WPS Registrar data
     626             :  * @wps: Pointer to longterm WPS context
     627             :  * @cfg: Registrar configuration
     628             :  * Returns: Pointer to allocated Registrar data or %NULL on failure
     629             :  *
     630             :  * This function is used to initialize WPS Registrar functionality. It can be
     631             :  * used for a single Registrar run (e.g., when run in a supplicant) or multiple
     632             :  * runs (e.g., when run as an internal Registrar in an AP). Caller is
     633             :  * responsible for freeing the returned data with wps_registrar_deinit() when
     634             :  * Registrar functionality is not needed anymore.
     635             :  */
     636             : struct wps_registrar *
     637        1402 : wps_registrar_init(struct wps_context *wps,
     638             :                    const struct wps_registrar_config *cfg)
     639             : {
     640        1402 :         struct wps_registrar *reg = os_zalloc(sizeof(*reg));
     641        1402 :         if (reg == NULL)
     642           1 :                 return NULL;
     643             : 
     644        1401 :         dl_list_init(&reg->pins);
     645        1401 :         dl_list_init(&reg->nfc_pw_tokens);
     646        1401 :         reg->wps = wps;
     647        1401 :         reg->new_psk_cb = cfg->new_psk_cb;
     648        1401 :         reg->set_ie_cb = cfg->set_ie_cb;
     649        1401 :         reg->pin_needed_cb = cfg->pin_needed_cb;
     650        1401 :         reg->reg_success_cb = cfg->reg_success_cb;
     651        1401 :         reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
     652        1401 :         reg->enrollee_seen_cb = cfg->enrollee_seen_cb;
     653        1401 :         reg->cb_ctx = cfg->cb_ctx;
     654        1401 :         reg->skip_cred_build = cfg->skip_cred_build;
     655        1401 :         if (cfg->extra_cred) {
     656           4 :                 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
     657             :                                                     cfg->extra_cred_len);
     658           4 :                 if (reg->extra_cred == NULL) {
     659           0 :                         os_free(reg);
     660           0 :                         return NULL;
     661             :                 }
     662             :         }
     663        1401 :         reg->disable_auto_conf = cfg->disable_auto_conf;
     664        1401 :         reg->sel_reg_dev_password_id_override = -1;
     665        1401 :         reg->sel_reg_config_methods_override = -1;
     666        1401 :         reg->static_wep_only = cfg->static_wep_only;
     667        1401 :         reg->dualband = cfg->dualband;
     668        1401 :         reg->force_per_enrollee_psk = cfg->force_per_enrollee_psk;
     669             : 
     670        1401 :         if (wps_set_ie(reg)) {
     671           0 :                 wps_registrar_deinit(reg);
     672           0 :                 return NULL;
     673             :         }
     674             : 
     675        1401 :         return reg;
     676             : }
     677             : 
     678             : 
     679        7461 : void wps_registrar_flush(struct wps_registrar *reg)
     680             : {
     681        7461 :         if (reg == NULL)
     682        7461 :                 return;
     683        7461 :         wps_free_pins(&reg->pins);
     684        7461 :         wps_free_nfc_pw_tokens(&reg->nfc_pw_tokens, 0);
     685        7461 :         wps_free_pbc_sessions(reg->pbc_sessions);
     686        7461 :         reg->pbc_sessions = NULL;
     687        7461 :         wps_free_devices(reg->devices);
     688        7461 :         reg->devices = NULL;
     689             : #ifdef WPS_WORKAROUNDS
     690        7461 :         reg->pbc_ignore_start.sec = 0;
     691             : #endif /* WPS_WORKAROUNDS */
     692             : }
     693             : 
     694             : 
     695             : /**
     696             :  * wps_registrar_deinit - Deinitialize WPS Registrar data
     697             :  * @reg: Registrar data from wps_registrar_init()
     698             :  */
     699        1401 : void wps_registrar_deinit(struct wps_registrar *reg)
     700             : {
     701        1401 :         if (reg == NULL)
     702        1401 :                 return;
     703        1401 :         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
     704        1401 :         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
     705        1401 :         wps_registrar_flush(reg);
     706        1401 :         wpabuf_clear_free(reg->extra_cred);
     707        1401 :         os_free(reg);
     708             : }
     709             : 
     710             : 
     711         379 : static void wps_registrar_invalidate_unused(struct wps_registrar *reg)
     712             : {
     713             :         struct wps_uuid_pin *pin;
     714             : 
     715         399 :         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
     716          21 :                 if (pin->wildcard_uuid == 1 && !(pin->flags & PIN_LOCKED)) {
     717           1 :                         wpa_printf(MSG_DEBUG, "WPS: Invalidate previously "
     718             :                                    "configured wildcard PIN");
     719           1 :                         wps_registrar_remove_pin(reg, pin);
     720           1 :                         break;
     721             :                 }
     722             :         }
     723         379 : }
     724             : 
     725             : 
     726             : /**
     727             :  * wps_registrar_add_pin - Configure a new PIN for Registrar
     728             :  * @reg: Registrar data from wps_registrar_init()
     729             :  * @addr: Enrollee MAC address or %NULL if not known
     730             :  * @uuid: UUID-E or %NULL for wildcard (any UUID)
     731             :  * @pin: PIN (Device Password)
     732             :  * @pin_len: Length of pin in octets
     733             :  * @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
     734             :  * Returns: 0 on success, -1 on failure
     735             :  */
     736         398 : int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr,
     737             :                           const u8 *uuid, const u8 *pin, size_t pin_len,
     738             :                           int timeout)
     739             : {
     740             :         struct wps_uuid_pin *p;
     741             : 
     742         398 :         p = os_zalloc(sizeof(*p));
     743         398 :         if (p == NULL)
     744           0 :                 return -1;
     745         398 :         if (addr)
     746         125 :                 os_memcpy(p->enrollee_addr, addr, ETH_ALEN);
     747         398 :         if (uuid == NULL)
     748         379 :                 p->wildcard_uuid = 1;
     749             :         else
     750          19 :                 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
     751         398 :         p->pin = os_malloc(pin_len);
     752         398 :         if (p->pin == NULL) {
     753           0 :                 os_free(p);
     754           0 :                 return -1;
     755             :         }
     756         398 :         os_memcpy(p->pin, pin, pin_len);
     757         398 :         p->pin_len = pin_len;
     758             : 
     759         398 :         if (timeout) {
     760          11 :                 p->flags |= PIN_EXPIRES;
     761          11 :                 os_get_reltime(&p->expiration);
     762          11 :                 p->expiration.sec += timeout;
     763             :         }
     764             : 
     765         398 :         if (p->wildcard_uuid)
     766         379 :                 wps_registrar_invalidate_unused(reg);
     767             : 
     768         398 :         dl_list_add(&reg->pins, &p->list);
     769             : 
     770         398 :         wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
     771             :                    timeout);
     772         398 :         wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
     773         398 :         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
     774         398 :         reg->selected_registrar = 1;
     775         398 :         reg->pbc = 0;
     776         398 :         if (addr)
     777         125 :                 wps_registrar_add_authorized_mac(reg, addr);
     778             :         else
     779         273 :                 wps_registrar_add_authorized_mac(
     780             :                         reg, (u8 *) "\xff\xff\xff\xff\xff\xff");
     781         398 :         wps_registrar_selected_registrar_changed(reg, 0);
     782         398 :         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
     783         398 :         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
     784             :                                wps_registrar_set_selected_timeout,
     785             :                                reg, NULL);
     786             : 
     787         398 :         return 0;
     788             : }
     789             : 
     790             : 
     791         297 : static void wps_registrar_remove_pin(struct wps_registrar *reg,
     792             :                                      struct wps_uuid_pin *pin)
     793             : {
     794             :         u8 *addr;
     795         297 :         u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
     796             : 
     797         297 :         if (is_zero_ether_addr(pin->enrollee_addr))
     798         177 :                 addr = bcast;
     799             :         else
     800         120 :                 addr = pin->enrollee_addr;
     801         297 :         wps_registrar_remove_authorized_mac(reg, addr);
     802         297 :         wps_remove_pin(pin);
     803         297 :         wps_registrar_selected_registrar_changed(reg, 0);
     804         297 : }
     805             : 
     806             : 
     807         381 : static void wps_registrar_expire_pins(struct wps_registrar *reg)
     808             : {
     809             :         struct wps_uuid_pin *pin, *prev;
     810             :         struct os_reltime now;
     811             : 
     812         381 :         os_get_reltime(&now);
     813         770 :         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
     814             :         {
     815         399 :                 if ((pin->flags & PIN_EXPIRES) &&
     816          10 :                     os_reltime_before(&pin->expiration, &now)) {
     817           1 :                         wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
     818           1 :                                     pin->uuid, WPS_UUID_LEN);
     819           1 :                         wps_registrar_remove_pin(reg, pin);
     820             :                 }
     821             :         }
     822         381 : }
     823             : 
     824             : 
     825             : /**
     826             :  * wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN
     827             :  * @reg: Registrar data from wps_registrar_init()
     828             :  * @dev_pw: PIN to search for or %NULL to match any
     829             :  * @dev_pw_len: Length of dev_pw in octets
     830             :  * Returns: 0 on success, -1 if not wildcard PIN is enabled
     831             :  */
     832           4 : static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg,
     833             :                                                  const u8 *dev_pw,
     834             :                                                  size_t dev_pw_len)
     835             : {
     836             :         struct wps_uuid_pin *pin, *prev;
     837             : 
     838           4 :         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
     839             :         {
     840           5 :                 if (dev_pw && pin->pin &&
     841           4 :                     (dev_pw_len != pin->pin_len ||
     842           2 :                      os_memcmp_const(dev_pw, pin->pin, dev_pw_len) != 0))
     843           0 :                         continue; /* different PIN */
     844           3 :                 if (pin->wildcard_uuid) {
     845           3 :                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
     846           3 :                                     pin->uuid, WPS_UUID_LEN);
     847           3 :                         wps_registrar_remove_pin(reg, pin);
     848           3 :                         return 0;
     849             :                 }
     850             :         }
     851             : 
     852           1 :         return -1;
     853             : }
     854             : 
     855             : 
     856             : /**
     857             :  * wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
     858             :  * @reg: Registrar data from wps_registrar_init()
     859             :  * @uuid: UUID-E
     860             :  * Returns: 0 on success, -1 on failure (e.g., PIN not found)
     861             :  */
     862         368 : int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
     863             : {
     864             :         struct wps_uuid_pin *pin, *prev;
     865             : 
     866         369 :         dl_list_for_each_safe(pin, prev, &reg->pins, struct wps_uuid_pin, list)
     867             :         {
     868         293 :                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
     869         292 :                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
     870         292 :                                     pin->uuid, WPS_UUID_LEN);
     871         292 :                         wps_registrar_remove_pin(reg, pin);
     872         292 :                         return 0;
     873             :                 }
     874             :         }
     875             : 
     876          76 :         return -1;
     877             : }
     878             : 
     879             : 
     880         381 : static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
     881             :                                         const u8 *uuid, size_t *pin_len)
     882             : {
     883         381 :         struct wps_uuid_pin *pin, *found = NULL;
     884             : 
     885         381 :         wps_registrar_expire_pins(reg);
     886             : 
     887         734 :         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
     888         392 :                 if (!pin->wildcard_uuid &&
     889          20 :                     os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
     890          19 :                         found = pin;
     891          19 :                         break;
     892             :                 }
     893             :         }
     894             : 
     895         381 :         if (!found) {
     896             :                 /* Check for wildcard UUIDs since none of the UUID-specific
     897             :                  * PINs matched */
     898         362 :                 dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
     899         332 :                         if (pin->wildcard_uuid == 1 ||
     900           0 :                             pin->wildcard_uuid == 2) {
     901         332 :                                 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
     902             :                                            "PIN. Assigned it for this UUID-E");
     903         332 :                                 pin->wildcard_uuid++;
     904         332 :                                 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
     905         332 :                                 found = pin;
     906         332 :                                 break;
     907             :                         }
     908             :                 }
     909             :         }
     910             : 
     911         381 :         if (!found)
     912          30 :                 return NULL;
     913             : 
     914             :         /*
     915             :          * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
     916             :          * that could otherwise avoid PIN invalidations.
     917             :          */
     918         351 :         if (found->flags & PIN_LOCKED) {
     919           0 :                 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
     920             :                            "allow concurrent re-use");
     921           0 :                 return NULL;
     922             :         }
     923         351 :         *pin_len = found->pin_len;
     924         351 :         found->flags |= PIN_LOCKED;
     925         351 :         return found->pin;
     926             : }
     927             : 
     928             : 
     929             : /**
     930             :  * wps_registrar_unlock_pin - Unlock a PIN for a specific UUID-E
     931             :  * @reg: Registrar data from wps_registrar_init()
     932             :  * @uuid: UUID-E
     933             :  * Returns: 0 on success, -1 on failure
     934             :  *
     935             :  * PINs are locked to enforce only one concurrent use. This function unlocks a
     936             :  * PIN to allow it to be used again. If the specified PIN was configured using
     937             :  * a wildcard UUID, it will be removed instead of allowing multiple uses.
     938             :  */
     939         928 : int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
     940             : {
     941             :         struct wps_uuid_pin *pin;
     942             : 
     943         932 :         dl_list_for_each(pin, &reg->pins, struct wps_uuid_pin, list) {
     944         382 :                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
     945         378 :                         if (pin->wildcard_uuid == 3) {
     946           0 :                                 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
     947             :                                            "wildcard PIN");
     948           0 :                                 return wps_registrar_invalidate_pin(reg, uuid);
     949             :                         }
     950         378 :                         pin->flags &= ~PIN_LOCKED;
     951         378 :                         return 0;
     952             :                 }
     953             :         }
     954             : 
     955         550 :         return -1;
     956             : }
     957             : 
     958             : 
     959          61 : static void wps_registrar_stop_pbc(struct wps_registrar *reg)
     960             : {
     961          61 :         reg->selected_registrar = 0;
     962          61 :         reg->pbc = 0;
     963          61 :         os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
     964          61 :         wps_registrar_remove_authorized_mac(reg,
     965             :                                             (u8 *) "\xff\xff\xff\xff\xff\xff");
     966          61 :         wps_registrar_selected_registrar_changed(reg, 0);
     967          61 : }
     968             : 
     969             : 
     970           7 : static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
     971             : {
     972           7 :         struct wps_registrar *reg = eloop_ctx;
     973             : 
     974           7 :         wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
     975           7 :         wps_pbc_timeout_event(reg->wps);
     976           7 :         wps_registrar_stop_pbc(reg);
     977           7 : }
     978             : 
     979             : 
     980             : /**
     981             :  * wps_registrar_button_pushed - Notify Registrar that AP button was pushed
     982             :  * @reg: Registrar data from wps_registrar_init()
     983             :  * @p2p_dev_addr: Limit allowed PBC devices to the specified P2P device, %NULL
     984             :  *      indicates no such filtering
     985             :  * Returns: 0 on success, -1 on failure, -2 on session overlap
     986             :  *
     987             :  * This function is called on an AP when a push button is pushed to activate
     988             :  * PBC mode. The PBC mode will be stopped after walk time (2 minutes) timeout
     989             :  * or when a PBC registration is completed. If more than one Enrollee in active
     990             :  * PBC mode has been detected during the monitor time (previous 2 minutes), the
     991             :  * PBC mode is not activated and -2 is returned to indicate session overlap.
     992             :  * This is skipped if a specific Enrollee is selected.
     993             :  */
     994         127 : int wps_registrar_button_pushed(struct wps_registrar *reg,
     995             :                                 const u8 *p2p_dev_addr)
     996             : {
     997         228 :         if (p2p_dev_addr == NULL &&
     998         101 :             wps_registrar_pbc_overlap(reg, NULL, NULL)) {
     999           3 :                 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
    1000             :                            "mode");
    1001           3 :                 wps_pbc_overlap_event(reg->wps);
    1002           3 :                 return -2;
    1003             :         }
    1004         124 :         wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
    1005         124 :         reg->force_pbc_overlap = 0;
    1006         124 :         reg->selected_registrar = 1;
    1007         124 :         reg->pbc = 1;
    1008         124 :         if (p2p_dev_addr)
    1009          26 :                 os_memcpy(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN);
    1010             :         else
    1011          98 :                 os_memset(reg->p2p_dev_addr, 0, ETH_ALEN);
    1012         124 :         wps_registrar_add_authorized_mac(reg,
    1013             :                                          (u8 *) "\xff\xff\xff\xff\xff\xff");
    1014         124 :         wps_registrar_selected_registrar_changed(reg, 0);
    1015             : 
    1016         124 :         wps_pbc_active_event(reg->wps);
    1017         124 :         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
    1018         124 :         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
    1019         124 :         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
    1020             :                                reg, NULL);
    1021         124 :         return 0;
    1022             : }
    1023             : 
    1024             : 
    1025          54 : static void wps_registrar_pbc_completed(struct wps_registrar *reg)
    1026             : {
    1027          54 :         wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
    1028          54 :         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
    1029          54 :         wps_registrar_stop_pbc(reg);
    1030          54 :         wps_pbc_disable_event(reg->wps);
    1031          54 : }
    1032             : 
    1033             : 
    1034         301 : static void wps_registrar_pin_completed(struct wps_registrar *reg)
    1035             : {
    1036         301 :         wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
    1037         301 :         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
    1038         301 :         reg->selected_registrar = 0;
    1039         301 :         wps_registrar_selected_registrar_changed(reg, 0);
    1040         301 : }
    1041             : 
    1042             : 
    1043           3 : void wps_registrar_complete(struct wps_registrar *registrar, const u8 *uuid_e,
    1044             :                             const u8 *dev_pw, size_t dev_pw_len)
    1045             : {
    1046           3 :         if (registrar->pbc) {
    1047           1 :                 wps_registrar_remove_pbc_session(registrar,
    1048             :                                                  uuid_e, NULL);
    1049           1 :                 wps_registrar_pbc_completed(registrar);
    1050             : #ifdef WPS_WORKAROUNDS
    1051           1 :                 os_get_reltime(&registrar->pbc_ignore_start);
    1052             : #endif /* WPS_WORKAROUNDS */
    1053           1 :                 os_memcpy(registrar->pbc_ignore_uuid, uuid_e, WPS_UUID_LEN);
    1054             :         } else {
    1055           2 :                 wps_registrar_pin_completed(registrar);
    1056             :         }
    1057             : 
    1058           6 :         if (dev_pw &&
    1059           3 :             wps_registrar_invalidate_wildcard_pin(registrar, dev_pw,
    1060             :                                                   dev_pw_len) == 0) {
    1061           2 :                 wpa_hexdump_key(MSG_DEBUG, "WPS: Invalidated wildcard PIN",
    1062             :                                 dev_pw, dev_pw_len);
    1063             :         }
    1064           3 : }
    1065             : 
    1066             : 
    1067          18 : int wps_registrar_wps_cancel(struct wps_registrar *reg)
    1068             : {
    1069          18 :         if (reg->pbc) {
    1070           6 :                 wpa_printf(MSG_DEBUG, "WPS: PBC is set - cancelling it");
    1071           6 :                 wps_registrar_pbc_timeout(reg, NULL);
    1072           6 :                 eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
    1073           6 :                 return 1;
    1074          12 :         } else if (reg->selected_registrar) {
    1075             :                 /* PIN Method */
    1076           1 :                 wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it");
    1077           1 :                 wps_registrar_pin_completed(reg);
    1078           1 :                 wps_registrar_invalidate_wildcard_pin(reg, NULL, 0);
    1079           1 :                 return 1;
    1080             :         }
    1081          11 :         return 0;
    1082             : }
    1083             : 
    1084             : 
    1085             : /**
    1086             :  * wps_registrar_probe_req_rx - Notify Registrar of Probe Request
    1087             :  * @reg: Registrar data from wps_registrar_init()
    1088             :  * @addr: MAC address of the Probe Request sender
    1089             :  * @wps_data: WPS IE contents
    1090             :  *
    1091             :  * This function is called on an AP when a Probe Request with WPS IE is
    1092             :  * received. This is used to track PBC mode use and to detect possible overlap
    1093             :  * situation with other WPS APs.
    1094             :  */
    1095        1717 : void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
    1096             :                                 const struct wpabuf *wps_data,
    1097             :                                 int p2p_wildcard)
    1098             : {
    1099             :         struct wps_parse_attr attr;
    1100        1717 :         int skip_add = 0;
    1101             : 
    1102        1717 :         wpa_hexdump_buf(MSG_MSGDUMP,
    1103             :                         "WPS: Probe Request with WPS data received",
    1104             :                         wps_data);
    1105             : 
    1106        1717 :         if (wps_parse_msg(wps_data, &attr) < 0)
    1107        1568 :                 return;
    1108             : 
    1109        1717 :         if (attr.config_methods == NULL) {
    1110           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
    1111             :                            "Probe Request");
    1112           1 :                 return;
    1113             :         }
    1114             : 
    1115        1716 :         if (attr.dev_password_id == NULL) {
    1116           0 :                 wpa_printf(MSG_DEBUG, "WPS: No Device Password Id attribute "
    1117             :                            "in Probe Request");
    1118           0 :                 return;
    1119             :         }
    1120             : 
    1121        3384 :         if (reg->enrollee_seen_cb && attr.uuid_e &&
    1122        3336 :             attr.primary_dev_type && attr.request_type && !p2p_wildcard) {
    1123        1668 :                 char *dev_name = NULL;
    1124        1668 :                 if (attr.dev_name) {
    1125        1668 :                         dev_name = os_zalloc(attr.dev_name_len + 1);
    1126        1668 :                         if (dev_name) {
    1127        1668 :                                 os_memcpy(dev_name, attr.dev_name,
    1128             :                                           attr.dev_name_len);
    1129             :                         }
    1130             :                 }
    1131        6672 :                 reg->enrollee_seen_cb(reg->cb_ctx, addr, attr.uuid_e,
    1132             :                                       attr.primary_dev_type,
    1133        1668 :                                       WPA_GET_BE16(attr.config_methods),
    1134        1668 :                                       WPA_GET_BE16(attr.dev_password_id),
    1135        1668 :                                       *attr.request_type, dev_name);
    1136        1668 :                 os_free(dev_name);
    1137             :         }
    1138             : 
    1139        1716 :         if (WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
    1140        1567 :                 return; /* Not PBC */
    1141             : 
    1142         894 :         wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
    1143         894 :                    MACSTR, MAC2STR(addr));
    1144         149 :         if (attr.uuid_e == NULL) {
    1145           0 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid Probe Request WPS IE: No "
    1146             :                            "UUID-E included");
    1147           0 :                 return;
    1148             :         }
    1149         149 :         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E from Probe Request", attr.uuid_e,
    1150             :                     WPS_UUID_LEN);
    1151             : 
    1152             : #ifdef WPS_WORKAROUNDS
    1153         152 :         if (reg->pbc_ignore_start.sec &&
    1154           3 :             os_memcmp(attr.uuid_e, reg->pbc_ignore_uuid, WPS_UUID_LEN) == 0) {
    1155             :                 struct os_reltime now, dur;
    1156           1 :                 os_get_reltime(&now);
    1157           1 :                 os_reltime_sub(&now, &reg->pbc_ignore_start, &dur);
    1158           1 :                 if (dur.sec >= 0 && dur.sec < 5) {
    1159           1 :                         wpa_printf(MSG_DEBUG, "WPS: Ignore PBC activation "
    1160             :                                    "based on Probe Request from the Enrollee "
    1161             :                                    "that just completed PBC provisioning");
    1162           1 :                         skip_add = 1;
    1163             :                 } else
    1164           0 :                         reg->pbc_ignore_start.sec = 0;
    1165             :         }
    1166             : #endif /* WPS_WORKAROUNDS */
    1167             : 
    1168         149 :         if (!skip_add)
    1169         148 :                 wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
    1170         149 :         if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
    1171           5 :                 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
    1172           5 :                 reg->force_pbc_overlap = 1;
    1173           5 :                 wps_pbc_overlap_event(reg->wps);
    1174             :         }
    1175             : }
    1176             : 
    1177             : 
    1178          15 : int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
    1179             :                    const u8 *p2p_dev_addr, const u8 *psk, size_t psk_len)
    1180             : {
    1181          15 :         if (reg->new_psk_cb == NULL)
    1182           0 :                 return 0;
    1183             : 
    1184          15 :         return reg->new_psk_cb(reg->cb_ctx, mac_addr, p2p_dev_addr, psk,
    1185             :                                psk_len);
    1186             : }
    1187             : 
    1188             : 
    1189          30 : static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
    1190             :                               const struct wps_device_data *dev)
    1191             : {
    1192          30 :         if (reg->pin_needed_cb == NULL)
    1193          30 :                 return;
    1194             : 
    1195          30 :         reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
    1196             : }
    1197             : 
    1198             : 
    1199         312 : static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
    1200             :                                const u8 *uuid_e, const u8 *dev_pw,
    1201             :                                size_t dev_pw_len)
    1202             : {
    1203         312 :         if (reg->reg_success_cb == NULL)
    1204         329 :                 return;
    1205             : 
    1206         295 :         reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e, dev_pw, dev_pw_len);
    1207             : }
    1208             : 
    1209             : 
    1210        1844 : static int wps_cb_set_ie(struct wps_registrar *reg, struct wpabuf *beacon_ie,
    1211             :                          struct wpabuf *probe_resp_ie)
    1212             : {
    1213        1844 :         return reg->set_ie_cb(reg->cb_ctx, beacon_ie, probe_resp_ie);
    1214             : }
    1215             : 
    1216             : 
    1217        1327 : static void wps_cb_set_sel_reg(struct wps_registrar *reg)
    1218             : {
    1219        1327 :         u16 methods = 0;
    1220        1327 :         if (reg->set_sel_reg_cb == NULL)
    1221        2441 :                 return;
    1222             : 
    1223         213 :         if (reg->selected_registrar) {
    1224         147 :                 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
    1225         147 :                 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
    1226             :                              WPS_CONFIG_PHY_PUSHBUTTON);
    1227         147 :                 if (reg->pbc)
    1228           6 :                         wps_set_pushbutton(&methods, reg->wps->config_methods);
    1229             :         }
    1230             : 
    1231         426 :         wpa_printf(MSG_DEBUG, "WPS: wps_cb_set_sel_reg: sel_reg=%d "
    1232             :                    "config_methods=0x%x pbc=%d methods=0x%x",
    1233         213 :                    reg->selected_registrar, reg->wps->config_methods,
    1234             :                    reg->pbc, methods);
    1235             : 
    1236         426 :         reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
    1237         213 :                             reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
    1238             :                             methods);
    1239             : }
    1240             : 
    1241             : 
    1242        2759 : static int wps_set_ie(struct wps_registrar *reg)
    1243             : {
    1244             :         struct wpabuf *beacon;
    1245             :         struct wpabuf *probe;
    1246             :         const u8 *auth_macs;
    1247             :         size_t count;
    1248        2759 :         size_t vendor_len = 0;
    1249             :         int i;
    1250             : 
    1251        2759 :         if (reg->set_ie_cb == NULL)
    1252         915 :                 return 0;
    1253             : 
    1254       20284 :         for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++) {
    1255       18440 :                 if (reg->wps->dev.vendor_ext[i]) {
    1256           3 :                         vendor_len += 2 + 2;
    1257           3 :                         vendor_len += wpabuf_len(reg->wps->dev.vendor_ext[i]);
    1258             :                 }
    1259             :         }
    1260             : 
    1261        1844 :         beacon = wpabuf_alloc(400 + vendor_len);
    1262        1844 :         if (beacon == NULL)
    1263           0 :                 return -1;
    1264        1844 :         probe = wpabuf_alloc(500 + vendor_len);
    1265        1844 :         if (probe == NULL) {
    1266           0 :                 wpabuf_free(beacon);
    1267           0 :                 return -1;
    1268             :         }
    1269             : 
    1270        1844 :         auth_macs = wps_authorized_macs(reg, &count);
    1271             : 
    1272        1844 :         wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs");
    1273             : 
    1274        3688 :         if (wps_build_version(beacon) ||
    1275        3688 :             wps_build_wps_state(reg->wps, beacon) ||
    1276        3688 :             wps_build_ap_setup_locked(reg->wps, beacon) ||
    1277        3688 :             wps_build_selected_registrar(reg, beacon) ||
    1278        3688 :             wps_build_sel_reg_dev_password_id(reg, beacon) ||
    1279        3688 :             wps_build_sel_reg_config_methods(reg, beacon) ||
    1280        3688 :             wps_build_sel_pbc_reg_uuid_e(reg, beacon) ||
    1281        3714 :             (reg->dualband && wps_build_rf_bands(&reg->wps->dev, beacon, 0)) ||
    1282        3688 :             wps_build_wfa_ext(beacon, 0, auth_macs, count) ||
    1283        1844 :             wps_build_vendor_ext(&reg->wps->dev, beacon)) {
    1284           0 :                 wpabuf_free(beacon);
    1285           0 :                 wpabuf_free(probe);
    1286           0 :                 return -1;
    1287             :         }
    1288             : 
    1289             : #ifdef CONFIG_P2P
    1290        2290 :         if (wps_build_dev_name(&reg->wps->dev, beacon) ||
    1291        1145 :             wps_build_primary_dev_type(&reg->wps->dev, beacon)) {
    1292           0 :                 wpabuf_free(beacon);
    1293           0 :                 wpabuf_free(probe);
    1294           0 :                 return -1;
    1295             :         }
    1296             : #endif /* CONFIG_P2P */
    1297             : 
    1298        1844 :         wpa_printf(MSG_DEBUG, "WPS: Build Probe Response IEs");
    1299             : 
    1300        3688 :         if (wps_build_version(probe) ||
    1301        3688 :             wps_build_wps_state(reg->wps, probe) ||
    1302        3688 :             wps_build_ap_setup_locked(reg->wps, probe) ||
    1303        3688 :             wps_build_selected_registrar(reg, probe) ||
    1304        3688 :             wps_build_sel_reg_dev_password_id(reg, probe) ||
    1305        3688 :             wps_build_sel_reg_config_methods(reg, probe) ||
    1306        1844 :             wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
    1307        1844 :                                 WPS_RESP_REGISTRAR) ||
    1308        3688 :             wps_build_uuid_e(probe, reg->wps->uuid) ||
    1309        3688 :             wps_build_device_attrs(&reg->wps->dev, probe) ||
    1310        3688 :             wps_build_probe_config_methods(reg, probe) ||
    1311        3714 :             (reg->dualband && wps_build_rf_bands(&reg->wps->dev, probe, 0)) ||
    1312        3688 :             wps_build_wfa_ext(probe, 0, auth_macs, count) ||
    1313        1844 :             wps_build_vendor_ext(&reg->wps->dev, probe)) {
    1314           0 :                 wpabuf_free(beacon);
    1315           0 :                 wpabuf_free(probe);
    1316           0 :                 return -1;
    1317             :         }
    1318             : 
    1319        1844 :         beacon = wps_ie_encapsulate(beacon);
    1320        1844 :         probe = wps_ie_encapsulate(probe);
    1321             : 
    1322        1844 :         if (!beacon || !probe) {
    1323           0 :                 wpabuf_free(beacon);
    1324           0 :                 wpabuf_free(probe);
    1325           0 :                 return -1;
    1326             :         }
    1327             : 
    1328        1844 :         if (reg->static_wep_only) {
    1329             :                 /*
    1330             :                  * Windows XP and Vista clients can get confused about
    1331             :                  * EAP-Identity/Request when they probe the network with
    1332             :                  * EAPOL-Start. In such a case, they may assume the network is
    1333             :                  * using IEEE 802.1X and prompt user for a certificate while
    1334             :                  * the correct (non-WPS) behavior would be to ask for the
    1335             :                  * static WEP key. As a workaround, use Microsoft Provisioning
    1336             :                  * IE to advertise that legacy 802.1X is not supported.
    1337             :                  */
    1338           0 :                 const u8 ms_wps[7] = {
    1339             :                         WLAN_EID_VENDOR_SPECIFIC, 5,
    1340             :                         /* Microsoft Provisioning IE (00:50:f2:5) */
    1341             :                         0x00, 0x50, 0xf2, 5,
    1342             :                         0x00 /* no legacy 802.1X or MS WPS */
    1343             :                 };
    1344           0 :                 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
    1345             :                            "into Beacon/Probe Response frames");
    1346           0 :                 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
    1347           0 :                 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
    1348             :         }
    1349             : 
    1350        1844 :         return wps_cb_set_ie(reg, beacon, probe);
    1351             : }
    1352             : 
    1353             : 
    1354         489 : static int wps_get_dev_password(struct wps_data *wps)
    1355             : {
    1356             :         const u8 *pin;
    1357         489 :         size_t pin_len = 0;
    1358             : 
    1359         489 :         bin_clear_free(wps->dev_password, wps->dev_password_len);
    1360         489 :         wps->dev_password = NULL;
    1361             : 
    1362         489 :         if (wps->pbc) {
    1363          78 :                 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
    1364          78 :                 pin = (const u8 *) "00000000";
    1365          78 :                 pin_len = 8;
    1366             : #ifdef CONFIG_WPS_NFC
    1367         411 :         } else if (wps->nfc_pw_token) {
    1368          28 :                 if (wps->nfc_pw_token->pw_id == DEV_PW_NFC_CONNECTION_HANDOVER)
    1369             :                 {
    1370          16 :                         wpa_printf(MSG_DEBUG, "WPS: Using NFC connection "
    1371             :                                    "handover and abbreviated WPS handshake "
    1372             :                                    "without Device Password");
    1373          16 :                         return 0;
    1374             :                 }
    1375          12 :                 wpa_printf(MSG_DEBUG, "WPS: Use OOB Device Password from NFC "
    1376             :                            "Password Token");
    1377          12 :                 pin = wps->nfc_pw_token->dev_pw;
    1378          12 :                 pin_len = wps->nfc_pw_token->dev_pw_len;
    1379         386 :         } else if (wps->dev_pw_id >= 0x10 &&
    1380           5 :                    wps->wps->ap_nfc_dev_pw_id == wps->dev_pw_id &&
    1381           2 :                    wps->wps->ap_nfc_dev_pw) {
    1382           2 :                 wpa_printf(MSG_DEBUG, "WPS: Use OOB Device Password from own NFC Password Token");
    1383           2 :                 pin = wpabuf_head(wps->wps->ap_nfc_dev_pw);
    1384           2 :                 pin_len = wpabuf_len(wps->wps->ap_nfc_dev_pw);
    1385             : #endif /* CONFIG_WPS_NFC */
    1386             :         } else {
    1387         381 :                 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
    1388             :                                             &pin_len);
    1389         381 :                 if (pin && wps->dev_pw_id >= 0x10) {
    1390           0 :                         wpa_printf(MSG_DEBUG, "WPS: No match for OOB Device "
    1391             :                                    "Password ID, but PIN found");
    1392             :                         /*
    1393             :                          * See whether Enrollee is willing to use PIN instead.
    1394             :                          */
    1395           0 :                         wps->dev_pw_id = DEV_PW_DEFAULT;
    1396             :                 }
    1397             :         }
    1398         473 :         if (pin == NULL) {
    1399          30 :                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
    1400             :                            "the Enrollee (context %p registrar %p)",
    1401          30 :                            wps->wps, wps->wps->registrar);
    1402          30 :                 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
    1403          30 :                                   &wps->peer_dev);
    1404          30 :                 return -1;
    1405             :         }
    1406             : 
    1407         443 :         wps->dev_password = os_malloc(pin_len);
    1408         443 :         if (wps->dev_password == NULL)
    1409           0 :                 return -1;
    1410         443 :         os_memcpy(wps->dev_password, pin, pin_len);
    1411         443 :         wps->dev_password_len = pin_len;
    1412             : 
    1413         443 :         return 0;
    1414             : }
    1415             : 
    1416             : 
    1417         498 : static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
    1418             : {
    1419         498 :         wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
    1420         498 :         wpabuf_put_be16(msg, ATTR_UUID_R);
    1421         498 :         wpabuf_put_be16(msg, WPS_UUID_LEN);
    1422         498 :         wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
    1423         498 :         return 0;
    1424             : }
    1425             : 
    1426             : 
    1427         389 : static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
    1428             : {
    1429             :         u8 *hash;
    1430             :         const u8 *addr[4];
    1431             :         size_t len[4];
    1432             : 
    1433         389 :         if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
    1434           0 :                 return -1;
    1435         389 :         wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
    1436         389 :         wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
    1437         389 :                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
    1438             : 
    1439         389 :         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
    1440           0 :                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
    1441             :                            "R-Hash derivation");
    1442           0 :                 return -1;
    1443             :         }
    1444             : 
    1445         389 :         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
    1446         389 :         wpabuf_put_be16(msg, ATTR_R_HASH1);
    1447         389 :         wpabuf_put_be16(msg, SHA256_MAC_LEN);
    1448         389 :         hash = wpabuf_put(msg, SHA256_MAC_LEN);
    1449             :         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
    1450         389 :         addr[0] = wps->snonce;
    1451         389 :         len[0] = WPS_SECRET_NONCE_LEN;
    1452         389 :         addr[1] = wps->psk1;
    1453         389 :         len[1] = WPS_PSK_LEN;
    1454         389 :         addr[2] = wpabuf_head(wps->dh_pubkey_e);
    1455         389 :         len[2] = wpabuf_len(wps->dh_pubkey_e);
    1456         389 :         addr[3] = wpabuf_head(wps->dh_pubkey_r);
    1457         389 :         len[3] = wpabuf_len(wps->dh_pubkey_r);
    1458         389 :         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    1459         389 :         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
    1460             : 
    1461         389 :         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
    1462         389 :         wpabuf_put_be16(msg, ATTR_R_HASH2);
    1463         389 :         wpabuf_put_be16(msg, SHA256_MAC_LEN);
    1464         389 :         hash = wpabuf_put(msg, SHA256_MAC_LEN);
    1465             :         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
    1466         389 :         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
    1467         389 :         addr[1] = wps->psk2;
    1468         389 :         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    1469         389 :         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
    1470             : 
    1471         389 :         return 0;
    1472             : }
    1473             : 
    1474             : 
    1475         389 : static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
    1476             : {
    1477         389 :         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
    1478         389 :         wpabuf_put_be16(msg, ATTR_R_SNONCE1);
    1479         389 :         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
    1480         389 :         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
    1481         389 :         return 0;
    1482             : }
    1483             : 
    1484             : 
    1485         367 : static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
    1486             : {
    1487         367 :         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
    1488         367 :         wpabuf_put_be16(msg, ATTR_R_SNONCE2);
    1489         367 :         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
    1490         367 :         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
    1491             :                         WPS_SECRET_NONCE_LEN);
    1492         367 :         return 0;
    1493             : }
    1494             : 
    1495             : 
    1496         369 : static int wps_build_cred_network_idx(struct wpabuf *msg,
    1497             :                                       const struct wps_credential *cred)
    1498             : {
    1499         369 :         wpa_printf(MSG_DEBUG, "WPS:  * Network Index (1)");
    1500         369 :         wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
    1501         369 :         wpabuf_put_be16(msg, 1);
    1502         369 :         wpabuf_put_u8(msg, 1);
    1503         369 :         return 0;
    1504             : }
    1505             : 
    1506             : 
    1507         369 : static int wps_build_cred_ssid(struct wpabuf *msg,
    1508             :                                const struct wps_credential *cred)
    1509             : {
    1510         369 :         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
    1511         738 :         wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID for Credential",
    1512         369 :                           cred->ssid, cred->ssid_len);
    1513         369 :         wpabuf_put_be16(msg, ATTR_SSID);
    1514         369 :         wpabuf_put_be16(msg, cred->ssid_len);
    1515         369 :         wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
    1516         369 :         return 0;
    1517             : }
    1518             : 
    1519             : 
    1520         369 : static int wps_build_cred_auth_type(struct wpabuf *msg,
    1521             :                                     const struct wps_credential *cred)
    1522             : {
    1523         369 :         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
    1524         369 :                    cred->auth_type);
    1525         369 :         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
    1526         369 :         wpabuf_put_be16(msg, 2);
    1527         369 :         wpabuf_put_be16(msg, cred->auth_type);
    1528         369 :         return 0;
    1529             : }
    1530             : 
    1531             : 
    1532         369 : static int wps_build_cred_encr_type(struct wpabuf *msg,
    1533             :                                     const struct wps_credential *cred)
    1534             : {
    1535         369 :         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
    1536         369 :                    cred->encr_type);
    1537         369 :         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
    1538         369 :         wpabuf_put_be16(msg, 2);
    1539         369 :         wpabuf_put_be16(msg, cred->encr_type);
    1540         369 :         return 0;
    1541             : }
    1542             : 
    1543             : 
    1544         369 : static int wps_build_cred_network_key(struct wpabuf *msg,
    1545             :                                       const struct wps_credential *cred)
    1546             : {
    1547         369 :         wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%d)",
    1548         369 :                    (int) cred->key_len);
    1549         738 :         wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
    1550         369 :                         cred->key, cred->key_len);
    1551         369 :         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
    1552         369 :         wpabuf_put_be16(msg, cred->key_len);
    1553         369 :         wpabuf_put_data(msg, cred->key, cred->key_len);
    1554         369 :         return 0;
    1555             : }
    1556             : 
    1557             : 
    1558         369 : static int wps_build_credential(struct wpabuf *msg,
    1559             :                                 const struct wps_credential *cred)
    1560             : {
    1561         738 :         if (wps_build_cred_network_idx(msg, cred) ||
    1562         738 :             wps_build_cred_ssid(msg, cred) ||
    1563         738 :             wps_build_cred_auth_type(msg, cred) ||
    1564         738 :             wps_build_cred_encr_type(msg, cred) ||
    1565         738 :             wps_build_cred_network_key(msg, cred) ||
    1566         369 :             wps_build_mac_addr(msg, cred->mac_addr))
    1567           0 :                 return -1;
    1568         369 :         return 0;
    1569             : }
    1570             : 
    1571             : 
    1572           1 : int wps_build_credential_wrap(struct wpabuf *msg,
    1573             :                               const struct wps_credential *cred)
    1574             : {
    1575             :         struct wpabuf *wbuf;
    1576           1 :         wbuf = wpabuf_alloc(200);
    1577           1 :         if (wbuf == NULL)
    1578           0 :                 return -1;
    1579           1 :         if (wps_build_credential(wbuf, cred)) {
    1580           0 :                 wpabuf_clear_free(wbuf);
    1581           0 :                 return -1;
    1582             :         }
    1583           1 :         wpabuf_put_be16(msg, ATTR_CRED);
    1584           1 :         wpabuf_put_be16(msg, wpabuf_len(wbuf));
    1585           1 :         wpabuf_put_buf(msg, wbuf);
    1586           1 :         wpabuf_clear_free(wbuf);
    1587           1 :         return 0;
    1588             : }
    1589             : 
    1590             : 
    1591         326 : int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
    1592             : {
    1593             :         struct wpabuf *cred;
    1594             : 
    1595         326 :         if (wps->wps->registrar->skip_cred_build)
    1596           4 :                 goto skip_cred_build;
    1597             : 
    1598         322 :         wpa_printf(MSG_DEBUG, "WPS:  * Credential");
    1599         322 :         if (wps->use_cred) {
    1600          13 :                 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
    1601          13 :                 goto use_provided;
    1602             :         }
    1603         309 :         os_memset(&wps->cred, 0, sizeof(wps->cred));
    1604             : 
    1605         309 :         os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
    1606         309 :         wps->cred.ssid_len = wps->wps->ssid_len;
    1607             : 
    1608             :         /* Select the best authentication and encryption type */
    1609         618 :         wpa_printf(MSG_DEBUG,
    1610             :                    "WPS: Own auth types 0x%x - masked Enrollee auth types 0x%x",
    1611         618 :                    wps->wps->auth_types, wps->auth_type);
    1612         309 :         if (wps->auth_type & WPS_AUTH_WPA2PSK)
    1613         309 :                 wps->auth_type = WPS_AUTH_WPA2PSK;
    1614           0 :         else if (wps->auth_type & WPS_AUTH_WPAPSK)
    1615           0 :                 wps->auth_type = WPS_AUTH_WPAPSK;
    1616           0 :         else if (wps->auth_type & WPS_AUTH_OPEN)
    1617           0 :                 wps->auth_type = WPS_AUTH_OPEN;
    1618             :         else {
    1619           0 :                 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
    1620           0 :                            wps->auth_type);
    1621           0 :                 return -1;
    1622             :         }
    1623         309 :         wps->cred.auth_type = wps->auth_type;
    1624             : 
    1625        1236 :         wpa_printf(MSG_DEBUG,
    1626             :                    "WPS: Own encr types 0x%x (rsn: 0x%x, wpa: 0x%x) - masked Enrollee encr types 0x%x",
    1627         618 :                    wps->wps->encr_types, wps->wps->encr_types_rsn,
    1628         618 :                    wps->wps->encr_types_wpa, wps->encr_type);
    1629         309 :         if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPA2PSK)
    1630         309 :                 wps->encr_type &= wps->wps->encr_types_rsn;
    1631           0 :         else if (wps->wps->ap && wps->auth_type == WPS_AUTH_WPAPSK)
    1632           0 :                 wps->encr_type &= wps->wps->encr_types_wpa;
    1633         309 :         if (wps->auth_type == WPS_AUTH_WPA2PSK ||
    1634           0 :             wps->auth_type == WPS_AUTH_WPAPSK) {
    1635         618 :                 if (wps->encr_type & WPS_ENCR_AES)
    1636         309 :                         wps->encr_type = WPS_ENCR_AES;
    1637           0 :                 else if (wps->encr_type & WPS_ENCR_TKIP)
    1638           0 :                         wps->encr_type = WPS_ENCR_TKIP;
    1639             :                 else {
    1640           0 :                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
    1641             :                                    "type for WPA/WPA2");
    1642           0 :                         return -1;
    1643             :                 }
    1644             :         } else {
    1645           0 :                 if (wps->encr_type & WPS_ENCR_NONE)
    1646           0 :                         wps->encr_type = WPS_ENCR_NONE;
    1647             : #ifdef CONFIG_TESTING_OPTIONS
    1648           0 :                 else if (wps->encr_type & WPS_ENCR_WEP)
    1649           0 :                         wps->encr_type = WPS_ENCR_WEP;
    1650             : #endif /* CONFIG_TESTING_OPTIONS */
    1651             :                 else {
    1652           0 :                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
    1653             :                                    "type for non-WPA/WPA2 mode");
    1654           0 :                         return -1;
    1655             :                 }
    1656             :         }
    1657         309 :         wps->cred.encr_type = wps->encr_type;
    1658             :         /*
    1659             :          * Set MAC address in the Credential to be the Enrollee's MAC address
    1660             :          */
    1661         309 :         os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
    1662             : 
    1663         316 :         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
    1664          14 :             !wps->wps->registrar->disable_auto_conf) {
    1665             :                 u8 r[16];
    1666             :                 /* Generate a random passphrase */
    1667           7 :                 if (random_pool_ready() != 1 ||
    1668           7 :                     random_get_bytes(r, sizeof(r)) < 0) {
    1669           0 :                         wpa_printf(MSG_INFO,
    1670             :                                    "WPS: Could not generate random PSK");
    1671           0 :                         return -1;
    1672             :                 }
    1673           7 :                 os_free(wps->new_psk);
    1674           7 :                 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
    1675           7 :                 if (wps->new_psk == NULL)
    1676           0 :                         return -1;
    1677           7 :                 wps->new_psk_len--; /* remove newline */
    1678          49 :                 while (wps->new_psk_len &&
    1679          21 :                        wps->new_psk[wps->new_psk_len - 1] == '=')
    1680          14 :                         wps->new_psk_len--;
    1681          14 :                 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
    1682           7 :                                       wps->new_psk, wps->new_psk_len);
    1683           7 :                 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
    1684           7 :                 wps->cred.key_len = wps->new_psk_len;
    1685         596 :         } else if (!wps->wps->registrar->force_per_enrollee_psk &&
    1686         758 :                    wps->use_psk_key && wps->wps->psk_set) {
    1687             :                 char hex[65];
    1688         232 :                 wpa_printf(MSG_DEBUG, "WPS: Use PSK format for Network Key");
    1689         232 :                 wpa_snprintf_hex(hex, sizeof(hex), wps->wps->psk, 32);
    1690         232 :                 os_memcpy(wps->cred.key, hex, 32 * 2);
    1691         232 :                 wps->cred.key_len = 32 * 2;
    1692         132 :         } else if (!wps->wps->registrar->force_per_enrollee_psk &&
    1693          62 :                    wps->wps->network_key) {
    1694          55 :                 os_memcpy(wps->cred.key, wps->wps->network_key,
    1695             :                           wps->wps->network_key_len);
    1696          55 :                 wps->cred.key_len = wps->wps->network_key_len;
    1697          15 :         } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
    1698             :                 char hex[65];
    1699             :                 /* Generate a random per-device PSK */
    1700          15 :                 os_free(wps->new_psk);
    1701          15 :                 wps->new_psk_len = 32;
    1702          15 :                 wps->new_psk = os_malloc(wps->new_psk_len);
    1703          15 :                 if (wps->new_psk == NULL)
    1704           3 :                         return -1;
    1705          14 :                 if (random_pool_ready() != 1 ||
    1706          14 :                     random_get_bytes(wps->new_psk, wps->new_psk_len) < 0) {
    1707           1 :                         wpa_printf(MSG_INFO,
    1708             :                                    "WPS: Could not generate random PSK");
    1709           1 :                         os_free(wps->new_psk);
    1710           1 :                         wps->new_psk = NULL;
    1711           1 :                         return -1;
    1712             :                 }
    1713          26 :                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
    1714          13 :                                 wps->new_psk, wps->new_psk_len);
    1715          13 :                 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
    1716             :                                  wps->new_psk_len);
    1717          13 :                 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
    1718          13 :                 wps->cred.key_len = wps->new_psk_len * 2;
    1719             :         }
    1720             : 
    1721             : use_provided:
    1722             : #ifdef CONFIG_WPS_TESTING
    1723         320 :         if (wps_testing_dummy_cred)
    1724           1 :                 cred = wpabuf_alloc(200);
    1725             :         else
    1726         319 :                 cred = NULL;
    1727         320 :         if (cred) {
    1728             :                 struct wps_credential dummy;
    1729           1 :                 wpa_printf(MSG_DEBUG, "WPS: Add dummy credential");
    1730           1 :                 os_memset(&dummy, 0, sizeof(dummy));
    1731           1 :                 os_memcpy(dummy.ssid, "dummy", 5);
    1732           1 :                 dummy.ssid_len = 5;
    1733           1 :                 dummy.auth_type = WPS_AUTH_WPA2PSK;
    1734           1 :                 dummy.encr_type = WPS_ENCR_AES;
    1735           1 :                 os_memcpy(dummy.key, "dummy psk", 9);
    1736           1 :                 dummy.key_len = 9;
    1737           1 :                 os_memcpy(dummy.mac_addr, wps->mac_addr_e, ETH_ALEN);
    1738           1 :                 wps_build_credential(cred, &dummy);
    1739           1 :                 wpa_hexdump_buf(MSG_DEBUG, "WPS: Dummy Credential", cred);
    1740             : 
    1741           1 :                 wpabuf_put_be16(msg, ATTR_CRED);
    1742           1 :                 wpabuf_put_be16(msg, wpabuf_len(cred));
    1743           1 :                 wpabuf_put_buf(msg, cred);
    1744             : 
    1745           1 :                 wpabuf_free(cred);
    1746             :         }
    1747             : #endif /* CONFIG_WPS_TESTING */
    1748             : 
    1749         320 :         cred = wpabuf_alloc(200);
    1750         320 :         if (cred == NULL)
    1751           1 :                 return -1;
    1752             : 
    1753         319 :         if (wps_build_credential(cred, &wps->cred)) {
    1754           0 :                 wpabuf_clear_free(cred);
    1755           0 :                 return -1;
    1756             :         }
    1757             : 
    1758         319 :         wpabuf_put_be16(msg, ATTR_CRED);
    1759         319 :         wpabuf_put_be16(msg, wpabuf_len(cred));
    1760         319 :         wpabuf_put_buf(msg, cred);
    1761         319 :         wpabuf_clear_free(cred);
    1762             : 
    1763             : skip_cred_build:
    1764         323 :         if (wps->wps->registrar->extra_cred) {
    1765           4 :                 wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
    1766           4 :                 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
    1767             :         }
    1768             : 
    1769         323 :         return 0;
    1770             : }
    1771             : 
    1772             : 
    1773          48 : static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
    1774             : {
    1775          48 :         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
    1776             : 
    1777          48 :         if (wps_build_credential(msg, &wps->cred))
    1778           0 :                 return -1;
    1779             : 
    1780          48 :         return 0;
    1781             : }
    1782             : 
    1783             : 
    1784          39 : static struct wpabuf * wps_build_ap_cred(struct wps_data *wps)
    1785             : {
    1786             :         struct wpabuf *msg, *plain;
    1787             : 
    1788          39 :         msg = wpabuf_alloc(1000);
    1789          39 :         if (msg == NULL)
    1790           0 :                 return NULL;
    1791             : 
    1792          39 :         plain = wpabuf_alloc(200);
    1793          39 :         if (plain == NULL) {
    1794           0 :                 wpabuf_free(msg);
    1795           0 :                 return NULL;
    1796             :         }
    1797             : 
    1798          39 :         if (wps_build_ap_settings(wps, plain)) {
    1799           0 :                 wpabuf_clear_free(plain);
    1800           0 :                 wpabuf_free(msg);
    1801           0 :                 return NULL;
    1802             :         }
    1803             : 
    1804          39 :         wpabuf_put_be16(msg, ATTR_CRED);
    1805          39 :         wpabuf_put_be16(msg, wpabuf_len(plain));
    1806          39 :         wpabuf_put_buf(msg, plain);
    1807          39 :         wpabuf_clear_free(plain);
    1808             : 
    1809          39 :         return msg;
    1810             : }
    1811             : 
    1812             : 
    1813         459 : static struct wpabuf * wps_build_m2(struct wps_data *wps)
    1814             : {
    1815             :         struct wpabuf *msg;
    1816         459 :         int config_in_m2 = 0;
    1817             : 
    1818         459 :         if (random_get_bytes(wps->nonce_r, WPS_NONCE_LEN) < 0)
    1819           0 :                 return NULL;
    1820         459 :         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
    1821         459 :                     wps->nonce_r, WPS_NONCE_LEN);
    1822         459 :         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
    1823             : 
    1824         459 :         wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
    1825         459 :         msg = wpabuf_alloc(1000);
    1826         459 :         if (msg == NULL)
    1827           0 :                 return NULL;
    1828             : 
    1829         918 :         if (wps_build_version(msg) ||
    1830         918 :             wps_build_msg_type(msg, WPS_M2) ||
    1831         918 :             wps_build_enrollee_nonce(wps, msg) ||
    1832         918 :             wps_build_registrar_nonce(wps, msg) ||
    1833         918 :             wps_build_uuid_r(wps, msg) ||
    1834         917 :             wps_build_public_key(wps, msg) ||
    1835         916 :             wps_derive_keys(wps) ||
    1836         916 :             wps_build_auth_type_flags(wps, msg) ||
    1837         916 :             wps_build_encr_type_flags(wps, msg) ||
    1838         916 :             wps_build_conn_type_flags(wps, msg) ||
    1839         916 :             wps_build_config_methods_r(wps->wps->registrar, msg) ||
    1840         916 :             wps_build_device_attrs(&wps->wps->dev, msg) ||
    1841         458 :             wps_build_rf_bands(&wps->wps->dev, msg,
    1842         916 :                                wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
    1843         916 :             wps_build_assoc_state(wps, msg) ||
    1844         916 :             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
    1845         916 :             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
    1846         916 :             wps_build_os_version(&wps->wps->dev, msg) ||
    1847         458 :             wps_build_wfa_ext(msg, 0, NULL, 0)) {
    1848           1 :                 wpabuf_free(msg);
    1849           1 :                 return NULL;
    1850             :         }
    1851             : 
    1852             : #ifdef CONFIG_WPS_NFC
    1853         482 :         if (wps->nfc_pw_token && wps->nfc_pw_token->pk_hash_provided_oob &&
    1854          24 :             wps->nfc_pw_token->pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
    1855             :                 /*
    1856             :                  * Use abbreviated handshake since public key hash allowed
    1857             :                  * Enrollee to validate our public key similarly to how Enrollee
    1858             :                  * public key was validated. There is no need to validate Device
    1859             :                  * Password in this case.
    1860             :                  */
    1861          16 :                 struct wpabuf *plain = wpabuf_alloc(500);
    1862          32 :                 if (plain == NULL ||
    1863          32 :                     wps_build_cred(wps, plain) ||
    1864          32 :                     wps_build_key_wrap_auth(wps, plain) ||
    1865          16 :                     wps_build_encr_settings(wps, msg, plain)) {
    1866           0 :                         wpabuf_free(msg);
    1867           0 :                         wpabuf_clear_free(plain);
    1868           0 :                         return NULL;
    1869             :                 }
    1870          16 :                 wpabuf_clear_free(plain);
    1871          16 :                 config_in_m2 = 1;
    1872             :         }
    1873             : #endif /* CONFIG_WPS_NFC */
    1874             : 
    1875         458 :         if (wps_build_authenticator(wps, msg)) {
    1876           0 :                 wpabuf_free(msg);
    1877           0 :                 return NULL;
    1878             :         }
    1879             : 
    1880         458 :         wps->int_reg = 1;
    1881         458 :         wps->state = config_in_m2 ? RECV_DONE : RECV_M3;
    1882         458 :         return msg;
    1883             : }
    1884             : 
    1885             : 
    1886          39 : static struct wpabuf * wps_build_m2d(struct wps_data *wps)
    1887             : {
    1888             :         struct wpabuf *msg;
    1889          39 :         u16 err = wps->config_error;
    1890             : 
    1891          39 :         wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
    1892          39 :         msg = wpabuf_alloc(1000);
    1893          39 :         if (msg == NULL)
    1894           0 :                 return NULL;
    1895             : 
    1896          39 :         if (wps->wps->ap && wps->wps->ap_setup_locked &&
    1897             :             err == WPS_CFG_NO_ERROR)
    1898           4 :                 err = WPS_CFG_SETUP_LOCKED;
    1899             : 
    1900          78 :         if (wps_build_version(msg) ||
    1901          78 :             wps_build_msg_type(msg, WPS_M2D) ||
    1902          78 :             wps_build_enrollee_nonce(wps, msg) ||
    1903          78 :             wps_build_registrar_nonce(wps, msg) ||
    1904          78 :             wps_build_uuid_r(wps, msg) ||
    1905          78 :             wps_build_auth_type_flags(wps, msg) ||
    1906          78 :             wps_build_encr_type_flags(wps, msg) ||
    1907          78 :             wps_build_conn_type_flags(wps, msg) ||
    1908          78 :             wps_build_config_methods_r(wps->wps->registrar, msg) ||
    1909          78 :             wps_build_device_attrs(&wps->wps->dev, msg) ||
    1910          39 :             wps_build_rf_bands(&wps->wps->dev, msg,
    1911          78 :                                wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
    1912          78 :             wps_build_assoc_state(wps, msg) ||
    1913          78 :             wps_build_config_error(msg, err) ||
    1914          78 :             wps_build_os_version(&wps->wps->dev, msg) ||
    1915          39 :             wps_build_wfa_ext(msg, 0, NULL, 0)) {
    1916           0 :                 wpabuf_free(msg);
    1917           0 :                 return NULL;
    1918             :         }
    1919             : 
    1920          39 :         wps->state = RECV_M2D_ACK;
    1921          39 :         return msg;
    1922             : }
    1923             : 
    1924             : 
    1925         389 : static struct wpabuf * wps_build_m4(struct wps_data *wps)
    1926             : {
    1927             :         struct wpabuf *msg, *plain;
    1928             : 
    1929         389 :         wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
    1930             : 
    1931         389 :         if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
    1932           0 :                 return NULL;
    1933             : 
    1934         389 :         plain = wpabuf_alloc(200);
    1935         389 :         if (plain == NULL)
    1936           0 :                 return NULL;
    1937             : 
    1938         389 :         msg = wpabuf_alloc(1000);
    1939         389 :         if (msg == NULL) {
    1940           0 :                 wpabuf_free(plain);
    1941           0 :                 return NULL;
    1942             :         }
    1943             : 
    1944         778 :         if (wps_build_version(msg) ||
    1945         778 :             wps_build_msg_type(msg, WPS_M4) ||
    1946         778 :             wps_build_enrollee_nonce(wps, msg) ||
    1947         778 :             wps_build_r_hash(wps, msg) ||
    1948         778 :             wps_build_r_snonce1(wps, plain) ||
    1949         778 :             wps_build_key_wrap_auth(wps, plain) ||
    1950         777 :             wps_build_encr_settings(wps, msg, plain) ||
    1951         776 :             wps_build_wfa_ext(msg, 0, NULL, 0) ||
    1952         388 :             wps_build_authenticator(wps, msg)) {
    1953           1 :                 wpabuf_clear_free(plain);
    1954           1 :                 wpabuf_free(msg);
    1955           1 :                 return NULL;
    1956             :         }
    1957         388 :         wpabuf_clear_free(plain);
    1958             : 
    1959         388 :         wps->state = RECV_M5;
    1960         388 :         return msg;
    1961             : }
    1962             : 
    1963             : 
    1964         367 : static struct wpabuf * wps_build_m6(struct wps_data *wps)
    1965             : {
    1966             :         struct wpabuf *msg, *plain;
    1967             : 
    1968         367 :         wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
    1969             : 
    1970         367 :         plain = wpabuf_alloc(200);
    1971         367 :         if (plain == NULL)
    1972           0 :                 return NULL;
    1973             : 
    1974         367 :         msg = wpabuf_alloc(1000);
    1975         367 :         if (msg == NULL) {
    1976           0 :                 wpabuf_free(plain);
    1977           0 :                 return NULL;
    1978             :         }
    1979             : 
    1980         734 :         if (wps_build_version(msg) ||
    1981         734 :             wps_build_msg_type(msg, WPS_M6) ||
    1982         734 :             wps_build_enrollee_nonce(wps, msg) ||
    1983         734 :             wps_build_r_snonce2(wps, plain) ||
    1984         734 :             wps_build_key_wrap_auth(wps, plain) ||
    1985         734 :             wps_build_encr_settings(wps, msg, plain) ||
    1986         734 :             wps_build_wfa_ext(msg, 0, NULL, 0) ||
    1987         367 :             wps_build_authenticator(wps, msg)) {
    1988           0 :                 wpabuf_clear_free(plain);
    1989           0 :                 wpabuf_free(msg);
    1990           0 :                 return NULL;
    1991             :         }
    1992         367 :         wpabuf_clear_free(plain);
    1993             : 
    1994         367 :         wps->wps_pin_revealed = 1;
    1995         367 :         wps->state = RECV_M7;
    1996         367 :         return msg;
    1997             : }
    1998             : 
    1999             : 
    2000         314 : static struct wpabuf * wps_build_m8(struct wps_data *wps)
    2001             : {
    2002             :         struct wpabuf *msg, *plain;
    2003             : 
    2004         314 :         wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
    2005             : 
    2006         314 :         plain = wpabuf_alloc(500);
    2007         314 :         if (plain == NULL)
    2008           0 :                 return NULL;
    2009             : 
    2010         314 :         msg = wpabuf_alloc(1000);
    2011         314 :         if (msg == NULL) {
    2012           0 :                 wpabuf_free(plain);
    2013           0 :                 return NULL;
    2014             :         }
    2015             : 
    2016         628 :         if (wps_build_version(msg) ||
    2017         628 :             wps_build_msg_type(msg, WPS_M8) ||
    2018         628 :             wps_build_enrollee_nonce(wps, msg) ||
    2019         643 :             ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
    2020         640 :             (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
    2021         622 :             wps_build_key_wrap_auth(wps, plain) ||
    2022         622 :             wps_build_encr_settings(wps, msg, plain) ||
    2023         622 :             wps_build_wfa_ext(msg, 0, NULL, 0) ||
    2024         311 :             wps_build_authenticator(wps, msg)) {
    2025           3 :                 wpabuf_clear_free(plain);
    2026           3 :                 wpabuf_clear_free(msg);
    2027           3 :                 return NULL;
    2028             :         }
    2029         311 :         wpabuf_clear_free(plain);
    2030             : 
    2031         311 :         wps->state = RECV_DONE;
    2032         311 :         return msg;
    2033             : }
    2034             : 
    2035             : 
    2036        1685 : struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
    2037             :                                       enum wsc_op_code *op_code)
    2038             : {
    2039             :         struct wpabuf *msg;
    2040             : 
    2041             : #ifdef CONFIG_WPS_UPNP
    2042        1685 :         if (!wps->int_reg && wps->wps->wps_upnp) {
    2043          52 :                 struct upnp_pending_message *p, *prev = NULL;
    2044          52 :                 if (wps->ext_reg > 1)
    2045          27 :                         wps_registrar_free_pending_m2(wps->wps);
    2046          52 :                 p = wps->wps->upnp_msgs;
    2047             :                 /* TODO: check pending message MAC address */
    2048         104 :                 while (p && p->next) {
    2049           0 :                         prev = p;
    2050           0 :                         p = p->next;
    2051             :                 }
    2052          52 :                 if (p) {
    2053          39 :                         wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
    2054             :                                    "UPnP");
    2055          39 :                         if (prev)
    2056           0 :                                 prev->next = NULL;
    2057             :                         else
    2058          39 :                                 wps->wps->upnp_msgs = NULL;
    2059          39 :                         msg = p->msg;
    2060          39 :                         switch (p->type) {
    2061             :                         case WPS_WSC_ACK:
    2062           0 :                                 *op_code = WSC_ACK;
    2063           0 :                                 break;
    2064             :                         case WPS_WSC_NACK:
    2065           0 :                                 *op_code = WSC_NACK;
    2066           0 :                                 break;
    2067             :                         default:
    2068          39 :                                 *op_code = WSC_MSG;
    2069          39 :                                 break;
    2070             :                         }
    2071          39 :                         os_free(p);
    2072          39 :                         if (wps->ext_reg == 0)
    2073           0 :                                 wps->ext_reg = 1;
    2074          39 :                         return msg;
    2075             :                 }
    2076             :         }
    2077        1646 :         if (wps->ext_reg) {
    2078           0 :                 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
    2079             :                            "pending message available");
    2080           0 :                 return NULL;
    2081             :         }
    2082             : #endif /* CONFIG_WPS_UPNP */
    2083             : 
    2084        1646 :         switch (wps->state) {
    2085             :         case SEND_M2:
    2086         489 :                 if (wps_get_dev_password(wps) < 0)
    2087          30 :                         msg = wps_build_m2d(wps);
    2088             :                 else
    2089         459 :                         msg = wps_build_m2(wps);
    2090         489 :                 *op_code = WSC_MSG;
    2091         489 :                 break;
    2092             :         case SEND_M2D:
    2093           9 :                 msg = wps_build_m2d(wps);
    2094           9 :                 *op_code = WSC_MSG;
    2095           9 :                 break;
    2096             :         case SEND_M4:
    2097         389 :                 msg = wps_build_m4(wps);
    2098         389 :                 *op_code = WSC_MSG;
    2099         389 :                 break;
    2100             :         case SEND_M6:
    2101         367 :                 msg = wps_build_m6(wps);
    2102         367 :                 *op_code = WSC_MSG;
    2103         367 :                 break;
    2104             :         case SEND_M8:
    2105         314 :                 msg = wps_build_m8(wps);
    2106         314 :                 *op_code = WSC_MSG;
    2107         314 :                 break;
    2108             :         case RECV_DONE:
    2109           6 :                 msg = wps_build_wsc_ack(wps);
    2110           6 :                 *op_code = WSC_ACK;
    2111           6 :                 break;
    2112             :         case SEND_WSC_NACK:
    2113          72 :                 msg = wps_build_wsc_nack(wps);
    2114          72 :                 *op_code = WSC_NACK;
    2115          72 :                 break;
    2116             :         default:
    2117           0 :                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
    2118           0 :                            "a message", wps->state);
    2119           0 :                 msg = NULL;
    2120           0 :                 break;
    2121             :         }
    2122             : 
    2123        1646 :         if (*op_code == WSC_MSG && msg) {
    2124             :                 /* Save a copy of the last message for Authenticator derivation
    2125             :                  */
    2126        1563 :                 wpabuf_free(wps->last_msg);
    2127        1563 :                 wps->last_msg = wpabuf_dup(msg);
    2128             :         }
    2129             : 
    2130        1646 :         return msg;
    2131             : }
    2132             : 
    2133             : 
    2134         522 : static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
    2135             : {
    2136         522 :         if (e_nonce == NULL) {
    2137           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
    2138           1 :                 return -1;
    2139             :         }
    2140             : 
    2141         521 :         os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
    2142         521 :         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
    2143         521 :                     wps->nonce_e, WPS_NONCE_LEN);
    2144             : 
    2145         521 :         return 0;
    2146             : }
    2147             : 
    2148             : 
    2149        1120 : static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
    2150             : {
    2151        1120 :         if (r_nonce == NULL) {
    2152           0 :                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
    2153           0 :                 return -1;
    2154             :         }
    2155             : 
    2156        1120 :         if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
    2157           0 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
    2158           0 :                 return -1;
    2159             :         }
    2160             : 
    2161        1120 :         return 0;
    2162             : }
    2163             : 
    2164             : 
    2165         524 : static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
    2166             : {
    2167         524 :         if (uuid_e == NULL) {
    2168           1 :                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
    2169           1 :                 return -1;
    2170             :         }
    2171             : 
    2172         523 :         os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
    2173         523 :         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
    2174             : 
    2175         523 :         return 0;
    2176             : }
    2177             : 
    2178             : 
    2179         501 : static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
    2180             : {
    2181         501 :         if (pw_id == NULL) {
    2182           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
    2183           1 :                 return -1;
    2184             :         }
    2185             : 
    2186         500 :         wps->dev_pw_id = WPA_GET_BE16(pw_id);
    2187         500 :         wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
    2188             : 
    2189         500 :         return 0;
    2190             : }
    2191             : 
    2192             : 
    2193         391 : static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
    2194             : {
    2195         391 :         if (e_hash1 == NULL) {
    2196           1 :                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
    2197           1 :                 return -1;
    2198             :         }
    2199             : 
    2200         390 :         os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
    2201         390 :         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
    2202             : 
    2203         390 :         return 0;
    2204             : }
    2205             : 
    2206             : 
    2207         390 : static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
    2208             : {
    2209         390 :         if (e_hash2 == NULL) {
    2210           1 :                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
    2211           1 :                 return -1;
    2212             :         }
    2213             : 
    2214         389 :         os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
    2215         389 :         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
    2216             : 
    2217         389 :         return 0;
    2218             : }
    2219             : 
    2220             : 
    2221         369 : static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
    2222             : {
    2223             :         u8 hash[SHA256_MAC_LEN];
    2224             :         const u8 *addr[4];
    2225             :         size_t len[4];
    2226             : 
    2227         369 :         if (e_snonce1 == NULL) {
    2228           1 :                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
    2229           1 :                 return -1;
    2230             :         }
    2231             : 
    2232         368 :         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
    2233             :                         WPS_SECRET_NONCE_LEN);
    2234             : 
    2235             :         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
    2236         368 :         addr[0] = e_snonce1;
    2237         368 :         len[0] = WPS_SECRET_NONCE_LEN;
    2238         368 :         addr[1] = wps->psk1;
    2239         368 :         len[1] = WPS_PSK_LEN;
    2240         368 :         addr[2] = wpabuf_head(wps->dh_pubkey_e);
    2241         368 :         len[2] = wpabuf_len(wps->dh_pubkey_e);
    2242         368 :         addr[3] = wpabuf_head(wps->dh_pubkey_r);
    2243         368 :         len[3] = wpabuf_len(wps->dh_pubkey_r);
    2244         368 :         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    2245             : 
    2246         368 :         if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
    2247           1 :                 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
    2248             :                            "not match with the pre-committed value");
    2249           1 :                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
    2250           1 :                 wps_pwd_auth_fail_event(wps->wps, 0, 1, wps->mac_addr_e);
    2251           1 :                 return -1;
    2252             :         }
    2253             : 
    2254         367 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
    2255             :                    "half of the device password");
    2256             : 
    2257         367 :         return 0;
    2258             : }
    2259             : 
    2260             : 
    2261         355 : static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
    2262             : {
    2263             :         u8 hash[SHA256_MAC_LEN];
    2264             :         const u8 *addr[4];
    2265             :         size_t len[4];
    2266             : 
    2267         355 :         if (e_snonce2 == NULL) {
    2268           1 :                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
    2269           1 :                 return -1;
    2270             :         }
    2271             : 
    2272         354 :         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
    2273             :                         WPS_SECRET_NONCE_LEN);
    2274             : 
    2275             :         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
    2276         354 :         addr[0] = e_snonce2;
    2277         354 :         len[0] = WPS_SECRET_NONCE_LEN;
    2278         354 :         addr[1] = wps->psk2;
    2279         354 :         len[1] = WPS_PSK_LEN;
    2280         354 :         addr[2] = wpabuf_head(wps->dh_pubkey_e);
    2281         354 :         len[2] = wpabuf_len(wps->dh_pubkey_e);
    2282         354 :         addr[3] = wpabuf_head(wps->dh_pubkey_r);
    2283         354 :         len[3] = wpabuf_len(wps->dh_pubkey_r);
    2284         354 :         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
    2285             : 
    2286         354 :         if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
    2287           1 :                 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
    2288             :                            "not match with the pre-committed value");
    2289           1 :                 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
    2290           1 :                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
    2291           1 :                 wps_pwd_auth_fail_event(wps->wps, 0, 2, wps->mac_addr_e);
    2292           1 :                 return -1;
    2293             :         }
    2294             : 
    2295         353 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
    2296             :                    "half of the device password");
    2297         353 :         wps->wps_pin_revealed = 0;
    2298         353 :         wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
    2299             : 
    2300             :         /*
    2301             :          * In case wildcard PIN is used and WPS handshake succeeds in the first
    2302             :          * attempt, wps_registrar_unlock_pin() would not free the PIN, so make
    2303             :          * sure the PIN gets invalidated here.
    2304             :          */
    2305         353 :         wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
    2306             : 
    2307         353 :         return 0;
    2308             : }
    2309             : 
    2310             : 
    2311         523 : static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
    2312             : {
    2313         523 :         if (mac_addr == NULL) {
    2314           1 :                 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
    2315           1 :                 return -1;
    2316             :         }
    2317             : 
    2318        3132 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
    2319        3132 :                    MAC2STR(mac_addr));
    2320         522 :         os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
    2321         522 :         os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
    2322             : 
    2323         522 :         return 0;
    2324             : }
    2325             : 
    2326             : 
    2327         521 : static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
    2328             :                               size_t pk_len)
    2329             : {
    2330         521 :         if (pk == NULL || pk_len == 0) {
    2331           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
    2332           1 :                 return -1;
    2333             :         }
    2334             : 
    2335         520 :         wpabuf_free(wps->dh_pubkey_e);
    2336         520 :         wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
    2337         520 :         if (wps->dh_pubkey_e == NULL)
    2338           1 :                 return -1;
    2339             : 
    2340         519 :         return 0;
    2341             : }
    2342             : 
    2343             : 
    2344         519 : static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
    2345             : {
    2346             :         u16 auth_types;
    2347             : 
    2348         519 :         if (auth == NULL) {
    2349           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
    2350             :                            "received");
    2351           1 :                 return -1;
    2352             :         }
    2353             : 
    2354         518 :         auth_types = WPA_GET_BE16(auth);
    2355             : 
    2356         518 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
    2357             :                    auth_types);
    2358             : #ifdef WPS_WORKAROUNDS
    2359             :         /*
    2360             :          * Some deployed implementations seem to advertise incorrect information
    2361             :          * in this attribute. A value of 0x1b (WPA2 + WPA + WPAPSK + OPEN, but
    2362             :          * no WPA2PSK) has been reported to be used. Add WPA2PSK to the list to
    2363             :          * avoid issues with building Credentials that do not use the strongest
    2364             :          * actually supported authentication option (that device does support
    2365             :          * WPA2PSK even when it does not claim it here).
    2366             :          */
    2367         518 :         if ((auth_types &
    2368             :              (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) ==
    2369             :             (WPS_AUTH_WPA2 | WPS_AUTH_WPAPSK)) {
    2370           1 :                 wpa_printf(MSG_DEBUG,
    2371             :                            "WPS: Workaround - assume Enrollee supports WPA2PSK based on claimed WPA2 support");
    2372           1 :                 auth_types |= WPS_AUTH_WPA2PSK;
    2373             :         }
    2374             : #endif /* WPS_WORKAROUNDS */
    2375         518 :         wps->auth_type = wps->wps->auth_types & auth_types;
    2376         518 :         if (wps->auth_type == 0) {
    2377         122 :                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
    2378             :                            "authentication types (own 0x%x Enrollee 0x%x)",
    2379          61 :                            wps->wps->auth_types, auth_types);
    2380             : #ifdef WPS_WORKAROUNDS
    2381             :                 /*
    2382             :                  * Some deployed implementations seem to advertise incorrect
    2383             :                  * information in this attribute. For example, Linksys WRT350N
    2384             :                  * seems to have a byteorder bug that breaks this negotiation.
    2385             :                  * In order to interoperate with existing implementations,
    2386             :                  * assume that the Enrollee supports everything we do.
    2387             :                  */
    2388          61 :                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
    2389             :                            "does not advertise supported authentication types "
    2390             :                            "correctly");
    2391          61 :                 wps->auth_type = wps->wps->auth_types;
    2392             : #else /* WPS_WORKAROUNDS */
    2393             :                 return -1;
    2394             : #endif /* WPS_WORKAROUNDS */
    2395             :         }
    2396             : 
    2397         518 :         return 0;
    2398             : }
    2399             : 
    2400             : 
    2401         518 : static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
    2402             : {
    2403             :         u16 encr_types;
    2404             : 
    2405         518 :         if (encr == NULL) {
    2406           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
    2407             :                            "received");
    2408           1 :                 return -1;
    2409             :         }
    2410             : 
    2411         517 :         encr_types = WPA_GET_BE16(encr);
    2412             : 
    2413         517 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
    2414             :                    encr_types);
    2415         517 :         wps->encr_type = wps->wps->encr_types & encr_types;
    2416         517 :         if (wps->encr_type == 0) {
    2417         116 :                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
    2418             :                            "encryption types (own 0x%x Enrollee 0x%x)",
    2419          58 :                            wps->wps->encr_types, encr_types);
    2420             : #ifdef WPS_WORKAROUNDS
    2421             :                 /*
    2422             :                  * Some deployed implementations seem to advertise incorrect
    2423             :                  * information in this attribute. For example, Linksys WRT350N
    2424             :                  * seems to have a byteorder bug that breaks this negotiation.
    2425             :                  * In order to interoperate with existing implementations,
    2426             :                  * assume that the Enrollee supports everything we do.
    2427             :                  */
    2428          58 :                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
    2429             :                            "does not advertise supported encryption types "
    2430             :                            "correctly");
    2431          58 :                 wps->encr_type = wps->wps->encr_types;
    2432             : #else /* WPS_WORKAROUNDS */
    2433             :                 return -1;
    2434             : #endif /* WPS_WORKAROUNDS */
    2435             :         }
    2436             : 
    2437         517 :         return 0;
    2438             : }
    2439             : 
    2440             : 
    2441         517 : static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
    2442             : {
    2443         517 :         if (conn == NULL) {
    2444           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
    2445             :                            "received");
    2446           1 :                 return -1;
    2447             :         }
    2448             : 
    2449         516 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
    2450         516 :                    *conn);
    2451             : 
    2452         516 :         return 0;
    2453             : }
    2454             : 
    2455             : 
    2456         516 : static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
    2457             : {
    2458             :         u16 m;
    2459             : 
    2460         516 :         if (methods == NULL) {
    2461           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
    2462           1 :                 return -1;
    2463             :         }
    2464             : 
    2465         515 :         m = WPA_GET_BE16(methods);
    2466             : 
    2467        4635 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x"
    2468             :                    "%s%s%s%s%s%s%s%s%s", m,
    2469         515 :                    m & WPS_CONFIG_USBA ? " [USBA]" : "",
    2470         515 :                    m & WPS_CONFIG_ETHERNET ? " [Ethernet]" : "",
    2471         515 :                    m & WPS_CONFIG_LABEL ? " [Label]" : "",
    2472         515 :                    m & WPS_CONFIG_DISPLAY ? " [Display]" : "",
    2473         515 :                    m & WPS_CONFIG_EXT_NFC_TOKEN ? " [Ext NFC Token]" : "",
    2474         515 :                    m & WPS_CONFIG_INT_NFC_TOKEN ? " [Int NFC Token]" : "",
    2475         515 :                    m & WPS_CONFIG_NFC_INTERFACE ? " [NFC]" : "",
    2476         515 :                    m & WPS_CONFIG_PUSHBUTTON ? " [PBC]" : "",
    2477         515 :                    m & WPS_CONFIG_KEYPAD ? " [Keypad]" : "");
    2478             : 
    2479         515 :         if (!(m & WPS_CONFIG_DISPLAY) && !wps->use_psk_key) {
    2480             :                 /*
    2481             :                  * The Enrollee does not have a display so it is unlikely to be
    2482             :                  * able to show the passphrase to a user and as such, could
    2483             :                  * benefit from receiving PSK to reduce key derivation time.
    2484             :                  */
    2485          92 :                 wpa_printf(MSG_DEBUG, "WPS: Prefer PSK format key due to "
    2486             :                            "Enrollee not supporting display");
    2487          92 :                 wps->use_psk_key = 1;
    2488             :         }
    2489             : 
    2490         515 :         return 0;
    2491             : }
    2492             : 
    2493             : 
    2494         515 : static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
    2495             : {
    2496         515 :         if (state == NULL) {
    2497           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
    2498             :                            "received");
    2499           1 :                 return -1;
    2500             :         }
    2501             : 
    2502         514 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
    2503         514 :                    *state);
    2504             : 
    2505         514 :         return 0;
    2506             : }
    2507             : 
    2508             : 
    2509         502 : static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
    2510             : {
    2511             :         u16 a;
    2512             : 
    2513         502 :         if (assoc == NULL) {
    2514           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
    2515           1 :                 return -1;
    2516             :         }
    2517             : 
    2518         501 :         a = WPA_GET_BE16(assoc);
    2519         501 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
    2520             : 
    2521         501 :         return 0;
    2522             : }
    2523             : 
    2524             : 
    2525         500 : static int wps_process_config_error(struct wps_data *wps, const u8 *err)
    2526             : {
    2527             :         u16 e;
    2528             : 
    2529         500 :         if (err == NULL) {
    2530           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
    2531           1 :                 return -1;
    2532             :         }
    2533             : 
    2534         499 :         e = WPA_GET_BE16(err);
    2535         499 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
    2536             : 
    2537         499 :         return 0;
    2538             : }
    2539             : 
    2540             : 
    2541          78 : static int wps_registrar_p2p_dev_addr_match(struct wps_data *wps)
    2542             : {
    2543             : #ifdef CONFIG_P2P
    2544          29 :         struct wps_registrar *reg = wps->wps->registrar;
    2545             : 
    2546          29 :         if (is_zero_ether_addr(reg->p2p_dev_addr))
    2547           5 :                 return 1; /* no filtering in use */
    2548             : 
    2549          24 :         if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) != 0) {
    2550          12 :                 wpa_printf(MSG_DEBUG, "WPS: No match on P2P Device Address "
    2551             :                            "filtering for PBC: expected " MACSTR " was "
    2552             :                            MACSTR " - indicate PBC session overlap",
    2553           6 :                            MAC2STR(reg->p2p_dev_addr),
    2554           6 :                            MAC2STR(wps->p2p_dev_addr));
    2555           1 :                 return 0;
    2556             :         }
    2557             : #endif /* CONFIG_P2P */
    2558          72 :         return 1;
    2559             : }
    2560             : 
    2561             : 
    2562           9 : static int wps_registrar_skip_overlap(struct wps_data *wps)
    2563             : {
    2564             : #ifdef CONFIG_P2P
    2565           7 :         struct wps_registrar *reg = wps->wps->registrar;
    2566             : 
    2567           7 :         if (is_zero_ether_addr(reg->p2p_dev_addr))
    2568           2 :                 return 0; /* no specific Enrollee selected */
    2569             : 
    2570           5 :         if (os_memcmp(reg->p2p_dev_addr, wps->p2p_dev_addr, ETH_ALEN) == 0) {
    2571           4 :                 wpa_printf(MSG_DEBUG, "WPS: Skip PBC overlap due to selected "
    2572             :                            "Enrollee match");
    2573           4 :                 return 1;
    2574             :         }
    2575             : #endif /* CONFIG_P2P */
    2576           3 :         return 0;
    2577             : }
    2578             : 
    2579             : 
    2580         525 : static enum wps_process_res wps_process_m1(struct wps_data *wps,
    2581             :                                            struct wps_parse_attr *attr)
    2582             : {
    2583         525 :         wpa_printf(MSG_DEBUG, "WPS: Received M1");
    2584             : 
    2585         525 :         if (wps->state != RECV_M1) {
    2586           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    2587           1 :                            "receiving M1", wps->state);
    2588           1 :                 return WPS_FAILURE;
    2589             :         }
    2590             : 
    2591        1047 :         if (wps_process_uuid_e(wps, attr->uuid_e) ||
    2592        1045 :             wps_process_mac_addr(wps, attr->mac_addr) ||
    2593        1043 :             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
    2594        1040 :             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
    2595        1037 :             wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
    2596        1035 :             wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
    2597        1033 :             wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
    2598        1031 :             wps_process_config_methods(wps, attr->config_methods) ||
    2599        1029 :             wps_process_wps_state(wps, attr->wps_state) ||
    2600        1017 :             wps_process_device_attrs(&wps->peer_dev, attr) ||
    2601        1005 :             wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
    2602        1003 :             wps_process_assoc_state(wps, attr->assoc_state) ||
    2603        1001 :             wps_process_dev_password_id(wps, attr->dev_password_id) ||
    2604         999 :             wps_process_config_error(wps, attr->config_error) ||
    2605         499 :             wps_process_os_version(&wps->peer_dev, attr->os_version))
    2606          26 :                 return WPS_FAILURE;
    2607             : 
    2608         981 :         if (wps->dev_pw_id < 0x10 &&
    2609         707 :             wps->dev_pw_id != DEV_PW_DEFAULT &&
    2610         423 :             wps->dev_pw_id != DEV_PW_P2PS_DEFAULT &&
    2611         398 :             wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
    2612         398 :             wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
    2613         305 :             wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
    2614             : #ifdef CONFIG_WPS_NFC
    2615         191 :             wps->dev_pw_id != DEV_PW_NFC_CONNECTION_HANDOVER &&
    2616             : #endif /* CONFIG_WPS_NFC */
    2617         170 :             (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
    2618          85 :              !wps->wps->registrar->pbc)) {
    2619           2 :                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
    2620           2 :                            wps->dev_pw_id);
    2621           2 :                 wps->state = SEND_M2D;
    2622           2 :                 return WPS_CONTINUE;
    2623             :         }
    2624             : 
    2625             : #ifdef CONFIG_WPS_NFC
    2626         977 :         if (wps->dev_pw_id >= 0x10 ||
    2627         481 :             wps->dev_pw_id == DEV_PW_NFC_CONNECTION_HANDOVER) {
    2628             :                 struct wps_nfc_pw_token *token;
    2629             :                 const u8 *addr[1];
    2630             :                 u8 hash[WPS_HASH_LEN];
    2631             : 
    2632          72 :                 wpa_printf(MSG_DEBUG, "WPS: Searching for NFC token match for id=%d (ctx %p registrar %p)",
    2633          72 :                            wps->dev_pw_id, wps->wps, wps->wps->registrar);
    2634          72 :                 token = wps_get_nfc_pw_token(
    2635          72 :                         &wps->wps->registrar->nfc_pw_tokens, wps->dev_pw_id);
    2636          62 :                 if (token && token->peer_pk_hash_known) {
    2637             :                         size_t len;
    2638             : 
    2639          28 :                         wpa_printf(MSG_DEBUG, "WPS: Found matching NFC "
    2640             :                                    "Password Token");
    2641          28 :                         dl_list_del(&token->list);
    2642          28 :                         wps->nfc_pw_token = token;
    2643             : 
    2644          28 :                         addr[0] = attr->public_key;
    2645          28 :                         len = attr->public_key_len;
    2646          28 :                         sha256_vector(1, addr, &len, hash);
    2647          28 :                         if (os_memcmp_const(hash,
    2648          28 :                                             wps->nfc_pw_token->pubkey_hash,
    2649             :                                             WPS_OOB_PUBKEY_HASH_LEN) != 0) {
    2650           2 :                                 wpa_printf(MSG_ERROR, "WPS: Public Key hash "
    2651             :                                            "mismatch");
    2652           2 :                                 wps->state = SEND_M2D;
    2653           2 :                                 wps->config_error =
    2654             :                                         WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
    2655           2 :                                 return WPS_CONTINUE;
    2656             :                         }
    2657           8 :                 } else if (token) {
    2658           2 :                         wpa_printf(MSG_DEBUG, "WPS: Found matching NFC "
    2659             :                                    "Password Token (no peer PK hash)");
    2660           2 :                         wps->nfc_pw_token = token;
    2661           9 :                 } else if (wps->dev_pw_id >= 0x10 &&
    2662           5 :                            wps->wps->ap_nfc_dev_pw_id == wps->dev_pw_id &&
    2663           2 :                            wps->wps->ap_nfc_dev_pw) {
    2664           2 :                         wpa_printf(MSG_DEBUG, "WPS: Found match with own NFC Password Token");
    2665             :                 }
    2666             :         }
    2667             : #endif /* CONFIG_WPS_NFC */
    2668             : 
    2669         494 :         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
    2670         161 :                 if ((wps->wps->registrar->force_pbc_overlap ||
    2671          78 :                      wps_registrar_pbc_overlap(wps->wps->registrar,
    2672         156 :                                                wps->mac_addr_e, wps->uuid_e) ||
    2673          84 :                      !wps_registrar_p2p_dev_addr_match(wps)) &&
    2674           6 :                     !wps_registrar_skip_overlap(wps)) {
    2675           5 :                         wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
    2676             :                                    "negotiation");
    2677           5 :                         wps->state = SEND_M2D;
    2678           5 :                         wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
    2679           5 :                         wps_pbc_overlap_event(wps->wps);
    2680           5 :                         wps_fail_event(wps->wps, WPS_M1,
    2681             :                                        WPS_CFG_MULTIPLE_PBC_DETECTED,
    2682           5 :                                        WPS_EI_NO_ERROR, wps->mac_addr_e);
    2683           5 :                         wps->wps->registrar->force_pbc_overlap = 1;
    2684           5 :                         return WPS_CONTINUE;
    2685             :                 }
    2686          78 :                 wps_registrar_add_pbc_session(wps->wps->registrar,
    2687          78 :                                               wps->mac_addr_e, wps->uuid_e);
    2688          78 :                 wps->pbc = 1;
    2689             :         }
    2690             : 
    2691             : #ifdef WPS_WORKAROUNDS
    2692             :         /*
    2693             :          * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
    2694             :          * passphrase format. To avoid interop issues, force PSK format to be
    2695             :          * used.
    2696             :          */
    2697         662 :         if (!wps->use_psk_key &&
    2698         346 :             wps->peer_dev.manufacturer &&
    2699         174 :             os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
    2700           2 :             wps->peer_dev.model_name &&
    2701           1 :             os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
    2702           1 :                 wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
    2703             :                            "PSK format");
    2704           1 :                 wps->use_psk_key = 1;
    2705             :         }
    2706             : #endif /* WPS_WORKAROUNDS */
    2707             : 
    2708         489 :         wps->state = SEND_M2;
    2709         489 :         return WPS_CONTINUE;
    2710             : }
    2711             : 
    2712             : 
    2713         393 : static enum wps_process_res wps_process_m3(struct wps_data *wps,
    2714             :                                            const struct wpabuf *msg,
    2715             :                                            struct wps_parse_attr *attr)
    2716             : {
    2717         393 :         wpa_printf(MSG_DEBUG, "WPS: Received M3");
    2718             : 
    2719         393 :         if (wps->state != RECV_M3) {
    2720           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    2721           1 :                            "receiving M3", wps->state);
    2722           1 :                 wps->state = SEND_WSC_NACK;
    2723           1 :                 return WPS_CONTINUE;
    2724             :         }
    2725             : 
    2726         393 :         if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
    2727           1 :             !wps_registrar_skip_overlap(wps)) {
    2728           0 :                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
    2729             :                            "session overlap");
    2730           0 :                 wps->state = SEND_WSC_NACK;
    2731           0 :                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
    2732           0 :                 return WPS_CONTINUE;
    2733             :         }
    2734             : 
    2735         784 :         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
    2736         783 :             wps_process_authenticator(wps, attr->authenticator, msg) ||
    2737         781 :             wps_process_e_hash1(wps, attr->e_hash1) ||
    2738         390 :             wps_process_e_hash2(wps, attr->e_hash2)) {
    2739           3 :                 wps->state = SEND_WSC_NACK;
    2740           3 :                 return WPS_CONTINUE;
    2741             :         }
    2742             : 
    2743         389 :         wps->state = SEND_M4;
    2744         389 :         return WPS_CONTINUE;
    2745             : }
    2746             : 
    2747             : 
    2748         372 : static enum wps_process_res wps_process_m5(struct wps_data *wps,
    2749             :                                            const struct wpabuf *msg,
    2750             :                                            struct wps_parse_attr *attr)
    2751             : {
    2752             :         struct wpabuf *decrypted;
    2753             :         struct wps_parse_attr eattr;
    2754             : 
    2755         372 :         wpa_printf(MSG_DEBUG, "WPS: Received M5");
    2756             : 
    2757         372 :         if (wps->state != RECV_M5) {
    2758           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    2759           1 :                            "receiving M5", wps->state);
    2760           1 :                 wps->state = SEND_WSC_NACK;
    2761           1 :                 return WPS_CONTINUE;
    2762             :         }
    2763             : 
    2764         372 :         if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
    2765           1 :             !wps_registrar_skip_overlap(wps)) {
    2766           0 :                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
    2767             :                            "session overlap");
    2768           0 :                 wps->state = SEND_WSC_NACK;
    2769           0 :                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
    2770           0 :                 return WPS_CONTINUE;
    2771             :         }
    2772             : 
    2773         742 :         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
    2774         371 :             wps_process_authenticator(wps, attr->authenticator, msg)) {
    2775           1 :                 wps->state = SEND_WSC_NACK;
    2776           1 :                 return WPS_CONTINUE;
    2777             :         }
    2778             : 
    2779         370 :         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
    2780         370 :                                               attr->encr_settings_len);
    2781         370 :         if (decrypted == NULL) {
    2782           1 :                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
    2783             :                            "Settings attribute");
    2784           1 :                 wps->state = SEND_WSC_NACK;
    2785           1 :                 return WPS_CONTINUE;
    2786             :         }
    2787             : 
    2788         369 :         if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) {
    2789           0 :                 wpabuf_clear_free(decrypted);
    2790           0 :                 wps->state = SEND_WSC_NACK;
    2791           0 :                 return WPS_CONTINUE;
    2792             :         }
    2793             : 
    2794         369 :         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
    2795             :                    "attribute");
    2796         738 :         if (wps_parse_msg(decrypted, &eattr) < 0 ||
    2797         738 :             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
    2798         369 :             wps_process_e_snonce1(wps, eattr.e_snonce1)) {
    2799           2 :                 wpabuf_clear_free(decrypted);
    2800           2 :                 wps->state = SEND_WSC_NACK;
    2801           2 :                 return WPS_CONTINUE;
    2802             :         }
    2803         367 :         wpabuf_clear_free(decrypted);
    2804             : 
    2805         367 :         wps->state = SEND_M6;
    2806         367 :         return WPS_CONTINUE;
    2807             : }
    2808             : 
    2809             : 
    2810          37 : static void wps_sta_cred_cb(struct wps_data *wps)
    2811             : {
    2812             :         /*
    2813             :          * Update credential to only include a single authentication and
    2814             :          * encryption type in case the AP configuration includes more than one
    2815             :          * option.
    2816             :          */
    2817          37 :         if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
    2818          34 :                 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
    2819           3 :         else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
    2820           1 :                 wps->cred.auth_type = WPS_AUTH_WPAPSK;
    2821          37 :         if (wps->cred.encr_type & WPS_ENCR_AES)
    2822          34 :                 wps->cred.encr_type = WPS_ENCR_AES;
    2823           3 :         else if (wps->cred.encr_type & WPS_ENCR_TKIP)
    2824           1 :                 wps->cred.encr_type = WPS_ENCR_TKIP;
    2825          37 :         wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
    2826             :                    "AP configuration");
    2827          37 :         if (wps->wps->cred_cb)
    2828          37 :                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
    2829          37 : }
    2830             : 
    2831             : 
    2832           9 : static void wps_cred_update(struct wps_credential *dst,
    2833             :                             struct wps_credential *src)
    2834             : {
    2835           9 :         os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
    2836           9 :         dst->ssid_len = src->ssid_len;
    2837           9 :         dst->auth_type = src->auth_type;
    2838           9 :         dst->encr_type = src->encr_type;
    2839           9 :         dst->key_idx = src->key_idx;
    2840           9 :         os_memcpy(dst->key, src->key, sizeof(dst->key));
    2841           9 :         dst->key_len = src->key_len;
    2842           9 : }
    2843             : 
    2844             : 
    2845         353 : static int wps_process_ap_settings_r(struct wps_data *wps,
    2846             :                                      struct wps_parse_attr *attr)
    2847             : {
    2848             :         struct wpabuf *msg;
    2849             : 
    2850         353 :         if (wps->wps->ap || wps->er)
    2851         305 :                 return 0;
    2852             : 
    2853             :         /* AP Settings Attributes in M7 when Enrollee is an AP */
    2854          48 :         if (wps_process_ap_settings(attr, &wps->cred) < 0)
    2855           0 :                 return -1;
    2856             : 
    2857          48 :         wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
    2858             : 
    2859          48 :         if (wps->new_ap_settings) {
    2860           9 :                 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
    2861             :                            "new settings");
    2862           9 :                 wps_cred_update(&wps->cred, wps->new_ap_settings);
    2863           9 :                 return 0;
    2864             :         } else {
    2865             :                 /*
    2866             :                  * Use the AP PIN only to receive the current AP settings, not
    2867             :                  * to reconfigure the AP.
    2868             :                  */
    2869             : 
    2870             :                 /*
    2871             :                  * Clear selected registrar here since we do not get to
    2872             :                  * WSC_Done in this protocol run.
    2873             :                  */
    2874          39 :                 wps_registrar_pin_completed(wps->wps->registrar);
    2875             : 
    2876          39 :                 msg = wps_build_ap_cred(wps);
    2877          39 :                 if (msg == NULL)
    2878           0 :                         return -1;
    2879          39 :                 wps->cred.cred_attr = wpabuf_head(msg);
    2880          39 :                 wps->cred.cred_attr_len = wpabuf_len(msg);
    2881             : 
    2882          39 :                 if (wps->ap_settings_cb) {
    2883          18 :                         wps->ap_settings_cb(wps->ap_settings_cb_ctx,
    2884           9 :                                             &wps->cred);
    2885           9 :                         wpabuf_free(msg);
    2886           9 :                         return 1;
    2887             :                 }
    2888          30 :                 wps_sta_cred_cb(wps);
    2889             : 
    2890          30 :                 wps->cred.cred_attr = NULL;
    2891          30 :                 wps->cred.cred_attr_len = 0;
    2892          30 :                 wpabuf_free(msg);
    2893             : 
    2894          30 :                 return 1;
    2895             :         }
    2896             : }
    2897             : 
    2898             : 
    2899         358 : static enum wps_process_res wps_process_m7(struct wps_data *wps,
    2900             :                                            const struct wpabuf *msg,
    2901             :                                            struct wps_parse_attr *attr)
    2902             : {
    2903             :         struct wpabuf *decrypted;
    2904             :         struct wps_parse_attr eattr;
    2905             : 
    2906         358 :         wpa_printf(MSG_DEBUG, "WPS: Received M7");
    2907             : 
    2908         358 :         if (wps->state != RECV_M7) {
    2909           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    2910           1 :                            "receiving M7", wps->state);
    2911           1 :                 wps->state = SEND_WSC_NACK;
    2912           1 :                 return WPS_CONTINUE;
    2913             :         }
    2914             : 
    2915         358 :         if (wps->pbc && wps->wps->registrar->force_pbc_overlap &&
    2916           1 :             !wps_registrar_skip_overlap(wps)) {
    2917           0 :                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
    2918             :                            "session overlap");
    2919           0 :                 wps->state = SEND_WSC_NACK;
    2920           0 :                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
    2921           0 :                 return WPS_CONTINUE;
    2922             :         }
    2923             : 
    2924         714 :         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
    2925         357 :             wps_process_authenticator(wps, attr->authenticator, msg)) {
    2926           1 :                 wps->state = SEND_WSC_NACK;
    2927           1 :                 return WPS_CONTINUE;
    2928             :         }
    2929             : 
    2930         356 :         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
    2931         356 :                                               attr->encr_settings_len);
    2932         356 :         if (decrypted == NULL) {
    2933           1 :                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
    2934             :                            "Settings attribute");
    2935           1 :                 wps->state = SEND_WSC_NACK;
    2936           1 :                 return WPS_CONTINUE;
    2937             :         }
    2938             : 
    2939         355 :         if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er,
    2940         355 :                                  attr->version2 != NULL) < 0) {
    2941           0 :                 wpabuf_clear_free(decrypted);
    2942           0 :                 wps->state = SEND_WSC_NACK;
    2943           0 :                 return WPS_CONTINUE;
    2944             :         }
    2945             : 
    2946         355 :         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
    2947             :                    "attribute");
    2948         710 :         if (wps_parse_msg(decrypted, &eattr) < 0 ||
    2949         710 :             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
    2950         708 :             wps_process_e_snonce2(wps, eattr.e_snonce2) ||
    2951         353 :             wps_process_ap_settings_r(wps, &eattr)) {
    2952          41 :                 wpabuf_clear_free(decrypted);
    2953          41 :                 wps->state = SEND_WSC_NACK;
    2954          41 :                 return WPS_CONTINUE;
    2955             :         }
    2956             : 
    2957         314 :         wpabuf_clear_free(decrypted);
    2958             : 
    2959         314 :         wps->state = SEND_M8;
    2960         314 :         return WPS_CONTINUE;
    2961             : }
    2962             : 
    2963             : 
    2964        1652 : static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
    2965             :                                                 const struct wpabuf *msg)
    2966             : {
    2967             :         struct wps_parse_attr attr;
    2968        1652 :         enum wps_process_res ret = WPS_CONTINUE;
    2969             : 
    2970        1652 :         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
    2971             : 
    2972        1652 :         if (wps_parse_msg(msg, &attr) < 0)
    2973           1 :                 return WPS_FAILURE;
    2974             : 
    2975        1651 :         if (attr.msg_type == NULL) {
    2976           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
    2977           1 :                 wps->state = SEND_WSC_NACK;
    2978           1 :                 return WPS_CONTINUE;
    2979             :         }
    2980             : 
    2981        2775 :         if (*attr.msg_type != WPS_M1 &&
    2982        2250 :             (attr.registrar_nonce == NULL ||
    2983        1125 :              os_memcmp(wps->nonce_r, attr.registrar_nonce,
    2984             :                        WPS_NONCE_LEN) != 0)) {
    2985           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
    2986           1 :                 return WPS_FAILURE;
    2987             :         }
    2988             : 
    2989        1649 :         switch (*attr.msg_type) {
    2990             :         case WPS_M1:
    2991         525 :                 if (wps_validate_m1(msg) < 0)
    2992           0 :                         return WPS_FAILURE;
    2993             : #ifdef CONFIG_WPS_UPNP
    2994         525 :                 if (wps->wps->wps_upnp && attr.mac_addr) {
    2995             :                         /* Remove old pending messages when starting new run */
    2996          13 :                         wps_free_pending_msgs(wps->wps->upnp_msgs);
    2997          13 :                         wps->wps->upnp_msgs = NULL;
    2998             : 
    2999          26 :                         upnp_wps_device_send_wlan_event(
    3000          13 :                                 wps->wps->wps_upnp, attr.mac_addr,
    3001             :                                 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
    3002             :                 }
    3003             : #endif /* CONFIG_WPS_UPNP */
    3004         525 :                 ret = wps_process_m1(wps, &attr);
    3005         525 :                 break;
    3006             :         case WPS_M3:
    3007         393 :                 if (wps_validate_m3(msg) < 0)
    3008           0 :                         return WPS_FAILURE;
    3009         393 :                 ret = wps_process_m3(wps, msg, &attr);
    3010         393 :                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
    3011           4 :                         wps_fail_event(wps->wps, WPS_M3, wps->config_error,
    3012           4 :                                        wps->error_indication, wps->mac_addr_e);
    3013         393 :                 break;
    3014             :         case WPS_M5:
    3015         372 :                 if (wps_validate_m5(msg) < 0)
    3016           0 :                         return WPS_FAILURE;
    3017         372 :                 ret = wps_process_m5(wps, msg, &attr);
    3018         372 :                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
    3019           5 :                         wps_fail_event(wps->wps, WPS_M5, wps->config_error,
    3020           5 :                                        wps->error_indication, wps->mac_addr_e);
    3021         372 :                 break;
    3022             :         case WPS_M7:
    3023         358 :                 if (wps_validate_m7(msg) < 0)
    3024           0 :                         return WPS_FAILURE;
    3025         358 :                 ret = wps_process_m7(wps, msg, &attr);
    3026         358 :                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
    3027          44 :                         wps_fail_event(wps->wps, WPS_M7, wps->config_error,
    3028          44 :                                        wps->error_indication, wps->mac_addr_e);
    3029         358 :                 break;
    3030             :         default:
    3031           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
    3032           1 :                            *attr.msg_type);
    3033           1 :                 return WPS_FAILURE;
    3034             :         }
    3035             : 
    3036        1648 :         if (ret == WPS_CONTINUE) {
    3037             :                 /* Save a copy of the last message for Authenticator derivation
    3038             :                  */
    3039        1621 :                 wpabuf_free(wps->last_msg);
    3040        1621 :                 wps->last_msg = wpabuf_dup(msg);
    3041             :         }
    3042             : 
    3043        1648 :         return ret;
    3044             : }
    3045             : 
    3046             : 
    3047          47 : static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
    3048             :                                                 const struct wpabuf *msg)
    3049             : {
    3050             :         struct wps_parse_attr attr;
    3051             : 
    3052          47 :         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
    3053             : 
    3054          47 :         if (wps_parse_msg(msg, &attr) < 0)
    3055           1 :                 return WPS_FAILURE;
    3056             : 
    3057          46 :         if (attr.msg_type == NULL) {
    3058           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
    3059           1 :                 return WPS_FAILURE;
    3060             :         }
    3061             : 
    3062          45 :         if (*attr.msg_type != WPS_WSC_ACK) {
    3063           1 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
    3064           1 :                            *attr.msg_type);
    3065           1 :                 return WPS_FAILURE;
    3066             :         }
    3067             : 
    3068             : #ifdef CONFIG_WPS_UPNP
    3069          57 :         if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
    3070          13 :             upnp_wps_subscribers(wps->wps->wps_upnp)) {
    3071          13 :                 if (wps->wps->upnp_msgs)
    3072          12 :                         return WPS_CONTINUE;
    3073           1 :                 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
    3074             :                            "external Registrar");
    3075           1 :                 return WPS_PENDING;
    3076             :         }
    3077             : #endif /* CONFIG_WPS_UPNP */
    3078             : 
    3079          61 :         if (attr.registrar_nonce == NULL ||
    3080          30 :             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
    3081             :         {
    3082           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
    3083           1 :                 return WPS_FAILURE;
    3084             :         }
    3085             : 
    3086          60 :         if (attr.enrollee_nonce == NULL ||
    3087          30 :             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
    3088           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
    3089           1 :                 return WPS_FAILURE;
    3090             :         }
    3091             : 
    3092          29 :         if (wps->state == RECV_M2D_ACK) {
    3093             : #ifdef CONFIG_WPS_UPNP
    3094          40 :                 if (wps->wps->wps_upnp &&
    3095          12 :                     upnp_wps_subscribers(wps->wps->wps_upnp)) {
    3096          12 :                         if (wps->wps->upnp_msgs)
    3097           0 :                                 return WPS_CONTINUE;
    3098          12 :                         if (wps->ext_reg == 0)
    3099          12 :                                 wps->ext_reg = 1;
    3100          12 :                         wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
    3101             :                                    "external Registrar");
    3102          12 :                         return WPS_PENDING;
    3103             :                 }
    3104             : #endif /* CONFIG_WPS_UPNP */
    3105             : 
    3106          16 :                 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
    3107             :                            "terminate negotiation");
    3108             :         }
    3109             : 
    3110          17 :         return WPS_FAILURE;
    3111             : }
    3112             : 
    3113             : 
    3114          62 : static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
    3115             :                                                  const struct wpabuf *msg)
    3116             : {
    3117             :         struct wps_parse_attr attr;
    3118             :         int old_state;
    3119             :         u16 config_error;
    3120             : 
    3121          62 :         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
    3122             : 
    3123          62 :         old_state = wps->state;
    3124          62 :         wps->state = SEND_WSC_NACK;
    3125             : 
    3126          62 :         if (wps_parse_msg(msg, &attr) < 0)
    3127           1 :                 return WPS_FAILURE;
    3128             : 
    3129          61 :         if (attr.msg_type == NULL) {
    3130           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
    3131           1 :                 return WPS_FAILURE;
    3132             :         }
    3133             : 
    3134          60 :         if (*attr.msg_type != WPS_WSC_NACK) {
    3135           1 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
    3136           1 :                            *attr.msg_type);
    3137           1 :                 return WPS_FAILURE;
    3138             :         }
    3139             : 
    3140             : #ifdef CONFIG_WPS_UPNP
    3141          59 :         if (wps->wps->wps_upnp && wps->ext_reg) {
    3142           1 :                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
    3143             :                            "Registrar terminated by the Enrollee");
    3144           1 :                 return WPS_FAILURE;
    3145             :         }
    3146             : #endif /* CONFIG_WPS_UPNP */
    3147             : 
    3148         115 :         if (attr.registrar_nonce == NULL ||
    3149          57 :             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
    3150             :         {
    3151           6 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
    3152           6 :                 return WPS_FAILURE;
    3153             :         }
    3154             : 
    3155         104 :         if (attr.enrollee_nonce == NULL ||
    3156          52 :             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
    3157           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
    3158           1 :                 return WPS_FAILURE;
    3159             :         }
    3160             : 
    3161          51 :         if (attr.config_error == NULL) {
    3162           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
    3163             :                            "in WSC_NACK");
    3164           1 :                 return WPS_FAILURE;
    3165             :         }
    3166             : 
    3167          50 :         config_error = WPA_GET_BE16(attr.config_error);
    3168          50 :         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
    3169             :                    "Configuration Error %d", config_error);
    3170             : 
    3171          50 :         switch (old_state) {
    3172             :         case RECV_M3:
    3173          14 :                 wps_fail_event(wps->wps, WPS_M2, config_error,
    3174          14 :                                wps->error_indication, wps->mac_addr_e);
    3175          14 :                 break;
    3176             :         case RECV_M5:
    3177          13 :                 wps_fail_event(wps->wps, WPS_M4, config_error,
    3178          13 :                                wps->error_indication, wps->mac_addr_e);
    3179          13 :                 break;
    3180             :         case RECV_M7:
    3181           6 :                 wps_fail_event(wps->wps, WPS_M6, config_error,
    3182           6 :                                wps->error_indication, wps->mac_addr_e);
    3183           6 :                 break;
    3184             :         case RECV_DONE:
    3185           6 :                 wps_fail_event(wps->wps, WPS_M8, config_error,
    3186           6 :                                wps->error_indication, wps->mac_addr_e);
    3187           6 :                 break;
    3188             :         default:
    3189          11 :                 break;
    3190             :         }
    3191             : 
    3192          50 :         return WPS_FAILURE;
    3193             : }
    3194             : 
    3195             : 
    3196         328 : static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
    3197             :                                                  const struct wpabuf *msg)
    3198             : {
    3199             :         struct wps_parse_attr attr;
    3200             : 
    3201         328 :         wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
    3202             : 
    3203         339 :         if (wps->state != RECV_DONE &&
    3204          21 :             (!wps->wps->wps_upnp || !wps->ext_reg)) {
    3205           1 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
    3206           1 :                            "receiving WSC_Done", wps->state);
    3207           1 :                 return WPS_FAILURE;
    3208             :         }
    3209             : 
    3210         327 :         if (wps_parse_msg(msg, &attr) < 0)
    3211           1 :                 return WPS_FAILURE;
    3212             : 
    3213         326 :         if (attr.msg_type == NULL) {
    3214           1 :                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
    3215           1 :                 return WPS_FAILURE;
    3216             :         }
    3217             : 
    3218         325 :         if (*attr.msg_type != WPS_WSC_DONE) {
    3219           1 :                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
    3220           1 :                            *attr.msg_type);
    3221           1 :                 return WPS_FAILURE;
    3222             :         }
    3223             : 
    3224             : #ifdef CONFIG_WPS_UPNP
    3225         324 :         if (wps->wps->wps_upnp && wps->ext_reg) {
    3226          10 :                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
    3227             :                            "Registrar completed successfully");
    3228          10 :                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
    3229          10 :                                  wps->uuid_e);
    3230          10 :                 return WPS_DONE;
    3231             :         }
    3232             : #endif /* CONFIG_WPS_UPNP */
    3233             : 
    3234         627 :         if (attr.registrar_nonce == NULL ||
    3235         313 :             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
    3236             :         {
    3237           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
    3238           1 :                 return WPS_FAILURE;
    3239             :         }
    3240             : 
    3241         625 :         if (attr.enrollee_nonce == NULL ||
    3242         312 :             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
    3243           1 :                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
    3244           1 :                 return WPS_FAILURE;
    3245             :         }
    3246             : 
    3247         312 :         wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
    3248         312 :         wps_device_store(wps->wps->registrar, &wps->peer_dev,
    3249         312 :                          wps->uuid_e);
    3250             : 
    3251         318 :         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
    3252          12 :             wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
    3253             :                 struct wps_credential cred;
    3254             : 
    3255           6 :                 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
    3256             :                            "on first Enrollee connection");
    3257             : 
    3258           6 :                 os_memset(&cred, 0, sizeof(cred));
    3259           6 :                 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
    3260           6 :                 cred.ssid_len = wps->wps->ssid_len;
    3261           6 :                 if (wps->wps->rf_band_cb(wps->wps->cb_ctx) == WPS_RF_60GHZ) {
    3262           0 :                         cred.auth_type = WPS_AUTH_WPA2PSK;
    3263           0 :                         cred.encr_type = WPS_ENCR_AES;
    3264             :                 } else {
    3265           6 :                         cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
    3266           6 :                         cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
    3267             :                 }
    3268           6 :                 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
    3269           6 :                 cred.key_len = wps->new_psk_len;
    3270             : 
    3271           6 :                 wps->wps->wps_state = WPS_STATE_CONFIGURED;
    3272          12 :                 wpa_hexdump_ascii_key(MSG_DEBUG,
    3273             :                                       "WPS: Generated random passphrase",
    3274           6 :                                       wps->new_psk, wps->new_psk_len);
    3275           6 :                 if (wps->wps->cred_cb)
    3276           6 :                         wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
    3277             : 
    3278           6 :                 os_free(wps->new_psk);
    3279           6 :                 wps->new_psk = NULL;
    3280             :         }
    3281             : 
    3282         312 :         if (!wps->wps->ap && !wps->er)
    3283           7 :                 wps_sta_cred_cb(wps);
    3284             : 
    3285         312 :         if (wps->new_psk) {
    3286          24 :                 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
    3287          12 :                                    wps->p2p_dev_addr, wps->new_psk,
    3288             :                                    wps->new_psk_len)) {
    3289           2 :                         wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
    3290             :                                    "new PSK");
    3291             :                 }
    3292          12 :                 os_free(wps->new_psk);
    3293          12 :                 wps->new_psk = NULL;
    3294             :         }
    3295             : 
    3296         624 :         wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e,
    3297         312 :                            wps->dev_password, wps->dev_password_len);
    3298             : 
    3299         312 :         if (wps->pbc) {
    3300          53 :                 wps_registrar_remove_pbc_session(wps->wps->registrar,
    3301          53 :                                                  wps->uuid_e,
    3302          53 :                                                  wps->p2p_dev_addr);
    3303          53 :                 wps_registrar_pbc_completed(wps->wps->registrar);
    3304             : #ifdef WPS_WORKAROUNDS
    3305          53 :                 os_get_reltime(&wps->wps->registrar->pbc_ignore_start);
    3306             : #endif /* WPS_WORKAROUNDS */
    3307          53 :                 os_memcpy(wps->wps->registrar->pbc_ignore_uuid, wps->uuid_e,
    3308             :                           WPS_UUID_LEN);
    3309             :         } else {
    3310         259 :                 wps_registrar_pin_completed(wps->wps->registrar);
    3311             :         }
    3312             :         /* TODO: maintain AuthorizedMACs somewhere separately for each ER and
    3313             :          * merge them into APs own list.. */
    3314             : 
    3315         312 :         wps_success_event(wps->wps, wps->mac_addr_e);
    3316             : 
    3317         312 :         return WPS_DONE;
    3318             : }
    3319             : 
    3320             : 
    3321        2143 : enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
    3322             :                                                enum wsc_op_code op_code,
    3323             :                                                const struct wpabuf *msg)
    3324             : {
    3325             :         enum wps_process_res ret;
    3326             : 
    3327        2143 :         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
    3328             :                    "op_code=%d)",
    3329             :                    (unsigned long) wpabuf_len(msg), op_code);
    3330             : 
    3331             : #ifdef CONFIG_WPS_UPNP
    3332        2143 :         if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
    3333             :                 struct wps_parse_attr attr;
    3334          18 :                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
    3335           9 :                     *attr.msg_type == WPS_M3)
    3336           9 :                         wps->ext_reg = 2; /* past M2/M2D phase */
    3337             :         }
    3338        2143 :         if (wps->ext_reg > 1)
    3339          63 :                 wps_registrar_free_pending_m2(wps->wps);
    3340        2221 :         if (wps->wps->wps_upnp && wps->ext_reg &&
    3341         117 :             wps->wps->upnp_msgs == NULL &&
    3342          12 :             (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
    3343          11 :         {
    3344             :                 struct wps_parse_attr attr;
    3345             :                 int type;
    3346          38 :                 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
    3347           0 :                         type = -1;
    3348             :                 else
    3349          38 :                         type = *attr.msg_type;
    3350          38 :                 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
    3351             :                            " to external Registrar for processing", type);
    3352          38 :                 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
    3353          38 :                                                 wps->mac_addr_e,
    3354             :                                                 UPNP_WPS_WLANEVENT_TYPE_EAP,
    3355             :                                                 msg);
    3356          38 :                 if (op_code == WSC_MSG)
    3357          27 :                         return WPS_PENDING;
    3358        2105 :         } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
    3359          27 :                 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
    3360             :                            "external Registrar");
    3361          27 :                 return WPS_CONTINUE;
    3362             :         }
    3363             : #endif /* CONFIG_WPS_UPNP */
    3364             : 
    3365        2089 :         switch (op_code) {
    3366             :         case WSC_MSG:
    3367        1652 :                 return wps_process_wsc_msg(wps, msg);
    3368             :         case WSC_ACK:
    3369          47 :                 if (wps_validate_wsc_ack(msg) < 0)
    3370           0 :                         return WPS_FAILURE;
    3371          47 :                 return wps_process_wsc_ack(wps, msg);
    3372             :         case WSC_NACK:
    3373          62 :                 if (wps_validate_wsc_nack(msg) < 0)
    3374           0 :                         return WPS_FAILURE;
    3375          62 :                 return wps_process_wsc_nack(wps, msg);
    3376             :         case WSC_Done:
    3377         328 :                 if (wps_validate_wsc_done(msg) < 0)
    3378           0 :                         return WPS_FAILURE;
    3379         328 :                 ret = wps_process_wsc_done(wps, msg);
    3380         328 :                 if (ret == WPS_FAILURE) {
    3381           6 :                         wps->state = SEND_WSC_NACK;
    3382          12 :                         wps_fail_event(wps->wps, WPS_WSC_DONE,
    3383           6 :                                        wps->config_error,
    3384           6 :                                        wps->error_indication, wps->mac_addr_e);
    3385             :                 }
    3386         328 :                 return ret;
    3387             :         default:
    3388           0 :                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
    3389           0 :                 return WPS_FAILURE;
    3390             :         }
    3391             : }
    3392             : 
    3393             : 
    3394          31 : int wps_registrar_update_ie(struct wps_registrar *reg)
    3395             : {
    3396          31 :         return wps_set_ie(reg);
    3397             : }
    3398             : 
    3399             : 
    3400           6 : static void wps_registrar_set_selected_timeout(void *eloop_ctx,
    3401             :                                                void *timeout_ctx)
    3402             : {
    3403           6 :         struct wps_registrar *reg = eloop_ctx;
    3404             : 
    3405           6 :         wpa_printf(MSG_DEBUG, "WPS: Selected Registrar timeout - "
    3406             :                    "unselect internal Registrar");
    3407           6 :         reg->selected_registrar = 0;
    3408           6 :         reg->pbc = 0;
    3409           6 :         wps_registrar_selected_registrar_changed(reg, 0);
    3410           6 : }
    3411             : 
    3412             : 
    3413             : #ifdef CONFIG_WPS_UPNP
    3414          22 : static void wps_registrar_sel_reg_add(struct wps_registrar *reg,
    3415             :                                       struct subscription *s)
    3416             : {
    3417             :         int i, j;
    3418          44 :         wpa_printf(MSG_DEBUG, "WPS: External Registrar selected (dev_pw_id=%d "
    3419             :                    "config_methods=0x%x)",
    3420          44 :                    s->dev_password_id, s->config_methods);
    3421          22 :         reg->sel_reg_union = 1;
    3422          22 :         if (reg->sel_reg_dev_password_id_override != DEV_PW_PUSHBUTTON)
    3423          22 :                 reg->sel_reg_dev_password_id_override = s->dev_password_id;
    3424          22 :         if (reg->sel_reg_config_methods_override == -1)
    3425          22 :                 reg->sel_reg_config_methods_override = 0;
    3426          22 :         reg->sel_reg_config_methods_override |= s->config_methods;
    3427          22 :         for (i = 0; i < WPS_MAX_AUTHORIZED_MACS; i++)
    3428          22 :                 if (is_zero_ether_addr(reg->authorized_macs_union[i]))
    3429          22 :                         break;
    3430          73 :         for (j = 0; i < WPS_MAX_AUTHORIZED_MACS && j < WPS_MAX_AUTHORIZED_MACS;
    3431          29 :              j++) {
    3432          50 :                 if (is_zero_ether_addr(s->authorized_macs[j]))
    3433          21 :                         break;
    3434         174 :                 wpa_printf(MSG_DEBUG, "WPS: Add authorized MAC into union: "
    3435         174 :                            MACSTR, MAC2STR(s->authorized_macs[j]));
    3436          29 :                 os_memcpy(reg->authorized_macs_union[i],
    3437             :                           s->authorized_macs[j], ETH_ALEN);
    3438          29 :                 i++;
    3439             :         }
    3440          22 :         wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union",
    3441          22 :                     (u8 *) reg->authorized_macs_union,
    3442             :                     sizeof(reg->authorized_macs_union));
    3443          22 : }
    3444             : #endif /* CONFIG_WPS_UPNP */
    3445             : 
    3446             : 
    3447        1327 : static void wps_registrar_sel_reg_union(struct wps_registrar *reg)
    3448             : {
    3449             : #ifdef CONFIG_WPS_UPNP
    3450             :         struct subscription *s;
    3451             : 
    3452        1327 :         if (reg->wps->wps_upnp == NULL)
    3453        2571 :                 return;
    3454             : 
    3455         159 :         dl_list_for_each(s, &reg->wps->wps_upnp->subscriptions,
    3456             :                          struct subscription, list) {
    3457             :                 struct subscr_addr *sa;
    3458          76 :                 sa = dl_list_first(&s->addr_list, struct subscr_addr, list);
    3459          76 :                 if (sa) {
    3460          76 :                         wpa_printf(MSG_DEBUG, "WPS: External Registrar %s:%d",
    3461             :                                    inet_ntoa(sa->saddr.sin_addr),
    3462          76 :                                    ntohs(sa->saddr.sin_port));
    3463             :                 }
    3464          76 :                 if (s->selected_registrar)
    3465          22 :                         wps_registrar_sel_reg_add(reg, s);
    3466             :                 else
    3467          54 :                         wpa_printf(MSG_DEBUG, "WPS: External Registrar not "
    3468             :                                    "selected");
    3469             :         }
    3470             : #endif /* CONFIG_WPS_UPNP */
    3471             : }
    3472             : 
    3473             : 
    3474             : /**
    3475             :  * wps_registrar_selected_registrar_changed - SetSelectedRegistrar change
    3476             :  * @reg: Registrar data from wps_registrar_init()
    3477             :  *
    3478             :  * This function is called when selected registrar state changes, e.g., when an
    3479             :  * AP receives a SetSelectedRegistrar UPnP message.
    3480             :  */
    3481        1327 : void wps_registrar_selected_registrar_changed(struct wps_registrar *reg,
    3482             :                                               u16 dev_pw_id)
    3483             : {
    3484        1327 :         wpa_printf(MSG_DEBUG, "WPS: Selected registrar information changed");
    3485             : 
    3486        1327 :         reg->sel_reg_union = reg->selected_registrar;
    3487        1327 :         reg->sel_reg_dev_password_id_override = -1;
    3488        1327 :         reg->sel_reg_config_methods_override = -1;
    3489        1327 :         os_memcpy(reg->authorized_macs_union, reg->authorized_macs,
    3490             :                   WPS_MAX_AUTHORIZED_MACS * ETH_ALEN);
    3491        1327 :         wpa_hexdump(MSG_DEBUG, "WPS: Authorized MACs union (start with own)",
    3492        1327 :                     (u8 *) reg->authorized_macs_union,
    3493             :                     sizeof(reg->authorized_macs_union));
    3494        1327 :         if (reg->selected_registrar) {
    3495             :                 u16 methods;
    3496             : 
    3497         850 :                 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
    3498         850 :                 methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
    3499             :                              WPS_CONFIG_PHY_PUSHBUTTON);
    3500         850 :                 if (reg->pbc) {
    3501         124 :                         reg->sel_reg_dev_password_id_override =
    3502             :                                 DEV_PW_PUSHBUTTON;
    3503         124 :                         wps_set_pushbutton(&methods, reg->wps->config_methods);
    3504         726 :                 } else if (dev_pw_id)
    3505          30 :                         reg->sel_reg_dev_password_id_override = dev_pw_id;
    3506         850 :                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar selected "
    3507             :                            "(pbc=%d)", reg->pbc);
    3508         850 :                 reg->sel_reg_config_methods_override = methods;
    3509             :         } else
    3510         477 :                 wpa_printf(MSG_DEBUG, "WPS: Internal Registrar not selected");
    3511             : 
    3512        1327 :         wps_registrar_sel_reg_union(reg);
    3513             : 
    3514        1327 :         wps_set_ie(reg);
    3515        1327 :         wps_cb_set_sel_reg(reg);
    3516        1327 : }
    3517             : 
    3518             : 
    3519           7 : int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
    3520             :                            char *buf, size_t buflen)
    3521             : {
    3522             :         struct wps_registrar_device *d;
    3523           7 :         int len = 0, ret;
    3524             :         char uuid[40];
    3525             :         char devtype[WPS_DEV_TYPE_BUFSIZE];
    3526             : 
    3527           7 :         d = wps_device_get(reg, addr);
    3528           7 :         if (d == NULL)
    3529           3 :                 return 0;
    3530           4 :         if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
    3531           0 :                 return 0;
    3532             : 
    3533          24 :         ret = os_snprintf(buf + len, buflen - len,
    3534             :                           "wpsUuid=%s\n"
    3535             :                           "wpsPrimaryDeviceType=%s\n"
    3536             :                           "wpsDeviceName=%s\n"
    3537             :                           "wpsManufacturer=%s\n"
    3538             :                           "wpsModelName=%s\n"
    3539             :                           "wpsModelNumber=%s\n"
    3540             :                           "wpsSerialNumber=%s\n",
    3541             :                           uuid,
    3542           4 :                           wps_dev_type_bin2str(d->dev.pri_dev_type, devtype,
    3543             :                                                sizeof(devtype)),
    3544           4 :                           d->dev.device_name ? d->dev.device_name : "",
    3545           4 :                           d->dev.manufacturer ? d->dev.manufacturer : "",
    3546           4 :                           d->dev.model_name ? d->dev.model_name : "",
    3547           4 :                           d->dev.model_number ? d->dev.model_number : "",
    3548           4 :                           d->dev.serial_number ? d->dev.serial_number : "");
    3549           4 :         if (os_snprintf_error(buflen - len, ret))
    3550           0 :                 return len;
    3551           4 :         len += ret;
    3552             : 
    3553           4 :         return len;
    3554             : }
    3555             : 
    3556             : 
    3557           4 : int wps_registrar_config_ap(struct wps_registrar *reg,
    3558             :                             struct wps_credential *cred)
    3559             : {
    3560           4 :         wpa_printf(MSG_DEBUG, "WPS: encr_type=0x%x", cred->encr_type);
    3561           4 :         if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP |
    3562             :                                  WPS_ENCR_AES))) {
    3563           0 :                 if (cred->encr_type & WPS_ENCR_WEP) {
    3564           0 :                         wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
    3565             :                                    "due to WEP configuration");
    3566           0 :                         return -1;
    3567             :                 }
    3568             : 
    3569           0 :                 wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
    3570           0 :                            "invalid encr_type 0x%x", cred->encr_type);
    3571           0 :                 return -1;
    3572             :         }
    3573             : 
    3574           4 :         if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
    3575             :             WPS_ENCR_TKIP) {
    3576           0 :                 wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
    3577             :                            "TKIP+AES");
    3578           0 :                 cred->encr_type |= WPS_ENCR_AES;
    3579             :         }
    3580             : 
    3581           4 :         if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
    3582             :             WPS_AUTH_WPAPSK) {
    3583           0 :                 wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
    3584             :                            "WPAPSK+WPA2PSK");
    3585           0 :                 cred->auth_type |= WPS_AUTH_WPA2PSK;
    3586             :         }
    3587             : 
    3588           4 :         if (reg->wps->cred_cb)
    3589           4 :                 return reg->wps->cred_cb(reg->wps->cb_ctx, cred);
    3590             : 
    3591           0 :         return -1;
    3592             : }
    3593             : 
    3594             : 
    3595             : #ifdef CONFIG_WPS_NFC
    3596             : 
    3597          30 : int wps_registrar_add_nfc_pw_token(struct wps_registrar *reg,
    3598             :                                    const u8 *pubkey_hash, u16 pw_id,
    3599             :                                    const u8 *dev_pw, size_t dev_pw_len,
    3600             :                                    int pk_hash_provided_oob)
    3601             : {
    3602             :         struct wps_nfc_pw_token *token;
    3603             : 
    3604          30 :         if (dev_pw_len > WPS_OOB_DEVICE_PASSWORD_LEN)
    3605           0 :                 return -1;
    3606             : 
    3607          30 :         if (pw_id == DEV_PW_NFC_CONNECTION_HANDOVER &&
    3608          18 :             (pubkey_hash == NULL || !pk_hash_provided_oob)) {
    3609           0 :                 wpa_printf(MSG_DEBUG, "WPS: Unexpected NFC Password Token "
    3610             :                            "addition - missing public key hash");
    3611           0 :                 return -1;
    3612             :         }
    3613             : 
    3614          30 :         wps_free_nfc_pw_tokens(&reg->nfc_pw_tokens, pw_id);
    3615             : 
    3616          30 :         token = os_zalloc(sizeof(*token));
    3617          30 :         if (token == NULL)
    3618           0 :                 return -1;
    3619             : 
    3620          30 :         token->peer_pk_hash_known = pubkey_hash != NULL;
    3621          30 :         if (pubkey_hash)
    3622          28 :                 os_memcpy(token->pubkey_hash, pubkey_hash,
    3623             :                           WPS_OOB_PUBKEY_HASH_LEN);
    3624          30 :         token->pw_id = pw_id;
    3625          30 :         token->pk_hash_provided_oob = pk_hash_provided_oob;
    3626          30 :         if (dev_pw) {
    3627          12 :                 wpa_snprintf_hex_uppercase((char *) token->dev_pw,
    3628             :                                            sizeof(token->dev_pw),
    3629             :                                            dev_pw, dev_pw_len);
    3630          12 :                 token->dev_pw_len = dev_pw_len * 2;
    3631             :         }
    3632             : 
    3633          30 :         dl_list_add(&reg->nfc_pw_tokens, &token->list);
    3634             : 
    3635          30 :         reg->selected_registrar = 1;
    3636          30 :         reg->pbc = 0;
    3637          30 :         wps_registrar_add_authorized_mac(reg,
    3638             :                                          (u8 *) "\xff\xff\xff\xff\xff\xff");
    3639          30 :         wps_registrar_selected_registrar_changed(reg, pw_id);
    3640          30 :         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
    3641          30 :         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
    3642             :                                wps_registrar_set_selected_timeout,
    3643             :                                reg, NULL);
    3644             : 
    3645          30 :         wpa_printf(MSG_DEBUG, "WPS: Added NFC Device Password %u to Registrar",
    3646             :                    pw_id);
    3647             : 
    3648          30 :         return 0;
    3649             : }
    3650             : 
    3651             : 
    3652           4 : int wps_registrar_add_nfc_password_token(struct wps_registrar *reg,
    3653             :                                          const u8 *oob_dev_pw,
    3654             :                                          size_t oob_dev_pw_len)
    3655             : {
    3656             :         const u8 *pos, *hash, *dev_pw;
    3657             :         u16 id;
    3658             :         size_t dev_pw_len;
    3659             : 
    3660           4 :         if (oob_dev_pw_len < WPS_OOB_PUBKEY_HASH_LEN + 2 ||
    3661             :             oob_dev_pw_len > WPS_OOB_PUBKEY_HASH_LEN + 2 +
    3662             :             WPS_OOB_DEVICE_PASSWORD_LEN)
    3663           0 :                 return -1;
    3664             : 
    3665           4 :         hash = oob_dev_pw;
    3666           4 :         pos = oob_dev_pw + WPS_OOB_PUBKEY_HASH_LEN;
    3667           4 :         id = WPA_GET_BE16(pos);
    3668           4 :         dev_pw = pos + 2;
    3669           4 :         dev_pw_len = oob_dev_pw + oob_dev_pw_len - dev_pw;
    3670             : 
    3671           4 :         wpa_printf(MSG_DEBUG, "WPS: Add NFC Password Token for Password ID %u",
    3672             :                    id);
    3673             : 
    3674           4 :         wpa_hexdump(MSG_DEBUG, "WPS: Public Key Hash",
    3675             :                     hash, WPS_OOB_PUBKEY_HASH_LEN);
    3676           4 :         wpa_hexdump_key(MSG_DEBUG, "WPS: Device Password", dev_pw, dev_pw_len);
    3677             : 
    3678           4 :         return wps_registrar_add_nfc_pw_token(reg, hash, id, dev_pw,
    3679             :                                               dev_pw_len, 0);
    3680             : }
    3681             : 
    3682             : 
    3683          30 : void wps_registrar_remove_nfc_pw_token(struct wps_registrar *reg,
    3684             :                                        struct wps_nfc_pw_token *token)
    3685             : {
    3686          30 :         wps_registrar_remove_authorized_mac(reg,
    3687             :                                             (u8 *) "\xff\xff\xff\xff\xff\xff");
    3688          30 :         wps_registrar_selected_registrar_changed(reg, 0);
    3689             : 
    3690             :         /*
    3691             :          * Free the NFC password token if it was used only for a single protocol
    3692             :          * run. The static handover case uses the same password token multiple
    3693             :          * times, so do not free that case here.
    3694             :          */
    3695          30 :         if (token->peer_pk_hash_known)
    3696          28 :                 os_free(token);
    3697          30 : }
    3698             : 
    3699             : #endif /* CONFIG_WPS_NFC */

Generated by: LCOV version 1.10