Coverage Report

Created: 2025-08-26 06:04

/src/hostap/src/wps/wps_enrollee.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Wi-Fi Protected Setup - Enrollee
3
 * Copyright (c) 2008, 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 "includes.h"
10
11
#include "common.h"
12
#include "crypto/crypto.h"
13
#include "crypto/sha256.h"
14
#include "crypto/random.h"
15
#include "wps_i.h"
16
#include "wps_dev_attr.h"
17
18
19
static int wps_build_wps_state(struct wps_data *wps, struct wpabuf *msg)
20
0
{
21
0
  u8 state;
22
0
  if (wps->wps->ap)
23
0
    state = wps->wps->wps_state;
24
0
  else
25
0
    state = WPS_STATE_NOT_CONFIGURED;
26
0
  wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
27
0
       state);
28
0
  wpabuf_put_be16(msg, ATTR_WPS_STATE);
29
0
  wpabuf_put_be16(msg, 1);
30
0
  wpabuf_put_u8(msg, state);
31
0
  return 0;
32
0
}
33
34
35
static int wps_build_e_hash(struct wps_data *wps, struct wpabuf *msg)
36
0
{
37
0
  u8 *hash;
38
0
  const u8 *addr[4];
39
0
  size_t len[4];
40
41
0
  if (random_get_bytes(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
42
0
    return -1;
43
0
  wpa_hexdump(MSG_DEBUG, "WPS: E-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
44
0
  wpa_hexdump(MSG_DEBUG, "WPS: E-S2",
45
0
        wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
46
47
0
  if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
48
0
    wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
49
0
         "E-Hash derivation");
50
0
    return -1;
51
0
  }
52
53
0
  wpa_printf(MSG_DEBUG, "WPS:  * E-Hash1");
54
0
  wpabuf_put_be16(msg, ATTR_E_HASH1);
55
0
  wpabuf_put_be16(msg, SHA256_MAC_LEN);
56
0
  hash = wpabuf_put(msg, SHA256_MAC_LEN);
57
  /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
58
0
  addr[0] = wps->snonce;
59
0
  len[0] = WPS_SECRET_NONCE_LEN;
60
0
  addr[1] = wps->psk1;
61
0
  len[1] = WPS_PSK_LEN;
62
0
  addr[2] = wpabuf_head(wps->dh_pubkey_e);
63
0
  len[2] = wpabuf_len(wps->dh_pubkey_e);
64
0
  addr[3] = wpabuf_head(wps->dh_pubkey_r);
65
0
  len[3] = wpabuf_len(wps->dh_pubkey_r);
66
0
  hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
67
0
  wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", hash, SHA256_MAC_LEN);
68
69
0
  wpa_printf(MSG_DEBUG, "WPS:  * E-Hash2");
70
0
  wpabuf_put_be16(msg, ATTR_E_HASH2);
71
0
  wpabuf_put_be16(msg, SHA256_MAC_LEN);
72
0
  hash = wpabuf_put(msg, SHA256_MAC_LEN);
73
  /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
74
0
  addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
75
0
  addr[1] = wps->psk2;
76
0
  hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
77
0
  wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", hash, SHA256_MAC_LEN);
78
79
0
  return 0;
80
0
}
81
82
83
static int wps_build_e_snonce1(struct wps_data *wps, struct wpabuf *msg)
84
0
{
85
0
  wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce1");
86
0
  wpabuf_put_be16(msg, ATTR_E_SNONCE1);
87
0
  wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
88
0
  wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
89
0
  return 0;
90
0
}
91
92
93
static int wps_build_e_snonce2(struct wps_data *wps, struct wpabuf *msg)
94
0
{
95
0
  wpa_printf(MSG_DEBUG, "WPS:  * E-SNonce2");
96
0
  wpabuf_put_be16(msg, ATTR_E_SNONCE2);
97
0
  wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
98
0
  wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
99
0
      WPS_SECRET_NONCE_LEN);
100
0
  return 0;
101
0
}
102
103
104
static struct wpabuf * wps_build_m1(struct wps_data *wps)
105
0
{
106
0
  struct wpabuf *msg;
107
0
  u16 config_methods;
108
0
  u8 multi_ap_backhaul_sta = 0;
109
110
0
  if (random_get_bytes(wps->nonce_e, WPS_NONCE_LEN) < 0)
111
0
    return NULL;
112
0
  wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
113
0
        wps->nonce_e, WPS_NONCE_LEN);
114
115
0
  wpa_printf(MSG_DEBUG, "WPS: Building Message M1");
116
0
  msg = wpabuf_alloc(1000);
117
0
  if (msg == NULL)
118
0
    return NULL;
119
120
0
  config_methods = wps->wps->config_methods;
121
0
  if (wps->wps->ap && !wps->pbc_in_m1 &&
122
0
      (wps->dev_password_len != 0 ||
123
0
       (config_methods & WPS_CONFIG_DISPLAY))) {
124
    /*
125
     * These are the methods that the AP supports as an Enrollee
126
     * for adding external Registrars, so remove PushButton.
127
     *
128
     * As a workaround for Windows 7 mechanism for probing WPS
129
     * capabilities from M1, leave PushButton option if no PIN
130
     * method is available or if WPS configuration enables PBC
131
     * workaround.
132
     */
133
0
    config_methods &= ~WPS_CONFIG_PUSHBUTTON;
134
0
    config_methods &= ~(WPS_CONFIG_VIRT_PUSHBUTTON |
135
0
            WPS_CONFIG_PHY_PUSHBUTTON);
136
0
  }
137
138
0
  if (wps->multi_ap_backhaul_sta)
139
0
    multi_ap_backhaul_sta = MULTI_AP_BACKHAUL_STA;
140
141
0
  if (wps_build_version(msg) ||
142
0
      wps_build_msg_type(msg, WPS_M1) ||
143
0
      wps_build_uuid_e(msg, wps->uuid_e) ||
144
0
      wps_build_mac_addr(msg, wps->mac_addr_e) ||
145
0
      wps_build_enrollee_nonce(wps, msg) ||
146
0
      wps_build_public_key(wps, msg) ||
147
0
      wps_build_auth_type_flags(wps, msg) ||
148
0
      wps_build_encr_type_flags(wps, msg) ||
149
0
      wps_build_conn_type_flags(wps, msg) ||
150
0
      wps_build_config_methods(msg, config_methods) ||
151
0
      wps_build_wps_state(wps, msg) ||
152
0
      wps_build_device_attrs(&wps->wps->dev, msg) ||
153
0
      wps_build_rf_bands(&wps->wps->dev, msg,
154
0
             wps->wps->rf_band_cb(wps->wps->cb_ctx)) ||
155
0
      wps_build_assoc_state(wps, msg) ||
156
0
      wps_build_dev_password_id(msg, wps->dev_pw_id) ||
157
0
      wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
158
0
      wps_build_os_version(&wps->wps->dev, msg) ||
159
0
      wps_build_wfa_ext(msg, 0, NULL, 0, multi_ap_backhaul_sta) ||
160
0
      wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
161
0
    wpabuf_free(msg);
162
0
    return NULL;
163
0
  }
164
165
0
  wps->state = RECV_M2;
166
0
  return msg;
167
0
}
168
169
170
static struct wpabuf * wps_build_m3(struct wps_data *wps)
171
0
{
172
0
  struct wpabuf *msg;
173
174
0
  wpa_printf(MSG_DEBUG, "WPS: Building Message M3");
175
176
0
  if (wps->dev_password == NULL) {
177
0
    wpa_printf(MSG_DEBUG, "WPS: No Device Password available");
178
0
    return NULL;
179
0
  }
180
0
  if (wps_derive_psk(wps, wps->dev_password, wps->dev_password_len) < 0)
181
0
    return NULL;
182
183
0
  if (wps->wps->ap && random_pool_ready() != 1) {
184
0
    wpa_printf(MSG_INFO,
185
0
         "WPS: Not enough entropy in random pool to proceed - do not allow AP PIN to be used");
186
0
    return NULL;
187
0
  }
188
189
0
  msg = wpabuf_alloc(1000);
190
0
  if (msg == NULL)
191
0
    return NULL;
192
193
0
  if (wps_build_version(msg) ||
194
0
      wps_build_msg_type(msg, WPS_M3) ||
195
0
      wps_build_registrar_nonce(wps, msg) ||
196
0
      wps_build_e_hash(wps, msg) ||
197
0
      wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
198
0
      wps_build_authenticator(wps, msg)) {
199
0
    wpabuf_free(msg);
200
0
    return NULL;
201
0
  }
202
203
0
  wps->state = RECV_M4;
204
0
  return msg;
205
0
}
206
207
208
static struct wpabuf * wps_build_m5(struct wps_data *wps)
209
0
{
210
0
  struct wpabuf *msg, *plain;
211
212
0
  wpa_printf(MSG_DEBUG, "WPS: Building Message M5");
213
214
0
  plain = wpabuf_alloc(200);
215
0
  if (plain == NULL)
216
0
    return NULL;
217
218
0
  msg = wpabuf_alloc(1000);
219
0
  if (msg == NULL) {
220
0
    wpabuf_free(plain);
221
0
    return NULL;
222
0
  }
223
224
0
  if (wps_build_version(msg) ||
225
0
      wps_build_msg_type(msg, WPS_M5) ||
226
0
      wps_build_registrar_nonce(wps, msg) ||
227
0
      wps_build_e_snonce1(wps, plain) ||
228
0
      wps_build_key_wrap_auth(wps, plain) ||
229
0
      wps_build_encr_settings(wps, msg, plain) ||
230
0
      wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
231
0
      wps_build_authenticator(wps, msg)) {
232
0
    wpabuf_clear_free(plain);
233
0
    wpabuf_free(msg);
234
0
    return NULL;
235
0
  }
236
0
  wpabuf_clear_free(plain);
237
238
0
  wps->state = RECV_M6;
239
0
  return msg;
240
0
}
241
242
243
static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
244
0
{
245
0
  wpa_printf(MSG_DEBUG, "WPS:  * SSID");
246
0
  wpabuf_put_be16(msg, ATTR_SSID);
247
0
  wpabuf_put_be16(msg, wps->wps->ssid_len);
248
0
  wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
249
0
  return 0;
250
0
}
251
252
253
static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
254
0
{
255
0
  u16 auth_type = wps->wps->ap_auth_type;
256
257
  /*
258
   * Work around issues with Windows 7 WPS implementation not liking
259
   * multiple Authentication Type bits in M7 AP Settings attribute by
260
   * showing only the most secure option from current configuration.
261
   */
262
0
  if (auth_type & WPS_AUTH_WPA2PSK)
263
0
    auth_type = WPS_AUTH_WPA2PSK;
264
0
  else if (auth_type & WPS_AUTH_WPAPSK)
265
0
    auth_type = WPS_AUTH_WPAPSK;
266
0
  else if (auth_type & WPS_AUTH_OPEN)
267
0
    auth_type = WPS_AUTH_OPEN;
268
269
0
  wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)", auth_type);
270
0
  wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
271
0
  wpabuf_put_be16(msg, 2);
272
0
  wpabuf_put_be16(msg, auth_type);
273
0
  return 0;
274
0
}
275
276
277
static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
278
0
{
279
0
  u16 encr_type = wps->wps->ap_encr_type;
280
281
  /*
282
   * Work around issues with Windows 7 WPS implementation not liking
283
   * multiple Encryption Type bits in M7 AP Settings attribute by
284
   * showing only the most secure option from current configuration.
285
   */
286
0
  if (wps->wps->ap_auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) {
287
0
    if (encr_type & WPS_ENCR_AES)
288
0
      encr_type = WPS_ENCR_AES;
289
0
    else if (encr_type & WPS_ENCR_TKIP)
290
0
      encr_type = WPS_ENCR_TKIP;
291
0
  }
292
293
0
  wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)", encr_type);
294
0
  wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
295
0
  wpabuf_put_be16(msg, 2);
296
0
  wpabuf_put_be16(msg, encr_type);
297
0
  return 0;
298
0
}
299
300
301
static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
302
0
{
303
0
  if ((wps->wps->ap_auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) &&
304
0
      wps->wps->network_key_len == 0) {
305
0
    char hex[65];
306
0
    u8 psk[32];
307
    /* Generate a random per-device PSK */
308
0
    if (random_pool_ready() != 1 ||
309
0
        random_get_bytes(psk, sizeof(psk)) < 0) {
310
0
      wpa_printf(MSG_INFO,
311
0
           "WPS: Could not generate random PSK");
312
0
      return -1;
313
0
    }
314
0
    wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
315
0
        psk, sizeof(psk));
316
0
    wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
317
0
         (unsigned int) wps->new_psk_len * 2);
318
0
    wpa_snprintf_hex(hex, sizeof(hex), psk, sizeof(psk));
319
0
    wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
320
0
    wpabuf_put_be16(msg, sizeof(psk) * 2);
321
0
    wpabuf_put_data(msg, hex, sizeof(psk) * 2);
322
0
    if (wps->wps->registrar) {
323
0
      wps_cb_new_psk(wps->wps->registrar,
324
0
               wps->peer_dev.mac_addr,
325
0
               wps->p2p_dev_addr, psk, sizeof(psk));
326
0
    }
327
0
    return 0;
328
0
  }
329
330
0
  wpa_printf(MSG_DEBUG, "WPS:  * Network Key (len=%u)",
331
0
       (unsigned int) wps->wps->network_key_len);
332
0
  wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
333
0
  wpabuf_put_be16(msg, wps->wps->network_key_len);
334
0
  wpabuf_put_data(msg, wps->wps->network_key, wps->wps->network_key_len);
335
0
  return 0;
336
0
}
337
338
339
static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
340
0
{
341
0
  wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (AP BSSID)");
342
0
  wpabuf_put_be16(msg, ATTR_MAC_ADDR);
343
0
  wpabuf_put_be16(msg, ETH_ALEN);
344
0
  wpabuf_put_data(msg, wps->wps->dev.mac_addr, ETH_ALEN);
345
0
  return 0;
346
0
}
347
348
349
static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *plain)
350
0
{
351
0
  const u8 *start, *end;
352
0
  int ret;
353
354
0
  if (wps->wps->ap_settings) {
355
0
    wpa_printf(MSG_DEBUG, "WPS:  * AP Settings (pre-configured)");
356
0
    wpabuf_put_data(plain, wps->wps->ap_settings,
357
0
        wps->wps->ap_settings_len);
358
0
    return 0;
359
0
  }
360
361
0
  wpa_printf(MSG_DEBUG, "WPS:  * AP Settings based on current configuration");
362
0
  start = wpabuf_put(plain, 0);
363
0
  ret = wps_build_cred_ssid(wps, plain) ||
364
0
    wps_build_cred_mac_addr(wps, plain) ||
365
0
    wps_build_cred_auth_type(wps, plain) ||
366
0
    wps_build_cred_encr_type(wps, plain) ||
367
0
    wps_build_cred_network_key(wps, plain);
368
0
  end = wpabuf_put(plain, 0);
369
370
0
  wpa_hexdump_key(MSG_DEBUG, "WPS: Plaintext AP Settings",
371
0
      start, end - start);
372
373
0
  return ret;
374
0
}
375
376
377
static struct wpabuf * wps_build_m7(struct wps_data *wps)
378
0
{
379
0
  struct wpabuf *msg, *plain;
380
381
0
  wpa_printf(MSG_DEBUG, "WPS: Building Message M7");
382
383
0
  plain = wpabuf_alloc(500 + wps->wps->ap_settings_len);
384
0
  if (plain == NULL)
385
0
    return NULL;
386
387
0
  msg = wpabuf_alloc(1000 + wps->wps->ap_settings_len);
388
0
  if (msg == NULL) {
389
0
    wpabuf_free(plain);
390
0
    return NULL;
391
0
  }
392
393
0
  if (wps_build_version(msg) ||
394
0
      wps_build_msg_type(msg, WPS_M7) ||
395
0
      wps_build_registrar_nonce(wps, msg) ||
396
0
      wps_build_e_snonce2(wps, plain) ||
397
0
      (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
398
0
      wps_build_key_wrap_auth(wps, plain) ||
399
0
      wps_build_encr_settings(wps, msg, plain) ||
400
0
      wps_build_wfa_ext(msg, 0, NULL, 0, 0) ||
401
0
      wps_build_authenticator(wps, msg)) {
402
0
    wpabuf_clear_free(plain);
403
0
    wpabuf_free(msg);
404
0
    return NULL;
405
0
  }
406
0
  wpabuf_clear_free(plain);
407
408
0
  if (wps->wps->ap && wps->wps->registrar) {
409
    /*
410
     * If the Registrar is only learning our current configuration,
411
     * it may not continue protocol run to successful completion.
412
     * Store information here to make sure it remains available.
413
     */
414
0
    wps_device_store(wps->wps->registrar, &wps->peer_dev,
415
0
         wps->uuid_r);
416
0
  }
417
418
0
  wps->state = RECV_M8;
419
0
  return msg;
420
0
}
421
422
423
static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
424
0
{
425
0
  struct wpabuf *msg;
426
427
0
  wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_Done");
428
429
0
  msg = wpabuf_alloc(1000);
430
0
  if (msg == NULL)
431
0
    return NULL;
432
433
0
  if (wps_build_version(msg) ||
434
0
      wps_build_msg_type(msg, WPS_WSC_DONE) ||
435
0
      wps_build_enrollee_nonce(wps, msg) ||
436
0
      wps_build_registrar_nonce(wps, msg) ||
437
0
      wps_build_wfa_ext(msg, 0, NULL, 0, 0)) {
438
0
    wpabuf_free(msg);
439
0
    return NULL;
440
0
  }
441
442
0
  if (wps->wps->ap)
443
0
    wps->state = RECV_ACK;
444
0
  else {
445
0
    wps_success_event(wps->wps, wps->peer_dev.mac_addr);
446
0
    wps->state = WPS_FINISHED;
447
0
  }
448
0
  return msg;
449
0
}
450
451
452
struct wpabuf * wps_enrollee_get_msg(struct wps_data *wps,
453
             enum wsc_op_code *op_code)
454
0
{
455
0
  struct wpabuf *msg;
456
457
0
  switch (wps->state) {
458
0
  case SEND_M1:
459
0
    msg = wps_build_m1(wps);
460
0
    *op_code = WSC_MSG;
461
0
    break;
462
0
  case SEND_M3:
463
0
    msg = wps_build_m3(wps);
464
0
    *op_code = WSC_MSG;
465
0
    break;
466
0
  case SEND_M5:
467
0
    msg = wps_build_m5(wps);
468
0
    *op_code = WSC_MSG;
469
0
    break;
470
0
  case SEND_M7:
471
0
    msg = wps_build_m7(wps);
472
0
    *op_code = WSC_MSG;
473
0
    break;
474
0
  case RECEIVED_M2D:
475
0
    if (wps->wps->ap) {
476
0
      msg = wps_build_wsc_nack(wps);
477
0
      *op_code = WSC_NACK;
478
0
      break;
479
0
    }
480
0
    msg = wps_build_wsc_ack(wps);
481
0
    *op_code = WSC_ACK;
482
0
    if (msg) {
483
      /* Another M2/M2D may be received */
484
0
      wps->state = RECV_M2;
485
0
    }
486
0
    break;
487
0
  case SEND_WSC_NACK:
488
0
    msg = wps_build_wsc_nack(wps);
489
0
    *op_code = WSC_NACK;
490
0
    break;
491
0
  case WPS_MSG_DONE:
492
0
    msg = wps_build_wsc_done(wps);
493
0
    *op_code = WSC_Done;
494
0
    break;
495
0
  default:
496
0
    wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
497
0
         "a message", wps->state);
498
0
    msg = NULL;
499
0
    break;
500
0
  }
501
502
0
  if (*op_code == WSC_MSG && msg) {
503
    /* Save a copy of the last message for Authenticator derivation
504
     */
505
0
    wpabuf_free(wps->last_msg);
506
0
    wps->last_msg = wpabuf_dup(msg);
507
0
  }
508
509
0
  return msg;
510
0
}
511
512
513
static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
514
0
{
515
0
  if (r_nonce == NULL) {
516
0
    wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
517
0
    return -1;
518
0
  }
519
520
0
  os_memcpy(wps->nonce_r, r_nonce, WPS_NONCE_LEN);
521
0
  wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
522
0
        wps->nonce_r, WPS_NONCE_LEN);
523
524
0
  return 0;
525
0
}
526
527
528
static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
529
0
{
530
0
  if (e_nonce == NULL) {
531
0
    wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
532
0
    return -1;
533
0
  }
534
535
0
  if (os_memcmp(wps->nonce_e, e_nonce, WPS_NONCE_LEN) != 0) {
536
0
    wpa_printf(MSG_DEBUG, "WPS: Invalid Enrollee Nonce received");
537
0
    return -1;
538
0
  }
539
540
0
  return 0;
541
0
}
542
543
544
static int wps_process_uuid_r(struct wps_data *wps, const u8 *uuid_r)
545
0
{
546
0
  if (uuid_r == NULL) {
547
0
    wpa_printf(MSG_DEBUG, "WPS: No UUID-R received");
548
0
    return -1;
549
0
  }
550
551
0
  os_memcpy(wps->uuid_r, uuid_r, WPS_UUID_LEN);
552
0
  wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
553
554
0
  return 0;
555
0
}
556
557
558
static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
559
            size_t pk_len)
560
0
{
561
0
  if (pk == NULL || pk_len == 0) {
562
0
    wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
563
0
    return -1;
564
0
  }
565
566
0
  if (wps->peer_pubkey_hash_set) {
567
0
    u8 hash[WPS_HASH_LEN];
568
0
    sha256_vector(1, &pk, &pk_len, hash);
569
0
    if (os_memcmp_const(hash, wps->peer_pubkey_hash,
570
0
            WPS_OOB_PUBKEY_HASH_LEN) != 0) {
571
0
      wpa_printf(MSG_ERROR, "WPS: Public Key hash mismatch");
572
0
      wpa_hexdump(MSG_DEBUG, "WPS: Received public key",
573
0
            pk, pk_len);
574
0
      wpa_hexdump(MSG_DEBUG, "WPS: Calculated public key "
575
0
            "hash", hash, WPS_OOB_PUBKEY_HASH_LEN);
576
0
      wpa_hexdump(MSG_DEBUG, "WPS: Expected public key hash",
577
0
            wps->peer_pubkey_hash,
578
0
            WPS_OOB_PUBKEY_HASH_LEN);
579
0
      wps->config_error = WPS_CFG_PUBLIC_KEY_HASH_MISMATCH;
580
0
      return -1;
581
0
    }
582
0
  }
583
584
0
  wpabuf_free(wps->dh_pubkey_r);
585
0
  wps->dh_pubkey_r = wpabuf_alloc_copy(pk, pk_len);
586
0
  if (wps->dh_pubkey_r == NULL)
587
0
    return -1;
588
589
0
  if (wps_derive_keys(wps) < 0)
590
0
    return -1;
591
592
0
  return 0;
593
0
}
594
595
596
static int wps_process_r_hash1(struct wps_data *wps, const u8 *r_hash1)
597
0
{
598
0
  if (r_hash1 == NULL) {
599
0
    wpa_printf(MSG_DEBUG, "WPS: No R-Hash1 received");
600
0
    return -1;
601
0
  }
602
603
0
  os_memcpy(wps->peer_hash1, r_hash1, WPS_HASH_LEN);
604
0
  wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", wps->peer_hash1, WPS_HASH_LEN);
605
606
0
  return 0;
607
0
}
608
609
610
static int wps_process_r_hash2(struct wps_data *wps, const u8 *r_hash2)
611
0
{
612
0
  if (r_hash2 == NULL) {
613
0
    wpa_printf(MSG_DEBUG, "WPS: No R-Hash2 received");
614
0
    return -1;
615
0
  }
616
617
0
  os_memcpy(wps->peer_hash2, r_hash2, WPS_HASH_LEN);
618
0
  wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", wps->peer_hash2, WPS_HASH_LEN);
619
620
0
  return 0;
621
0
}
622
623
624
static int wps_process_r_snonce1(struct wps_data *wps, const u8 *r_snonce1)
625
0
{
626
0
  u8 hash[SHA256_MAC_LEN];
627
0
  const u8 *addr[4];
628
0
  size_t len[4];
629
630
0
  if (r_snonce1 == NULL) {
631
0
    wpa_printf(MSG_DEBUG, "WPS: No R-SNonce1 received");
632
0
    return -1;
633
0
  }
634
635
0
  wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce1", r_snonce1,
636
0
      WPS_SECRET_NONCE_LEN);
637
638
  /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
639
0
  addr[0] = r_snonce1;
640
0
  len[0] = WPS_SECRET_NONCE_LEN;
641
0
  addr[1] = wps->psk1;
642
0
  len[1] = WPS_PSK_LEN;
643
0
  addr[2] = wpabuf_head(wps->dh_pubkey_e);
644
0
  len[2] = wpabuf_len(wps->dh_pubkey_e);
645
0
  addr[3] = wpabuf_head(wps->dh_pubkey_r);
646
0
  len[3] = wpabuf_len(wps->dh_pubkey_r);
647
0
  hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
648
649
0
  if (os_memcmp_const(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
650
0
    wpa_printf(MSG_DEBUG, "WPS: R-Hash1 derived from R-S1 does "
651
0
         "not match with the pre-committed value");
652
0
    wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
653
0
    wps_pwd_auth_fail_event(wps->wps, 1, 1, wps->peer_dev.mac_addr);
654
0
    return -1;
655
0
  }
656
657
0
  wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the first "
658
0
       "half of the device password");
659
660
0
  return 0;
661
0
}
662
663
664
static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
665
0
{
666
0
  u8 hash[SHA256_MAC_LEN];
667
0
  const u8 *addr[4];
668
0
  size_t len[4];
669
670
0
  if (r_snonce2 == NULL) {
671
0
    wpa_printf(MSG_DEBUG, "WPS: No R-SNonce2 received");
672
0
    return -1;
673
0
  }
674
675
0
  wpa_hexdump_key(MSG_DEBUG, "WPS: R-SNonce2", r_snonce2,
676
0
      WPS_SECRET_NONCE_LEN);
677
678
  /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
679
0
  addr[0] = r_snonce2;
680
0
  len[0] = WPS_SECRET_NONCE_LEN;
681
0
  addr[1] = wps->psk2;
682
0
  len[1] = WPS_PSK_LEN;
683
0
  addr[2] = wpabuf_head(wps->dh_pubkey_e);
684
0
  len[2] = wpabuf_len(wps->dh_pubkey_e);
685
0
  addr[3] = wpabuf_head(wps->dh_pubkey_r);
686
0
  len[3] = wpabuf_len(wps->dh_pubkey_r);
687
0
  hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
688
689
0
  if (os_memcmp_const(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
690
0
    wpa_printf(MSG_DEBUG, "WPS: R-Hash2 derived from R-S2 does "
691
0
         "not match with the pre-committed value");
692
0
    wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
693
0
    wps_pwd_auth_fail_event(wps->wps, 1, 2, wps->peer_dev.mac_addr);
694
0
    return -1;
695
0
  }
696
697
0
  wpa_printf(MSG_DEBUG, "WPS: Registrar proved knowledge of the second "
698
0
       "half of the device password");
699
700
0
  return 0;
701
0
}
702
703
704
static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
705
            size_t cred_len, int wps2)
706
0
{
707
0
  struct wps_parse_attr attr;
708
0
  struct wpabuf msg;
709
0
  int ret = 0;
710
711
0
  wpa_printf(MSG_DEBUG, "WPS: Received Credential");
712
0
  os_memset(&wps->cred, 0, sizeof(wps->cred));
713
0
  wpabuf_set(&msg, cred, cred_len);
714
0
  if (wps_parse_msg(&msg, &attr) < 0 ||
715
0
      wps_process_cred(&attr, &wps->cred))
716
0
    return -1;
717
718
0
  if (!ether_addr_equal(wps->cred.mac_addr, wps->wps->dev.mac_addr)) {
719
0
    wpa_printf(MSG_DEBUG, "WPS: MAC Address in the Credential ("
720
0
         MACSTR ") does not match with own address (" MACSTR
721
0
         ")", MAC2STR(wps->cred.mac_addr),
722
0
         MAC2STR(wps->wps->dev.mac_addr));
723
    /*
724
     * In theory, this could be consider fatal error, but there are
725
     * number of deployed implementations using other address here
726
     * due to unclarity in the specification. For interoperability
727
     * reasons, allow this to be processed since we do not really
728
     * use the MAC Address information for anything.
729
     */
730
#ifdef CONFIG_WPS_STRICT
731
    if (wps2) {
732
      wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
733
           "MAC Address in AP Settings");
734
      return -1;
735
    }
736
#endif /* CONFIG_WPS_STRICT */
737
0
  }
738
739
0
  if (!(wps->cred.encr_type &
740
0
        (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES))) {
741
0
    if (wps->cred.encr_type & WPS_ENCR_WEP) {
742
0
      wpa_printf(MSG_INFO, "WPS: Reject Credential "
743
0
           "due to WEP configuration");
744
0
      wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
745
0
      return -2;
746
0
    }
747
748
0
    wpa_printf(MSG_INFO, "WPS: Reject Credential due to "
749
0
         "invalid encr_type 0x%x", wps->cred.encr_type);
750
0
    return -1;
751
0
  }
752
753
0
  if (wps->wps->cred_cb) {
754
0
    wps->cred.cred_attr = cred - 4;
755
0
    wps->cred.cred_attr_len = cred_len + 4;
756
0
    ret = wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
757
0
    wps->cred.cred_attr = NULL;
758
0
    wps->cred.cred_attr_len = 0;
759
0
  }
760
761
0
  return ret;
762
0
}
763
764
765
static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
766
           u16 cred_len[], unsigned int num_cred, int wps2)
767
0
{
768
0
  size_t i;
769
0
  int ok = 0;
770
771
0
  if (wps->wps->ap)
772
0
    return 0;
773
774
0
  if (num_cred == 0) {
775
0
    wpa_printf(MSG_DEBUG, "WPS: No Credential attributes "
776
0
         "received");
777
0
    return -1;
778
0
  }
779
780
0
  for (i = 0; i < num_cred; i++) {
781
0
    int res;
782
0
    res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
783
0
    if (res == 0)
784
0
      ok++;
785
0
    else if (res == -2)
786
0
      wpa_printf(MSG_DEBUG, "WPS: WEP credential skipped");
787
0
    else
788
0
      return -1;
789
0
  }
790
791
0
  if (ok == 0) {
792
0
    wpa_printf(MSG_DEBUG, "WPS: No valid Credential attribute "
793
0
         "received");
794
0
    return -1;
795
0
  }
796
797
0
  return 0;
798
0
}
799
800
801
static int wps_process_ap_settings_e(struct wps_data *wps,
802
             struct wps_parse_attr *attr,
803
             struct wpabuf *attrs, int wps2)
804
0
{
805
0
  struct wps_credential cred;
806
0
  int ret = 0;
807
808
0
  if (!wps->wps->ap)
809
0
    return 0;
810
811
0
  if (wps_process_ap_settings(attr, &cred) < 0)
812
0
    return -1;
813
814
0
  wpa_printf(MSG_INFO, "WPS: Received new AP configuration from "
815
0
       "Registrar");
816
817
0
  if (!ether_addr_equal(cred.mac_addr, wps->wps->dev.mac_addr)) {
818
0
    wpa_printf(MSG_DEBUG, "WPS: MAC Address in the AP Settings ("
819
0
         MACSTR ") does not match with own address (" MACSTR
820
0
         ")", MAC2STR(cred.mac_addr),
821
0
         MAC2STR(wps->wps->dev.mac_addr));
822
    /*
823
     * In theory, this could be consider fatal error, but there are
824
     * number of deployed implementations using other address here
825
     * due to unclarity in the specification. For interoperability
826
     * reasons, allow this to be processed since we do not really
827
     * use the MAC Address information for anything.
828
     */
829
#ifdef CONFIG_WPS_STRICT
830
    if (wps2) {
831
      wpa_printf(MSG_INFO, "WPS: Do not accept incorrect "
832
           "MAC Address in AP Settings");
833
      return -1;
834
    }
835
#endif /* CONFIG_WPS_STRICT */
836
0
  }
837
838
0
  if (!(cred.encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP | WPS_ENCR_AES)))
839
0
  {
840
0
    if (cred.encr_type & WPS_ENCR_WEP) {
841
0
      wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
842
0
           "due to WEP configuration");
843
0
      wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
844
0
      return -1;
845
0
    }
846
847
0
    wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
848
0
         "invalid encr_type 0x%x", cred.encr_type);
849
0
    return -1;
850
0
  }
851
852
#ifdef CONFIG_WPS_STRICT
853
  if (wps2) {
854
    if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
855
        WPS_ENCR_TKIP ||
856
        (cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
857
        WPS_AUTH_WPAPSK) {
858
      wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
859
           "AP Settings: WPA-Personal/TKIP only");
860
      wps->error_indication =
861
        WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
862
      return -1;
863
    }
864
  }
865
#endif /* CONFIG_WPS_STRICT */
866
867
0
  if ((cred.encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) == WPS_ENCR_TKIP)
868
0
  {
869
0
    wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
870
0
         "TKIP+AES");
871
0
    cred.encr_type |= WPS_ENCR_AES;
872
0
  }
873
874
0
  if ((cred.auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
875
0
      WPS_AUTH_WPAPSK) {
876
0
    wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
877
0
         "WPAPSK+WPA2PSK");
878
0
    cred.auth_type |= WPS_AUTH_WPA2PSK;
879
0
  }
880
881
#ifdef CONFIG_NO_TKIP
882
  if (cred.encr_type & WPS_ENCR_TKIP) {
883
    wpa_printf(MSG_DEBUG, "WPS: Disable encr_type TKIP");
884
    cred.encr_type &= ~WPS_ENCR_TKIP;
885
  }
886
  if (cred.auth_type & WPS_AUTH_WPAPSK) {
887
    wpa_printf(MSG_DEBUG, "WPS: Disable auth_type WPAPSK");
888
    cred.auth_type &= ~WPS_AUTH_WPAPSK;
889
  }
890
#endif /* CONFIG_NO_TKIP */
891
892
0
  if (wps->wps->cred_cb) {
893
0
    cred.cred_attr = wpabuf_head(attrs);
894
0
    cred.cred_attr_len = wpabuf_len(attrs);
895
0
    ret = wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
896
0
  }
897
898
0
  return ret;
899
0
}
900
901
902
static int wps_process_dev_pw_id(struct wps_data *wps, const u8 *dev_pw_id)
903
0
{
904
0
  u16 id;
905
906
0
  if (dev_pw_id == NULL) {
907
0
    wpa_printf(MSG_DEBUG, "WPS: Device Password ID");
908
0
    return -1;
909
0
  }
910
911
0
  id = WPA_GET_BE16(dev_pw_id);
912
0
  if (wps->dev_pw_id == id) {
913
0
    wpa_printf(MSG_DEBUG, "WPS: Device Password ID %u", id);
914
0
    return 0;
915
0
  }
916
917
0
#ifdef CONFIG_P2P
918
0
  if ((id == DEV_PW_DEFAULT &&
919
0
       wps->dev_pw_id == DEV_PW_REGISTRAR_SPECIFIED) ||
920
0
      (id == DEV_PW_REGISTRAR_SPECIFIED &&
921
0
       wps->dev_pw_id == DEV_PW_DEFAULT)) {
922
    /*
923
     * Common P2P use cases indicate whether the PIN is from the
924
     * client or GO using Device Password Id in M1/M2 in a way that
925
     * does not look fully compliant with WSC specification. Anyway,
926
     * this is deployed and needs to be allowed, so ignore changes
927
     * between Registrar-Specified and Default PIN.
928
     */
929
0
    wpa_printf(MSG_DEBUG, "WPS: Allow PIN Device Password ID "
930
0
         "change");
931
0
    return 0;
932
0
  }
933
0
#endif /* CONFIG_P2P */
934
935
0
  wpa_printf(MSG_DEBUG, "WPS: Registrar trying to change Device Password "
936
0
       "ID from %u to %u", wps->dev_pw_id, id);
937
938
0
  if (wps->dev_pw_id == DEV_PW_PUSHBUTTON && id == DEV_PW_DEFAULT) {
939
0
    wpa_printf(MSG_DEBUG,
940
0
         "WPS: Workaround - ignore PBC-to-PIN change");
941
0
    return 0;
942
0
  }
943
944
0
  if (wps->alt_dev_password && wps->alt_dev_pw_id == id) {
945
0
    wpa_printf(MSG_DEBUG, "WPS: Found a matching Device Password");
946
0
    bin_clear_free(wps->dev_password, wps->dev_password_len);
947
0
    wps->dev_pw_id = wps->alt_dev_pw_id;
948
0
    wps->dev_password = wps->alt_dev_password;
949
0
    wps->dev_password_len = wps->alt_dev_password_len;
950
0
    wps->alt_dev_password = NULL;
951
0
    wps->alt_dev_password_len = 0;
952
0
    return 0;
953
0
  }
954
955
0
  return -1;
956
0
}
957
958
959
static enum wps_process_res wps_process_m2(struct wps_data *wps,
960
             const struct wpabuf *msg,
961
             struct wps_parse_attr *attr)
962
0
{
963
0
  wpa_printf(MSG_DEBUG, "WPS: Received M2");
964
965
0
  if (wps->state != RECV_M2) {
966
0
    wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
967
0
         "receiving M2", wps->state);
968
0
    wps->state = SEND_WSC_NACK;
969
0
    return WPS_CONTINUE;
970
0
  }
971
972
0
  if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
973
0
      wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
974
0
      wps_process_uuid_r(wps, attr->uuid_r) ||
975
0
      wps_process_dev_pw_id(wps, attr->dev_password_id)) {
976
0
    wps->state = SEND_WSC_NACK;
977
0
    return WPS_CONTINUE;
978
0
  }
979
980
  /*
981
   * Stop here on an AP as an Enrollee if AP Setup is locked unless the
982
   * special locked mode is used to allow protocol run up to M7 in order
983
   * to support external Registrars that only learn the current AP
984
   * configuration without changing it.
985
   */
986
0
  if (wps->wps->ap &&
987
0
      ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) ||
988
0
       wps->dev_password == NULL)) {
989
0
    wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
990
0
         "registration of a new Registrar");
991
0
    wps->config_error = WPS_CFG_SETUP_LOCKED;
992
0
    wps->state = SEND_WSC_NACK;
993
0
    return WPS_CONTINUE;
994
0
  }
995
996
0
  if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
997
0
      wps_process_authenticator(wps, attr->authenticator, msg) ||
998
0
      wps_process_device_attrs(&wps->peer_dev, attr)) {
999
0
    wps->state = SEND_WSC_NACK;
1000
0
    return WPS_CONTINUE;
1001
0
  }
1002
1003
0
#ifdef CONFIG_WPS_NFC
1004
0
  if (wps->peer_pubkey_hash_set) {
1005
0
    struct wpabuf *decrypted;
1006
0
    struct wps_parse_attr eattr;
1007
1008
0
    decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1009
0
                  attr->encr_settings_len);
1010
0
    if (decrypted == NULL) {
1011
0
      wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt "
1012
0
           "Encrypted Settings attribute");
1013
0
      wps->state = SEND_WSC_NACK;
1014
0
      return WPS_CONTINUE;
1015
0
    }
1016
1017
0
    wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted "
1018
0
         "Settings attribute");
1019
0
    if (wps_parse_msg(decrypted, &eattr) < 0 ||
1020
0
        wps_process_key_wrap_auth(wps, decrypted,
1021
0
                eattr.key_wrap_auth) ||
1022
0
        wps_process_creds(wps, eattr.cred, eattr.cred_len,
1023
0
              eattr.num_cred, attr->version2 != NULL)) {
1024
0
      wpabuf_clear_free(decrypted);
1025
0
      wps->state = SEND_WSC_NACK;
1026
0
      return WPS_CONTINUE;
1027
0
    }
1028
0
    wpabuf_clear_free(decrypted);
1029
1030
0
    wps->state = WPS_MSG_DONE;
1031
0
    return WPS_CONTINUE;
1032
0
  }
1033
0
#endif /* CONFIG_WPS_NFC */
1034
1035
0
  wps->state = SEND_M3;
1036
0
  return WPS_CONTINUE;
1037
0
}
1038
1039
1040
static enum wps_process_res wps_process_m2d(struct wps_data *wps,
1041
              struct wps_parse_attr *attr)
1042
0
{
1043
0
  wpa_printf(MSG_DEBUG, "WPS: Received M2D");
1044
1045
0
  if (wps->state != RECV_M2) {
1046
0
    wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1047
0
         "receiving M2D", wps->state);
1048
0
    wps->state = SEND_WSC_NACK;
1049
0
    return WPS_CONTINUE;
1050
0
  }
1051
1052
0
  wpa_hexdump_ascii(MSG_DEBUG, "WPS: Manufacturer",
1053
0
        attr->manufacturer, attr->manufacturer_len);
1054
0
  wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Name",
1055
0
        attr->model_name, attr->model_name_len);
1056
0
  wpa_hexdump_ascii(MSG_DEBUG, "WPS: Model Number",
1057
0
        attr->model_number, attr->model_number_len);
1058
0
  wpa_hexdump_ascii(MSG_DEBUG, "WPS: Serial Number",
1059
0
        attr->serial_number, attr->serial_number_len);
1060
0
  wpa_hexdump_ascii(MSG_DEBUG, "WPS: Device Name",
1061
0
        attr->dev_name, attr->dev_name_len);
1062
1063
0
  if (wps->wps->event_cb) {
1064
0
    union wps_event_data data;
1065
0
    struct wps_event_m2d *m2d = &data.m2d;
1066
0
    os_memset(&data, 0, sizeof(data));
1067
0
    if (attr->config_methods)
1068
0
      m2d->config_methods =
1069
0
        WPA_GET_BE16(attr->config_methods);
1070
0
    m2d->manufacturer = attr->manufacturer;
1071
0
    m2d->manufacturer_len = attr->manufacturer_len;
1072
0
    m2d->model_name = attr->model_name;
1073
0
    m2d->model_name_len = attr->model_name_len;
1074
0
    m2d->model_number = attr->model_number;
1075
0
    m2d->model_number_len = attr->model_number_len;
1076
0
    m2d->serial_number = attr->serial_number;
1077
0
    m2d->serial_number_len = attr->serial_number_len;
1078
0
    m2d->dev_name = attr->dev_name;
1079
0
    m2d->dev_name_len = attr->dev_name_len;
1080
0
    m2d->primary_dev_type = attr->primary_dev_type;
1081
0
    if (attr->config_error)
1082
0
      m2d->config_error =
1083
0
        WPA_GET_BE16(attr->config_error);
1084
0
    if (attr->dev_password_id)
1085
0
      m2d->dev_password_id =
1086
0
        WPA_GET_BE16(attr->dev_password_id);
1087
0
    wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_M2D, &data);
1088
0
  }
1089
1090
0
  wps->state = RECEIVED_M2D;
1091
0
  return WPS_CONTINUE;
1092
0
}
1093
1094
1095
static enum wps_process_res wps_process_m4(struct wps_data *wps,
1096
             const struct wpabuf *msg,
1097
             struct wps_parse_attr *attr)
1098
0
{
1099
0
  struct wpabuf *decrypted;
1100
0
  struct wps_parse_attr eattr;
1101
1102
0
  wpa_printf(MSG_DEBUG, "WPS: Received M4");
1103
1104
0
  if (wps->state != RECV_M4) {
1105
0
    wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1106
0
         "receiving M4", wps->state);
1107
0
    wps->state = SEND_WSC_NACK;
1108
0
    return WPS_CONTINUE;
1109
0
  }
1110
1111
0
  if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1112
0
      wps_process_authenticator(wps, attr->authenticator, msg) ||
1113
0
      wps_process_r_hash1(wps, attr->r_hash1) ||
1114
0
      wps_process_r_hash2(wps, attr->r_hash2)) {
1115
0
    wps->state = SEND_WSC_NACK;
1116
0
    return WPS_CONTINUE;
1117
0
  }
1118
1119
0
  decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1120
0
                attr->encr_settings_len);
1121
0
  if (decrypted == NULL) {
1122
0
    wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1123
0
         "Settings attribute");
1124
0
    wps->state = SEND_WSC_NACK;
1125
0
    return WPS_CONTINUE;
1126
0
  }
1127
1128
0
  if (wps_validate_m4_encr(decrypted, attr->version2 != NULL) < 0) {
1129
0
    wpabuf_clear_free(decrypted);
1130
0
    wps->state = SEND_WSC_NACK;
1131
0
    return WPS_CONTINUE;
1132
0
  }
1133
1134
0
  wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1135
0
       "attribute");
1136
0
  if (wps_parse_msg(decrypted, &eattr) < 0 ||
1137
0
      wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1138
0
      wps_process_r_snonce1(wps, eattr.r_snonce1)) {
1139
0
    wpabuf_clear_free(decrypted);
1140
0
    wps->state = SEND_WSC_NACK;
1141
0
    return WPS_CONTINUE;
1142
0
  }
1143
0
  wpabuf_clear_free(decrypted);
1144
1145
0
  wps->state = SEND_M5;
1146
0
  return WPS_CONTINUE;
1147
0
}
1148
1149
1150
static enum wps_process_res wps_process_m6(struct wps_data *wps,
1151
             const struct wpabuf *msg,
1152
             struct wps_parse_attr *attr)
1153
0
{
1154
0
  struct wpabuf *decrypted;
1155
0
  struct wps_parse_attr eattr;
1156
1157
0
  wpa_printf(MSG_DEBUG, "WPS: Received M6");
1158
1159
0
  if (wps->state != RECV_M6) {
1160
0
    wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1161
0
         "receiving M6", wps->state);
1162
0
    wps->state = SEND_WSC_NACK;
1163
0
    return WPS_CONTINUE;
1164
0
  }
1165
1166
0
  if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1167
0
      wps_process_authenticator(wps, attr->authenticator, msg)) {
1168
0
    wps->state = SEND_WSC_NACK;
1169
0
    return WPS_CONTINUE;
1170
0
  }
1171
1172
0
  decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1173
0
                attr->encr_settings_len);
1174
0
  if (decrypted == NULL) {
1175
0
    wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1176
0
         "Settings attribute");
1177
0
    wps->state = SEND_WSC_NACK;
1178
0
    return WPS_CONTINUE;
1179
0
  }
1180
1181
0
  if (wps_validate_m6_encr(decrypted, attr->version2 != NULL) < 0) {
1182
0
    wpabuf_clear_free(decrypted);
1183
0
    wps->state = SEND_WSC_NACK;
1184
0
    return WPS_CONTINUE;
1185
0
  }
1186
1187
0
  wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1188
0
       "attribute");
1189
0
  if (wps_parse_msg(decrypted, &eattr) < 0 ||
1190
0
      wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1191
0
      wps_process_r_snonce2(wps, eattr.r_snonce2)) {
1192
0
    wpabuf_clear_free(decrypted);
1193
0
    wps->state = SEND_WSC_NACK;
1194
0
    return WPS_CONTINUE;
1195
0
  }
1196
0
  wpabuf_clear_free(decrypted);
1197
1198
0
  if (wps->wps->ap)
1199
0
    wps->wps->event_cb(wps->wps->cb_ctx, WPS_EV_AP_PIN_SUCCESS,
1200
0
           NULL);
1201
1202
0
  wps->state = SEND_M7;
1203
0
  return WPS_CONTINUE;
1204
0
}
1205
1206
1207
static enum wps_process_res wps_process_m8(struct wps_data *wps,
1208
             const struct wpabuf *msg,
1209
             struct wps_parse_attr *attr)
1210
0
{
1211
0
  struct wpabuf *decrypted;
1212
0
  struct wps_parse_attr eattr;
1213
1214
0
  wpa_printf(MSG_DEBUG, "WPS: Received M8");
1215
1216
0
  if (wps->state != RECV_M8) {
1217
0
    wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
1218
0
         "receiving M8", wps->state);
1219
0
    wps->state = SEND_WSC_NACK;
1220
0
    return WPS_CONTINUE;
1221
0
  }
1222
1223
0
  if (wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
1224
0
      wps_process_authenticator(wps, attr->authenticator, msg)) {
1225
0
    wps->state = SEND_WSC_NACK;
1226
0
    return WPS_CONTINUE;
1227
0
  }
1228
1229
0
  if (wps->wps->ap && wps->wps->ap_setup_locked) {
1230
    /*
1231
     * Stop here if special ap_setup_locked == 2 mode allowed the
1232
     * protocol to continue beyond M2. This allows ER to learn the
1233
     * current AP settings without changing them.
1234
     */
1235
0
    wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
1236
0
         "registration of a new Registrar");
1237
0
    wps->config_error = WPS_CFG_SETUP_LOCKED;
1238
0
    wps->state = SEND_WSC_NACK;
1239
0
    return WPS_CONTINUE;
1240
0
  }
1241
1242
0
  decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
1243
0
                attr->encr_settings_len);
1244
0
  if (decrypted == NULL) {
1245
0
    wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
1246
0
         "Settings attribute");
1247
0
    wps->state = SEND_WSC_NACK;
1248
0
    return WPS_CONTINUE;
1249
0
  }
1250
1251
0
  if (wps_validate_m8_encr(decrypted, wps->wps->ap,
1252
0
         attr->version2 != NULL) < 0) {
1253
0
    wpabuf_clear_free(decrypted);
1254
0
    wps->state = SEND_WSC_NACK;
1255
0
    return WPS_CONTINUE;
1256
0
  }
1257
1258
0
  wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
1259
0
       "attribute");
1260
0
  if (wps_parse_msg(decrypted, &eattr) < 0 ||
1261
0
      wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
1262
0
      wps_process_creds(wps, eattr.cred, eattr.cred_len,
1263
0
            eattr.num_cred, attr->version2 != NULL) ||
1264
0
      wps_process_ap_settings_e(wps, &eattr, decrypted,
1265
0
              attr->version2 != NULL)) {
1266
0
    wpabuf_clear_free(decrypted);
1267
0
    wps->state = SEND_WSC_NACK;
1268
0
    return WPS_CONTINUE;
1269
0
  }
1270
0
  wpabuf_clear_free(decrypted);
1271
1272
0
  wps->state = WPS_MSG_DONE;
1273
0
  return WPS_CONTINUE;
1274
0
}
1275
1276
1277
static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
1278
            const struct wpabuf *msg)
1279
0
{
1280
0
  struct wps_parse_attr attr;
1281
0
  enum wps_process_res ret = WPS_CONTINUE;
1282
1283
0
  wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
1284
1285
0
  if (wps_parse_msg(msg, &attr) < 0)
1286
0
    return WPS_FAILURE;
1287
1288
0
  if (attr.enrollee_nonce == NULL ||
1289
0
      os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1290
0
    wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1291
0
    return WPS_FAILURE;
1292
0
  }
1293
1294
0
  if (attr.msg_type == NULL) {
1295
0
    wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1296
0
    wps->state = SEND_WSC_NACK;
1297
0
    return WPS_CONTINUE;
1298
0
  }
1299
1300
0
  switch (*attr.msg_type) {
1301
0
  case WPS_M2:
1302
0
    if (wps_validate_m2(msg) < 0)
1303
0
      return WPS_FAILURE;
1304
0
    ret = wps_process_m2(wps, msg, &attr);
1305
0
    break;
1306
0
  case WPS_M2D:
1307
0
    if (wps_validate_m2d(msg) < 0)
1308
0
      return WPS_FAILURE;
1309
0
    ret = wps_process_m2d(wps, &attr);
1310
0
    break;
1311
0
  case WPS_M4:
1312
0
    if (wps_validate_m4(msg) < 0)
1313
0
      return WPS_FAILURE;
1314
0
    ret = wps_process_m4(wps, msg, &attr);
1315
0
    if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1316
0
      wps_fail_event(wps->wps, WPS_M4, wps->config_error,
1317
0
               wps->error_indication,
1318
0
               wps->peer_dev.mac_addr);
1319
0
    break;
1320
0
  case WPS_M6:
1321
0
    if (wps_validate_m6(msg) < 0)
1322
0
      return WPS_FAILURE;
1323
0
    ret = wps_process_m6(wps, msg, &attr);
1324
0
    if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1325
0
      wps_fail_event(wps->wps, WPS_M6, wps->config_error,
1326
0
               wps->error_indication,
1327
0
               wps->peer_dev.mac_addr);
1328
0
    break;
1329
0
  case WPS_M8:
1330
0
    if (wps_validate_m8(msg) < 0)
1331
0
      return WPS_FAILURE;
1332
0
    ret = wps_process_m8(wps, msg, &attr);
1333
0
    if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
1334
0
      wps_fail_event(wps->wps, WPS_M8, wps->config_error,
1335
0
               wps->error_indication,
1336
0
               wps->peer_dev.mac_addr);
1337
0
    break;
1338
0
  default:
1339
0
    wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
1340
0
         *attr.msg_type);
1341
0
    return WPS_FAILURE;
1342
0
  }
1343
1344
  /*
1345
   * Save a copy of the last message for Authenticator derivation if we
1346
   * are continuing. However, skip M2D since it is not authenticated and
1347
   * neither is the ACK/NACK response frame. This allows the possibly
1348
   * following M2 to be processed correctly by using the previously sent
1349
   * M1 in Authenticator derivation.
1350
   */
1351
0
  if (ret == WPS_CONTINUE && *attr.msg_type != WPS_M2D) {
1352
    /* Save a copy of the last message for Authenticator derivation
1353
     */
1354
0
    wpabuf_free(wps->last_msg);
1355
0
    wps->last_msg = wpabuf_dup(msg);
1356
0
  }
1357
1358
0
  return ret;
1359
0
}
1360
1361
1362
static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
1363
            const struct wpabuf *msg)
1364
0
{
1365
0
  struct wps_parse_attr attr;
1366
1367
0
  wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
1368
1369
0
  if (wps_parse_msg(msg, &attr) < 0)
1370
0
    return WPS_FAILURE;
1371
1372
0
  if (attr.msg_type == NULL) {
1373
0
    wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1374
0
    return WPS_FAILURE;
1375
0
  }
1376
1377
0
  if (*attr.msg_type != WPS_WSC_ACK) {
1378
0
    wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1379
0
         *attr.msg_type);
1380
0
    return WPS_FAILURE;
1381
0
  }
1382
1383
0
  if (attr.registrar_nonce == NULL ||
1384
0
      os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1385
0
  {
1386
0
    wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1387
0
    return WPS_FAILURE;
1388
0
  }
1389
1390
0
  if (attr.enrollee_nonce == NULL ||
1391
0
      os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1392
0
    wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1393
0
    return WPS_FAILURE;
1394
0
  }
1395
1396
0
  if (wps->state == RECV_ACK && wps->wps->ap) {
1397
0
    wpa_printf(MSG_DEBUG, "WPS: External Registrar registration "
1398
0
         "completed successfully");
1399
0
    wps_success_event(wps->wps, wps->peer_dev.mac_addr);
1400
0
    wps->state = WPS_FINISHED;
1401
0
    return WPS_DONE;
1402
0
  }
1403
1404
0
  return WPS_FAILURE;
1405
0
}
1406
1407
1408
static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
1409
             const struct wpabuf *msg)
1410
0
{
1411
0
  struct wps_parse_attr attr;
1412
0
  u16 config_error;
1413
1414
0
  wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
1415
1416
0
  if (wps_parse_msg(msg, &attr) < 0)
1417
0
    return WPS_FAILURE;
1418
1419
0
  if (attr.msg_type == NULL) {
1420
0
    wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
1421
0
    return WPS_FAILURE;
1422
0
  }
1423
1424
0
  if (*attr.msg_type != WPS_WSC_NACK) {
1425
0
    wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
1426
0
         *attr.msg_type);
1427
0
    return WPS_FAILURE;
1428
0
  }
1429
1430
0
  if (attr.registrar_nonce == NULL ||
1431
0
      os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
1432
0
  {
1433
0
    wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
1434
0
    wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
1435
0
          attr.registrar_nonce, WPS_NONCE_LEN);
1436
0
    wpa_hexdump(MSG_DEBUG, "WPS: Expected Registrar Nonce",
1437
0
          wps->nonce_r, WPS_NONCE_LEN);
1438
0
    return WPS_FAILURE;
1439
0
  }
1440
1441
0
  if (attr.enrollee_nonce == NULL ||
1442
0
      os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
1443
0
    wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
1444
0
    wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
1445
0
          attr.enrollee_nonce, WPS_NONCE_LEN);
1446
0
    wpa_hexdump(MSG_DEBUG, "WPS: Expected Enrollee Nonce",
1447
0
          wps->nonce_e, WPS_NONCE_LEN);
1448
0
    return WPS_FAILURE;
1449
0
  }
1450
1451
0
  if (attr.config_error == NULL) {
1452
0
    wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
1453
0
         "in WSC_NACK");
1454
0
    return WPS_FAILURE;
1455
0
  }
1456
1457
0
  config_error = WPA_GET_BE16(attr.config_error);
1458
0
  wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
1459
0
       "Configuration Error %d", config_error);
1460
1461
0
  switch (wps->state) {
1462
0
  case RECV_M4:
1463
0
    wps_fail_event(wps->wps, WPS_M3, config_error,
1464
0
             wps->error_indication, wps->peer_dev.mac_addr);
1465
0
    break;
1466
0
  case RECV_M6:
1467
0
    wps_fail_event(wps->wps, WPS_M5, config_error,
1468
0
             wps->error_indication, wps->peer_dev.mac_addr);
1469
0
    break;
1470
0
  case RECV_M8:
1471
0
    wps_fail_event(wps->wps, WPS_M7, config_error,
1472
0
             wps->error_indication, wps->peer_dev.mac_addr);
1473
0
    break;
1474
0
  default:
1475
0
    break;
1476
0
  }
1477
1478
  /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
1479
   * Enrollee is Authenticator */
1480
0
  wps->state = SEND_WSC_NACK;
1481
1482
0
  return WPS_FAILURE;
1483
0
}
1484
1485
1486
enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
1487
                enum wsc_op_code op_code,
1488
                const struct wpabuf *msg)
1489
0
{
1490
1491
0
  wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
1492
0
       "op_code=%d)",
1493
0
       (unsigned long) wpabuf_len(msg), op_code);
1494
1495
0
  if (op_code == WSC_UPnP) {
1496
    /* Determine the OpCode based on message type attribute */
1497
0
    struct wps_parse_attr attr;
1498
0
    if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
1499
0
      if (*attr.msg_type == WPS_WSC_ACK)
1500
0
        op_code = WSC_ACK;
1501
0
      else if (*attr.msg_type == WPS_WSC_NACK)
1502
0
        op_code = WSC_NACK;
1503
0
    }
1504
0
  }
1505
1506
0
  switch (op_code) {
1507
0
  case WSC_MSG:
1508
0
  case WSC_UPnP:
1509
0
    return wps_process_wsc_msg(wps, msg);
1510
0
  case WSC_ACK:
1511
0
    if (wps_validate_wsc_ack(msg) < 0)
1512
0
      return WPS_FAILURE;
1513
0
    return wps_process_wsc_ack(wps, msg);
1514
0
  case WSC_NACK:
1515
0
    if (wps_validate_wsc_nack(msg) < 0)
1516
0
      return WPS_FAILURE;
1517
0
    return wps_process_wsc_nack(wps, msg);
1518
0
  default:
1519
0
    wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
1520
0
    return WPS_FAILURE;
1521
0
  }
1522
0
}